private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) { var keyboardMessage = (WinAPI.USER32.WM)wParam; bool intercept = false; if (Status == DeviceHookStatus.Active) { ThreadPriority oldPriority = Thread.CurrentThread.Priority; try { Thread.CurrentThread.Priority = ThreadPriority.Highest; // it was ok and someone listens to events if (nCode >= 0) { var keyData = (WinAPI.USER32.KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(WinAPI.USER32.KeyboardHookStruct)); // Determine key var virtualKey = (VirtualKey)keyData.vkCode; var key = Tools.WinTool.VirtualKeyToKey(virtualKey); var scanCode = (ScanCode)keyData.scanCode; var asciiChar = DetermineASCIIKeyPressed(keyData); // Determine key state var keyState = KeyState.Unknown; if (keyboardMessage == WinAPI.USER32.WM.KEYDOWN || keyboardMessage == WinAPI.USER32.WM.SYSKEYDOWN) { keyState = KeyState.Down; } else if (keyboardMessage == WinAPI.USER32.WM.KEYUP || keyboardMessage == WinAPI.USER32.WM.SYSKEYUP) { keyState = KeyState.Up; } if (InterceptKeys.Contains(key)) { intercept = true; } // Base method will process rest of logic base.ContinueOutsideCriticalExecutionContext( () => base.ProcessKeyEvent( asciiChar, key, scanCode, keyState, virtualKey.HasFlag(VirtualKey.Shift), virtualKey.HasFlag(VirtualKey.Control), virtualKey.HasFlag(VirtualKey.A) ) ); } } finally { Thread.CurrentThread.Priority = oldPriority; } } if (intercept) { return(new IntPtr(-1)); } return(WinAPI.USER32.CallNextHookEx(_hKeyboardHook, nCode, wParam, lParam)); }