2009-07-24 2 views
1

Я использую приведенный ниже код, чтобы отключить Alt + Tab, Alt + Esc, Ctrl + Esc и Windows Key, но как-то он не работает. Пожалуйста, помогите мне исправить это.Блокировка сочетаний клавиш с использованием C#

namespace BlockShortcuts 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private delegate int LowLevelKeyboardProcDelegate(int nCode, int 
      wParam, ref KBDLLHOOKSTRUCT lParam); 

     [DllImport("user32.dll", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi)] 
     private static extern int SetWindowsHookEx(
      int idHook, 
      LowLevelKeyboardProcDelegate lpfn, 
      int hMod, 
      int dwThreadId); 

     [DllImport("user32.dll")] 
     private static extern int UnhookWindowsHookEx(int hHook); 

     [DllImport("user32.dll", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi)] 
     private static extern int CallNextHookEx(
      int hHook, int nCode, 
      int wParam, ref KBDLLHOOKSTRUCT lParam); 

     const int WH_KEYBOARD_LL = 13; 
     private int intLLKey; 
     private KBDLLHOOKSTRUCT lParam; 

     private struct KBDLLHOOKSTRUCT 
     { 
      public int vkCode; 
      int scanCode; 
      public int flags; 
      int time; 
      int dwExtraInfo; 
     } 

     private int LowLevelKeyboardProc(
      int nCode, int wParam, 
      ref KBDLLHOOKSTRUCT lParam) 
     { 
      bool blnEat = false; 
      switch (wParam) 
      { 
       case 256: 
       case 257: 
       case 260: 
       case 261: 
        //Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key 
        if (((lParam.vkCode == 9) && (lParam.flags == 32)) || 
        ((lParam.vkCode == 27) && (lParam.flags == 32)) || ((lParam.vkCode == 
        27) && (lParam.flags == 0)) || ((lParam.vkCode == 91) && (lParam.flags 
        == 1)) || ((lParam.vkCode == 92) && (lParam.flags == 1)) || ((true) && 
        (lParam.flags == 32))) 
        { 
         blnEat = true; 
        } 
        break; 
      } 

      if (blnEat) 
       return 1; 
      else return CallNextHookEx(0, nCode, wParam, ref lParam); 

     } 

     private void KeyboardHook(object sender, EventArgs e) 
     { 
      intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL,new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc), 
         System.Runtime.InteropServices.Marshal.GetHINSTANCE(
         System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0); 
     } 

     private void ReleaseKeyboardHook() 
     { 
      intLLKey = UnhookWindowsHookEx(intLLKey); 
     } 

     private void checkBox1_CheckedChanged(object sender, EventArgs e) 
     { 
      if (checkBox1.Checked) 
       KeyboardHook(this, e); 
      else 
       ReleaseKeyboardHook(); 
     } 
    } 
} 
+0

@tom Ritter, что отредактированный в коде выше. Благодарю. – Anuya

+0

@karthik, вы можете найти изменения по адресу http://stackoverflow.com/revisions/1175675/list –

ответ

6

Код в целом работает нормально. Эффект, который вы наблюдаете, вероятно, связан с запуском под отладчиком Visual Studio, что обычно подразумевает, что вы работаете в Visual Studio Visual Studio Hosting Process (vshost.exe).

Это означает, что вызов System.Reflection.Assembly.GetExecutingAssembly() в пределах вашей функции KeyboardHook() возвращает vshost.exe, а не ваш исполняемый файл, следовательно, желаемого эффекта установки крючка для вашего исполняемого файла не может быть достигнуто.

Таким образом, чтобы увидеть ваш код в действительности вы должны будете сделать одно из следующих действий:

  • запустить его вне Visual Studio
  • запустить его в Visual Studio, но с помощью меню «Debug'- > «Запуск без отладки»
  • отключить Visual Studio Хостинг процесса см ниже

Обратите внимание, что вы могли бы disable the Visual Studio Hosting Process, но следует помнить о возможных побочных эффектов, цитата:

Когда процесс хостинга отключен, несколько отладочных функций недоступны или опыт уменьшился производительность. Для получения дополнительной информации см. Debugging and the Hosting Process.

1

Вы можете проверить мой ответ на соответствующий вопрос по поводу here. Обратите внимание на разницу в методе RegisterLowLevelHook (вы назвали ваш KeyboardHook, чтобы вы знали, что сравнивать). У меня не было проблем с этим, даже при отладке от VS. В принципе, как заявили другие, не используйте метод GetExecutingAssembly, но вместо этого я перечислил в другом ответе.

Вот выдержка для одной функции, представляющей интерес для Вас:

private IntPtr RegisterLowLevelHook(LowLevelKeyboardProc hook) 
{ 
    IntPtr handle = IntPtr.Zero; 

    using (Process currentProcess = Process.GetCurrentProcess()) 
    using (ProcessModule currentModule = currentProcess.MainModule) 
    { 
     IntPtr module = Kernel32.GetModuleHandle(currentModule.ModuleName); 
     handle = User32.SetWindowsHookEx(HookType.KEYBOARD_LL, hook, module, 0); 
    } 

    return handle; 
} 
Смежные вопросы