using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Reflection; using System.ComponentModel; namespace GeneralFramework { public class MouseKeyHook { [StructLayout(LayoutKind.Sequential)] private class POINT { public int x; public int y; } [StructLayout(LayoutKind.Sequential)] private class MouseHookStruct { public POINT pt; public int hwnd; public int wHitTestCode; public int dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] private class MouseLLHookStruct { public POINT pt; public int mouseData; public int flags; public int time; public int dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] private class KeyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } [DllImport("kernel32.dll")] static extern int GetCurrentThreadId(); //取得当前线程编号的API [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] private static extern int SetWindowsHookEx( int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] private static extern int UnhookWindowsHookEx(int idHook); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int CallNextHookEx( int idHook, int nCode, int wParam, IntPtr lParam); private delegate int HookProc(int nCode, int wParam, IntPtr lParam); [DllImport("user32")] private static extern int ToAscii( int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState); [DllImport("user32")] private static extern int GetKeyboardState(byte[] pbKeyState); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern short GetKeyState(int vKey); private const int WH_MOUSE_LL = 14; private const int WH_KEYBOARD_LL = 13; private const int WH_MOUSE = 7; private const int WH_KEYBOARD = 2; private const int WM_MOUSEMOVE = 0x200; private const int WM_LBUTTONDOWN = 0x201; private const int WM_RBUTTONDOWN = 0x204; private const int WM_MBUTTONDOWN = 0x207; private const int WM_LBUTTONUP = 0x202; private const int WM_RBUTTONUP = 0x205; private const int WM_MBUTTONUP = 0x208; private const int WM_LBUTTONDBLCLK = 0x203; private const int WM_RBUTTONDBLCLK = 0x206; private const int WM_MBUTTONDBLCLK = 0x209; private const int WM_MOUSEWHEEL = 0x020A; private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; private const int WM_SYSKEYDOWN = 0x104; private const int WM_SYSKEYUP = 0x105; private const byte VK_SHIFT = 0x10; private const byte VK_CAPITAL = 0x14; private const byte VK_NUMLOCK = 0x90; public MouseKeyHook() { Start(); } public MouseKeyHook(bool InstallMouseHook, bool InstallKeyboardHook) { Start(InstallMouseHook, InstallKeyboardHook); } ~MouseKeyHook() { Stop(true, true, false); } public event MouseEventHandler OnMouseActivity; public event KeyEventHandler KeyDown; public event KeyPressEventHandler KeyPress; public event KeyEventHandler KeyUp; private int hMouseHook = 0; private int hKeyboardHook = 0; private static HookProc MouseHookProcedure; private static HookProc KeyboardHookProcedure; public void Start() { this.Start(true, true); } public void Start(bool InstallMouseHook, bool InstallKeyboardHook) { if (hMouseHook == 0 && InstallMouseHook) { MouseHookProcedure = new HookProc(MouseHookProc); hMouseHook = SetWindowsHookEx( WH_MOUSE, MouseHookProcedure, IntPtr.Zero, GetCurrentThreadId()); if (hMouseHook == 0) { int errorCode = Marshal.GetLastWin32Error(); Stop(true, false, false); //throw new Win32Exception(errorCode); } } if (hKeyboardHook == 0 && InstallKeyboardHook) { KeyboardHookProcedure = new HookProc(KeyboardHookProc); hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD, KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId()); if (hKeyboardHook == 0) { int errorCode = Marshal.GetLastWin32Error(); Stop(false, true, false); //throw new Win32Exception(errorCode); } } } public void Stop() { this.Stop(true, true, true); } public void Stop(bool UninstallMouseHook, bool UninstallKeyboardHook, bool ThrowExceptions) { if (hMouseHook != 0 && UninstallMouseHook) { int retMouse = UnhookWindowsHookEx(hMouseHook); hMouseHook = 0; if (retMouse == 0 && ThrowExceptions) { int errorCode = Marshal.GetLastWin32Error(); throw new Win32Exception(errorCode); } } if (hKeyboardHook != 0 && UninstallKeyboardHook) { int retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; if (retKeyboard == 0 && ThrowExceptions) { int errorCode = Marshal.GetLastWin32Error(); throw new Win32Exception(errorCode); } } } private int MouseHookProc(int nCode, int wParam, IntPtr lParam) { if ((nCode >= 0) && (OnMouseActivity != null)) { MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct)); MouseButtons button = MouseButtons.None; short mouseDelta = 0; switch (wParam) { case WM_LBUTTONDOWN: button = MouseButtons.Left; break; case WM_RBUTTONDOWN: button = MouseButtons.Right; break; case WM_MOUSEWHEEL: mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff); break; } int clickCount = 0; if (button != MouseButtons.None) if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2; else clickCount = 1; MouseEventArgs e = new MouseEventArgs( button, clickCount, mouseHookStruct.pt.x, mouseHookStruct.pt.y, mouseDelta); OnMouseActivity(this, e); } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { try { if (nCode < 0) { return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } KeyDown(this, null); return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } catch (Exception ex) { return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } } } }