public static void HookKeyboard(HookProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { var module = KERNEL32.GetModuleHandle(curModule.ModuleName); UnhookKeyboard(); HookProc hook = (int nCode, IntPtr wParam, IntPtr lParam) => { proc(nCode, wParam, lParam); return(USER32.CallNextHookEx(_hHook, nCode, wParam, lParam)); }; _hHook = USER32.SetWindowsHookEx(WH_KEYBOARD_LL, hook, module, 0); } }
/// <summary> /// Callback for LL MouseHook /// </summary> private IntPtr MouseCallback(int code, IntPtr wParam, IntPtr lParam) { if (code < 0) { return(USER32.CallNextHookEx(IntPtr.Zero, code, wParam, lParam)); } // Else Process bool handled = false; USER32.MSLLHOOKSTRUCT mse = (USER32.MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(USER32.MSLLHOOKSTRUCT)); int wP = wParam.ToInt32(); MouseButtons button = MouseButtons.None; short mouseDelta = 0; int clickCount = 0; bool mouseDown = false; bool mouseUp = false; bool injected = (mse.flags == USER32.MSLLHOOKSTRUCTFlags.LLMHF_INJECTED); bool isDownAlt = ((USER32.GetKeyState((uint)VirtualKey.VK_MENU) & 0x80) == 0x80 ? true : false); bool isDownCtrl = ((USER32.GetKeyState((uint)VirtualKey.VK_CONTROL) & 0x80) == 0x80 ? true : false); bool isDownShift = ((USER32.GetKeyState((uint)VirtualKey.VK_SHIFT) & 0x80) == 0x80 ? true : false); bool isDownCapslock = (USER32.GetKeyState((uint)VirtualKey.VK_CAPITAL) != 0 ? true : false); bool isDownNumlock = (USER32.GetKeyState((uint)VirtualKey.VK_NUMLOCK) != 0 ? true : false); bool isDownScrolllock = (USER32.GetKeyState((uint)VirtualKey.VK_SCROLL) != 0 ? true : false); switch ((WM)wP) { case WM.LBUTTONDOWN: mouseDown = true; button = MouseButtons.Left; break; case WM.LBUTTONUP: mouseUp = true; button = MouseButtons.Left; clickCount = 1; break; case WM.LBUTTONDBLCLK: button = MouseButtons.Left; clickCount = 2; break; case WM.RBUTTONDOWN: mouseDown = true; button = MouseButtons.Right; clickCount = 1; break; case WM.RBUTTONUP: mouseUp = true; button = MouseButtons.Right; clickCount = 1; break; case WM.RBUTTONDBLCLK: button = MouseButtons.Right; clickCount = 2; break; case WM.MBUTTONDOWN: mouseDown = true; button = MouseButtons.Middle; break; case WM.MBUTTONUP: mouseUp = true; button = MouseButtons.Middle; clickCount = 1; break; case WM.MBUTTONDBLCLK: button = MouseButtons.Middle; clickCount = 2; break; case WM.XBUTTONDOWN: mouseDown = true; button = (((mse.mouseData >> 16) & 0xffff) == 1)? MouseButtons.XButton1 : MouseButtons.XButton2; break; case WM.XBUTTONUP: mouseUp = true; button = (((mse.mouseData >> 16) & 0xffff) == 1) ? MouseButtons.XButton1 : MouseButtons.XButton2; clickCount = 1; break; case WM.XBUTTONDBLCLK: button = (((mse.mouseData >> 16) & 0xffff) == 1) ? MouseButtons.XButton1 : MouseButtons.XButton2; clickCount = 2; break; case WM.MOUSEWHEEL: mouseDelta = (short)((mse.mouseData >> 16) & 0xffff); break; } MouseHookEventArgs e = new MouseHookEventArgs(injected, button, clickCount, mse.pt.X, mse.pt.Y, mouseDelta, isDownAlt, isDownCtrl, isDownShift, isDownCapslock, isDownNumlock, isDownScrolllock); // Mouse up if (this.MouseUp != null && mouseUp) { this.MouseUp.Invoke(e); } // Mouse down if (this.MouseDown != null && mouseDown) { this.MouseDown.Invoke(e); } // If someone listens to click and a click is heppened if (this.MouseClicked != null && mouseUp && clickCount > 0) { if (this.IsDoubleClick(button, mse.time)) { clickCount = 2; } else { this.MouseClicked.Invoke(e); } } // If someone listens to double click and a click is heppened if (this.MouseDoubleClicked != null && mouseUp && clickCount == 2) { this.MouseDoubleClicked.Invoke(e); } // Wheel was moved if (this.MouseWheel != null && mouseDelta != 0) { this.MouseWheel.Invoke(e); } // Mouse Move Event if mouse was moved if (this.MouseMove != null && (MouseHook._oldX != mse.pt.X || MouseHook._oldY != mse.pt.Y)) { MouseHook._oldX = mse.pt.X; MouseHook._oldY = mse.pt.Y; this.MouseMove.Invoke(e); } if (handled) { return(new IntPtr(-1)); } return(USER32.CallNextHookEx(this.mseHook, code, wParam, lParam)); }
/// <summary> /// Callback for LL Keyboard Hook /// </summary> private IntPtr KeyboardCallback(int code, IntPtr wParam, IntPtr lParam) { if (code < 0) { return(USER32.CallNextHookEx(IntPtr.Zero, code, wParam, lParam)); } // Else Process bool handled = false; USER32.KBDLLHOOKSTRUCT kbd = (USER32.KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(USER32.KBDLLHOOKSTRUCT)); int wP = wParam.ToInt32(); bool isInjected = kbd.flags == USER32.KBDLLHOOKSTRUCTFlags.LLKHF_INJECTED; bool isDownAlt = ((USER32.GetKeyState((uint)VirtualKey.VK_MENU) & 0x80) == 0x80 ? true : false); bool isDownCtrl = ((USER32.GetKeyState((uint)VirtualKey.VK_CONTROL) & 0x80) == 0x80 ? true : false); bool isDownShift = ((USER32.GetKeyState((uint)VirtualKey.VK_SHIFT) & 0x80) == 0x80 ? true : false); bool isDownCapslock = (USER32.GetKeyState((uint)VirtualKey.VK_CAPITAL) != 0 ? true : false); bool isDownNumlock = (USER32.GetKeyState((uint)VirtualKey.VK_NUMLOCK) != 0 ? true : false); bool isDownScrolllock = (USER32.GetKeyState((uint)VirtualKey.VK_SCROLL) != 0 ? true : false); // If Key Down if (this.KeyDown != null && (wP == (int)WM.SYSKEYDOWN || wP == (int)WM.KEYDOWN)) { KeyHookEventArgs e = new KeyHookEventArgs(kbd.vkCode, isInjected, isDownAlt, isDownCtrl, isDownShift, isDownCapslock, isDownNumlock, isDownScrolllock); this.KeyDown.Invoke(e); handled = e.Handled; } // Key Press if (this.KeyPressed != null && wP == (int)WM.KEYDOWN) { byte[] keyState = new byte[256]; USER32.GetKeyboardState(keyState); byte[] inBuffer = new byte[2]; if (USER32.ToAscii(kbd.vkCode, kbd.scanCode, keyState, inBuffer, (uint)kbd.flags) == 1) { char key = (char)inBuffer[0]; if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) { key = Char.ToUpper(key); } KeyHookEventArgs e = new KeyHookEventArgs(kbd.vkCode, key, isInjected, isDownAlt, isDownCtrl, isDownShift, isDownCapslock, isDownNumlock, isDownScrolllock); this.KeyPressed.Invoke(e); handled = handled || e.Handled; } } // Key Up if (this.KeyUp != null && (wP == (int)WM.SYSKEYUP || wP == (int)WM.KEYUP)) { Keys keyData = (Keys)kbd.vkCode; KeyHookEventArgs e = new KeyHookEventArgs(kbd.vkCode, isInjected, isDownAlt, isDownCtrl, isDownShift, isDownCapslock, isDownNumlock, isDownScrolllock); this.KeyUp.Invoke(e); handled = handled || e.Handled; } if (handled) { return(new IntPtr(-1)); } return(USER32.CallNextHookEx(this.kbdHook, code, wParam, lParam)); }