/// <summary> /// Notifies event subscribers of a keyboard event /// </summary> /// <param name="wParam">key info</param> /// <param name="hookStruct">keyboard info</param> /// <param name="handled">was the event handled? set to true if so</param> private void notifyEvent(KeyboardWParam wParam, KBDLLHOOKSTRUCT hookStruct, ref bool handled) { var args = new KeyEventArgs((Keys)hookStruct.vkCode) { Handled = false }; switch (wParam) { case KeyboardWParam.WM_SYSKEYDOWN: if (EvtKeyDown != null) { EvtKeyDown(this, args); } break; case KeyboardWParam.WM_KEYDOWN: if (EvtKeyDown != null) { EvtKeyDown(this, args); } if (EvtKeyPress != null) { bool isShiftDown = (User32Interop.GetKeyState(VK_SHIFT) & 0x80) == 0x80; bool isCapsLockDown = User32Interop.GetKeyState(VK_CAPITAL) != 0; var keyState = new byte[256]; var inBuffer = new byte[2]; User32Interop.GetKeyboardState(keyState); if (User32Interop.ToAscii(hookStruct.vkCode, hookStruct.scanCode, keyState, inBuffer, hookStruct.flags) == 1) { var key = (char)inBuffer[0]; if ((isCapsLockDown ^ isShiftDown) && Char.IsLetter(key)) { key = Char.ToUpper(key); } var e = new KeyPressEventArgs(key); EvtKeyPress(this, e); } } break; case KeyboardWParam.WM_SYSKEYUP: case KeyboardWParam.WM_KEYUP: if (EvtKeyUp != null) { EvtKeyUp(this, args); } break; } handled = args.Handled; }