/// <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 static int KeyboardHookProc(int nCode, int wParam, IntPtr lParam) { if (nCode < 0) { return(CallNextHookEx(keyboardHookHandle, nCode, wParam, lParam)); } //Marshall the data from callback. var info = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); var extended = (info.Flags & LLKHF_EXTENDED) != 0; var code = extended && info.VirtualKeyCode == VK_RETURN ? 1025 : info.VirtualKeyCode; switch (wParam) { case WM_KEYDOWN: case WM_SYSKEYDOWN: KeyboardState.AddPressedElement(code, PressHold); break; case WM_KEYUP: case WM_SYSKEYUP: KeyboardState.RemovePressedElement(code, PressHold); // Toggle the mouse trap. if (code == TrapToggleKeyCode) { trapEnabled = !trapEnabled; } break; } if (KeyboardInsert?.Invoke(code) ?? false || (trapEnabled && TrapKeyboard)) { return(1); } return(CallNextHookEx(keyboardHookHandle, nCode, wParam, lParam)); }