private IntPtr keyboardHandler(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT kbdStruct) { IntPtr ret; try { if (nCode >= 0) { var virtualKeyCode = (Keys) kbdStruct.KeyCode; var keyData = BuildKeyData(virtualKeyCode); var keyEventArgs = new KeyEventArgs(keyData); var intParam = wParam.ToInt32(); switch (intParam) { case NativeMethods.WM_SYSKEYDOWN: case NativeMethods.WM_KEYDOWN: RaiseKeyDownEvent(keyEventArgs); var buffer = ToUnicode(kbdStruct); if (!string.IsNullOrEmpty(buffer)) { foreach (var rawKey in buffer) { var s = _keyConverter.ConvertToString(rawKey); if (s == null) continue; var key = s[0]; RaiseKeyPressEvent(key); } } break; case NativeMethods.WM_SYSKEYUP: case NativeMethods.WM_KEYUP: RaiseKeyUpEvent(keyEventArgs); break; } if(keyEventArgs.SuppressKeyPress) return new IntPtr(1); } } finally { ret = NativeMethods.CallNextHookEx(_previousKeyboardHandler, nCode, wParam, ref kbdStruct); } return ret; }
internal static extern IntPtr CallNextHookEx(SafeWinHandle hhk, int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
public DeadKeyInfo(KBDLLHOOKSTRUCT info, byte[] keyState) { KeyCode = (Keys) info.KeyCode; ScanCode = info.ScanCode; KeyboardState = keyState; }
private static string ToUnicode(KBDLLHOOKSTRUCT info) { string result = null; var keyState = new byte[256]; var buffer = new StringBuilder(128); var success = NativeMethods.GetKeyboardState(keyState); if(!success) return string.Empty; var isAltGr = IsKeyPressed(NativeMethods.VK_RMENU) && IsKeyPressed(NativeMethods.VK_LCONTROL); if (isAltGr) keyState[NativeMethods.VK_LCONTROL] = keyState[NativeMethods.VK_LALT] = 0x80; var layout = GetForegroundKeyboardLayout(); var count = ToUnicode((Keys) info.KeyCode, info.ScanCode, keyState, buffer, layout); if (count > 0) { result = buffer.ToString(0, count); if (_lastDeadKey != null) { ToUnicode(_lastDeadKey.KeyCode, _lastDeadKey.ScanCode, _lastDeadKey.KeyboardState, buffer, layout); _lastDeadKey = null; } } else if (count < 0) { _lastDeadKey = new DeadKeyInfo(info, keyState); while (count < 0) { count = ToUnicode(Keys.Decimal, buffer, layout); } } return result; }