/// <summary> /// A callback function which will be called every time a keyboard activity detected. /// </summary> /// <param name="nCode"> /// [in] Specifies whether the hook procedure must process the message. /// If nCode is HC_ACTION, the hook procedure must process the message. /// If nCode is less than zero, the hook procedure must pass the message to the /// CallNextHookEx function without further processing and must return the /// value returned by CallNextHookEx. /// </param> /// <param name="wParam"> /// [in] Specifies whether the message was sent by the current thread. /// If the message was sent by the current thread, it is nonzero; otherwise, it is zero. /// </param> /// <param name="lParam"> /// [in] Pointer to a CWPSTRUCT structure that contains details about the message. /// </param> /// <returns> /// If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx. /// If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx /// and return the value it returns; otherwise, other applications that have installed WH_CALLWNDPROC /// hooks will not receive hook notifications and may behave incorrectly as a result. If the hook /// procedure does not call CallNextHookEx, the return value should be zero. /// </returns> private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { //Indicates if any of underlaing events set e.Handled flag bool handled = false; //If was Ok and someone listens to events if ((nCode >= 0) && (KeyDown != null || KeyUp != null || KeyPress != null)) { //Read structure KeyboardHookStruct at lParam var myKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { #region Raise KeyDown var keyData = (Keys)myKeyboardHookStruct.vkCode; var e = new CustomKeyEventArgs(keyData); KeyDown(this, e); handled = handled || e.Handled; #endregion } if (KeyPress != null && wParam == WM_KEYDOWN) { #region Raise KeyPress bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80); bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0); var keyState = new byte[256]; GetKeyboardState(keyState); var inBuffer = new byte[2]; if (ToAscii(myKeyboardHookStruct.vkCode, myKeyboardHookStruct.scanCode, keyState, inBuffer, myKeyboardHookStruct.flags) == 1) { var key = (char)inBuffer[0]; if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) { key = Char.ToUpper(key); } var e = new CustomKeyPressEventArgs(key); KeyPress(this, e); handled = handled || e.Handled; } #endregion } if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)) { #region Raise KeyUp var keyData = (Keys)myKeyboardHookStruct.vkCode; var e = new CustomKeyEventArgs(keyData); KeyUp(this, e); handled = handled || e.Handled; #endregion } } //If event handled in application do not handoff to other listeners if (handled) { return(1); } return(CallNextHookEx(hKeyboardHook, nCode, wParam, lParam)); }
/// <summary> /// A callback function which will be called every time a keyboard activity detected. /// </summary> /// <param name="nCode"> /// [in] Specifies whether the hook procedure must process the message. /// If nCode is HC_ACTION, the hook procedure must process the message. /// If nCode is less than zero, the hook procedure must pass the message to the /// CallNextHookEx function without further processing and must return the /// value returned by CallNextHookEx. /// </param> /// <param name="wParam"> /// [in] Specifies whether the message was sent by the current thread. /// If the message was sent by the current thread, it is nonzero; otherwise, it is zero. /// </param> /// <param name="lParam"> /// [in] Pointer to a CWPSTRUCT structure that contains details about the message. /// </param> /// <returns> /// If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx. /// If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx /// and return the value it returns; otherwise, other applications that have installed WH_CALLWNDPROC /// hooks will not receive hook notifications and may behave incorrectly as a result. If the hook /// procedure does not call CallNextHookEx, the return value should be zero. /// </returns> private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { //Indicates if any of underlaing events set e.Handled flag bool handled = false; //If was Ok and someone listens to events if ((nCode >= 0) && (KeyDown != null || KeyUp != null || KeyPress != null)) { //Read structure KeyboardHookStruct at lParam var myKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { #region Raise KeyDown var keyData = (Keys)myKeyboardHookStruct.vkCode; var e = new CustomKeyEventArgs(keyData); KeyDown(this, e); handled = handled || e.Handled; #endregion } if (KeyPress != null && wParam == WM_KEYDOWN) { #region Raise KeyPress bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80); bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0); var keyState = new byte[256]; GetKeyboardState(keyState); var inBuffer = new byte[2]; if (ToAscii(myKeyboardHookStruct.vkCode, myKeyboardHookStruct.scanCode, keyState, inBuffer, myKeyboardHookStruct.flags) == 1) { var key = (char)inBuffer[0]; if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key); var e = new CustomKeyPressEventArgs(key); KeyPress(this, e); handled = handled || e.Handled; } #endregion } if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)) { #region Raise KeyUp var keyData = (Keys)myKeyboardHookStruct.vkCode; var e = new CustomKeyEventArgs(keyData); KeyUp(this, e); handled = handled || e.Handled; #endregion } } //If event handled in application do not handoff to other listeners if (handled) return 1; return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); }
/// <summary> /// A callback function which will be called every time a keyboard activity detected. /// </summary> /// <param name="nCode"> /// [in] Specifies whether the hook procedure must process the message. /// If nCode is HC_ACTION, the hook procedure must process the message. /// If nCode is less than zero, the hook procedure must pass the message to the /// CallNextHookEx function without further processing and must return the /// value returned by CallNextHookEx. /// </param> /// <param name="wParam"> /// [in] Specifies whether the message was sent by the current thread. /// If the message was sent by the current thread, it is nonzero; otherwise, it is zero. /// </param> /// <param name="lParam"> /// [in] Pointer to a CWPSTRUCT structure that contains details about the message. /// </param> /// <returns> /// If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx. /// If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx /// and return the value it returns; otherwise, other applications that have installed WH_CALLWNDPROC /// hooks will not receive hook notifications and may behave incorrectly as a result. If the hook /// procedure does not call CallNextHookEx, the return value should be zero. /// </returns> private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam) { //Indicates if any of underlaing events set e.Handled flag var handled = false; //If was Ok and someone listens to events if (nCode < 0 || KeyDown == null && KeyUp == null && KeyPress == null) { return(CallNextHookEx(_hKeyboardHook, nCode, wParam, lParam)); } //Read structure KeyboardHookStruct at lParam var myKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { #region Raise KeyDown var isDownShift = (GetKeyState(VK_SHIFT) & 0x80) == 0x80; var isDownCapslock = GetKeyState(VK_CAPITAL) != 0; var e = new CustomKeyEventArgs(KeyInterop.KeyFromVirtualKey(myKeyboardHookStruct.vkCode), isDownCapslock ^ isDownShift); KeyDown?.Invoke(this, e); handled = e.Handled; #endregion } if (KeyPress != null && wParam == WM_KEYDOWN) { #region Raise KeyPress var isDownShift = (GetKeyState(VK_SHIFT) & 0x80) == 0x80; var isDownCapslock = GetKeyState(VK_CAPITAL) != 0; var keyState = new byte[256]; GetKeyboardState(keyState); var inBuffer = new byte[2]; if (ToAscii(myKeyboardHookStruct.vkCode, myKeyboardHookStruct.scanCode, keyState, inBuffer, myKeyboardHookStruct.flags) == 1) { var key = (char)inBuffer[0]; if (isDownCapslock ^ isDownShift && char.IsLetter(key)) { key = char.ToUpper(key); } var e = new CustomKeyPressEventArgs(key); KeyPress?.Invoke(this, e); handled = handled || e.Handled; } #endregion } if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)) { #region Raise KeyUp var e = new CustomKeyEventArgs(KeyInterop.KeyFromVirtualKey(myKeyboardHookStruct.vkCode)); KeyUp?.Invoke(this, e); handled = handled || e.Handled; #endregion } //If event handled in application do not handoff to other listeners return(handled ? 1 : CallNextHookEx(_hKeyboardHook, nCode, wParam, lParam)); }