/// <summary>Initializes the keyboard hook.</summary> /// <param name="keyDown">The delegate to be called when a key down event occurs.</param> public KeyboardHook(int targetProcessID, KeyEventHandler keyDown) { if (keyDown == null) { throw new ArgumentNullException("keyDown"); } // Store the user's KeyDown delegate _keyDown = keyDown; _pid = targetProcessID; // Create the callback and pin it, since it'll be called // from unmanaged code _hookProc = new LowLevelKeyboardProc(HookCallback); // Set the hook for just the GUI thread using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { _hookHandle = SafeWindowsHookHandle.SetWindowsHookEx( WH_KEYBOARD_LL, _hookProc, GetModuleHandle(curModule.ModuleName), 0); } if (_hookHandle.IsInvalid) { Exception exc = new Win32Exception(); Dispose(); throw exc; } }
/// <summary>Dispose the KeyboardHook.</summary> public void Dispose() { if (_hookHandle != null) { _hookHandle.Dispose(); _hookHandle = null; } }
public static extern IntPtr CallNextHookEx(SafeWindowsHookHandle hhk, int nCode, IntPtr wParam, IntPtr lParam);
/// <summary>Callback from the installed hook.</summary> ///</returns> private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { bool handled = false; try { if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { uint pid; GetWindowThreadProcessId(GetForegroundWindow(), out pid); if (pid == _pid) { KBDLLHOOKSTRUCT hookParam = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); Keys key = (Keys)hookParam.vkCode; if (key == Keys.Packet) { key = (Keys)hookParam.scanCode; } KeyEventArgs e = new KeyEventArgs(key | ModifierKeys); _keyDown(this, e); handled = e.Handled | e.SuppressKeyPress; } } // won't work because WH_KEYBOARD_LL doesn't fire for app commands // can't change it to WH_SHELL to get the app commands to fire because // only WH_KEYBOARD_LL and WH_MOUSE_LL are supported for global hooks like this one else if (nCode >= 0 && wParam == (IntPtr)WM_APPCOMMAND) { // LogToFile("app command detected"); uint pid; GetWindowThreadProcessId(GetForegroundWindow(), out pid); if (pid == _pid) { int cmd = (int)((uint)lParam >> 16 & ~0xf000); // LogToFile("app command is " + cmd); Keys key = Keys.F24; if (cmd == APPCOMMAND_MEDIA_PLAY) { key = Keys.Play; } KeyEventArgs e = new KeyEventArgs(key | ModifierKeys); _keyDown(this, e); handled = e.Handled | e.SuppressKeyPress; } } else { //LogToFile("detected other, type=" + wParam.ToString()); } return(handled ? new IntPtr(1) : SafeWindowsHookHandle.CallNextHookEx( _hookHandle, nCode, wParam, lParam)); } catch (Exception exc) { Error(this, new ErrorEventArgs(exc)); } return(new IntPtr(1)); }