添加钩子监听全局鼠标或键盘事件
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Reflection; 5 using System.Runtime.InteropServices; 6 using System.Text; 7 using System.Threading.Tasks; 8 using System.Windows.Forms; 9 10 namespace WinGPChat 11 { 12 /// <summary> 13 /// 这个类可以让你得到一个在运行中程序的所有键盘或鼠标事件 14 /// 并且引发一个带KeyEventArgs参数的.NET事件以便你很容易使用这些信息 15 /// </summary> 16 public class KeyBordHook 17 { 18 private const int WM_KEYDOWN = 0x100; 19 private const int WM_KEYUP = 0x101; 20 private const int WM_SYSKEYDOWN = 0x104; 21 private const int WM_SYSKEYUP = 0x105; 22 //全局的事件 23 public event KeyEventHandler OnKeyDownEvent; 24 public event KeyEventHandler OnKeyUpEvent; 25 public event KeyPressEventHandler OnKeyPressEvent; 26 static int hKeyboardHook = 0; //键盘钩子句柄 27 //鼠标常量 28 public const int WH_KEYBOARD_LL = 13; //keyboard hook constant 29 HookProc KeyboardHookProcedure; //声明键盘钩子事件类型. 30 //声明键盘钩子的封送结构类型 31 [StructLayout(LayoutKind.Sequential)] 32 public class KeyboardHookStruct 33 { 34 public int vkCode; //表示一个在1到254间的虚似键盘码 35 public int scanCode; //表示硬件扫描码 36 public int flags; 37 public int time; 38 public int dwExtraInfo; 39 } 40 //装置钩子的函数 41 [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 42 public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); 43 //卸下钩子的函数 44 [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 45 public static extern bool UnhookWindowsHookEx(int idHook); 46 //下一个钩挂的函数 47 [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 48 public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); 49 [DllImport("user32 ")] 50 public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState); 51 [DllImport("user32 ")] 52 public static extern int GetKeyboardState(byte[] pbKeyState); 53 public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); 54 /// <summary> 55 /// 墨认的构造函数构造当前类的实例并自动的运行起来. 56 /// </summary> 57 public KeyBordHook() 58 { 59 Start(); 60 } 61 //析构函数. 62 ~KeyBordHook() 63 { 64 Stop(); 65 } 66 public void Start() 67 { 68 //安装键盘钩子 69 if (hKeyboardHook == 0) 70 { 71 KeyboardHookProcedure = new HookProc(KeyboardHookProc); 72 hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().ManifestModule), 0); 73 if (hKeyboardHook == 0) 74 { 75 Stop(); 76 throw new Exception("SetWindowsHookEx ist failed. "); 77 } 78 } 79 } 80 public void Stop() 81 { 82 bool retKeyboard = true; 83 if (hKeyboardHook != 0) 84 { 85 retKeyboard = UnhookWindowsHookEx(hKeyboardHook); 86 hKeyboardHook = 0; 87 } 88 //如果卸下钩子失败 89 if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed. "); 90 } 91 private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) 92 { 93 if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null)) 94 { 95 KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); 96 //引发OnKeyDownEvent 97 if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) 98 { 99 Keys keyData = (Keys)MyKeyboardHookStruct.vkCode; 100 KeyEventArgs e = new KeyEventArgs(keyData); 101 OnKeyDownEvent(this, e); 102 } 103 //引发OnKeyPressEvent 104 if (OnKeyPressEvent != null && wParam == WM_KEYDOWN) 105 { 106 byte[] keyState = new byte[256]; 107 GetKeyboardState(keyState); 108 byte[] inBuffer = new byte[2]; 109 if (ToAscii(MyKeyboardHookStruct.vkCode, 110 MyKeyboardHookStruct.scanCode, 111 keyState, 112 inBuffer, 113 MyKeyboardHookStruct.flags) == 1) 114 { 115 KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]); 116 OnKeyPressEvent(this, e); 117 } 118 } 119 //引发OnKeyUpEvent 120 if (OnKeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)) 121 { 122 Keys keyData = (Keys)MyKeyboardHookStruct.vkCode; 123 KeyEventArgs e = new KeyEventArgs(keyData); 124 OnKeyUpEvent(this, e); 125 } 126 } 127 return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); 128 } 129 } 130 131 /// <summary> 132 /// 这个类可以让你得到一个在运行中程序的所有鼠标事件 133 /// 并且引发一个带MouseEventArgs参数的.NET鼠标事件以便你很容易使用这些信息 134 /// </summary> 135 public class MouseHook 136 { 137 private const int WM_MOUSEMOVE = 0x200; 138 private const int WM_LBUTTONDOWN = 0x201; 139 private const int WM_RBUTTONDOWN = 0x204; 140 private const int WM_MBUTTONDOWN = 0x207; 141 private const int WM_LBUTTONUP = 0x202; 142 private const int WM_RBUTTONUP = 0x205; 143 private const int WM_MBUTTONUP = 0x208; 144 private const int WM_LBUTTONDBLCLK = 0x203; 145 private const int WM_RBUTTONDBLCLK = 0x206; 146 private const int WM_MBUTTONDBLCLK = 0x209; 147 //全局的事件 148 public event MouseEventHandler OnMouseActivity; 149 static int hMouseHook = 0; //鼠标钩子句柄 150 //鼠标常量 151 public const int WH_MOUSE_LL = 14; //mouse hook constant 152 HookProc MouseHookProcedure; //声明鼠标钩子事件类型. 153 //声明一个Point的封送类型 154 [StructLayout(LayoutKind.Sequential)] 155 public class POINT 156 { 157 public int x; 158 public int y; 159 } 160 //声明鼠标钩子的封送结构类型 161 [StructLayout(LayoutKind.Sequential)] 162 public class MouseHookStruct 163 { 164 public POINT pt; 165 public int hWnd; 166 public int wHitTestCode; 167 public int dwExtraInfo; 168 } 169 //装置钩子的函数 170 [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 171 public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); 172 //卸下钩子的函数 173 [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 174 public static extern bool UnhookWindowsHookEx(int idHook); 175 //下一个钩挂的函数 176 [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 177 public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); 178 public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); 179 /// <summary> 180 /// 墨认的构造函数构造当前类的实例. 181 /// </summary> 182 public MouseHook() 183 { 184 //Start(); 185 } 186 //析构函数. 187 ~MouseHook() 188 { 189 Stop(); 190 } 191 public void Start() 192 { 193 //安装鼠标钩子 194 if (hMouseHook == 0) 195 { 196 //生成一个HookProc的实例. 197 MouseHookProcedure = new HookProc(MouseHookProc); 198 hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0); 199 //如果装置失败停止钩子 200 if (hMouseHook == 0) 201 { 202 Stop(); 203 throw new Exception("SetWindowsHookEx failed. "); 204 } 205 } 206 } 207 public void Stop() 208 { 209 bool retMouse = true; 210 if (hMouseHook != 0) 211 { 212 retMouse = UnhookWindowsHookEx(hMouseHook); 213 hMouseHook = 0; 214 } 215 //如果卸下钩子失败 216 if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed. "); 217 } 218 private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) 219 { 220 //如果正常运行并且用户要监听鼠标的消息 221 if ((nCode >= 0) && (OnMouseActivity != null)) 222 { 223 MouseButtons button = MouseButtons.None; 224 int clickCount = 0; 225 switch (wParam) 226 { 227 case WM_LBUTTONDOWN: 228 button = MouseButtons.Left; 229 clickCount = 1; 230 break; 231 case WM_LBUTTONUP: 232 button = MouseButtons.Left; 233 clickCount = 1; 234 break; 235 case WM_LBUTTONDBLCLK: 236 button = MouseButtons.Left; 237 clickCount = 2; 238 break; 239 case WM_RBUTTONDOWN: 240 button = MouseButtons.Right; 241 clickCount = 1; 242 break; 243 case WM_RBUTTONUP: 244 button = MouseButtons.Right; 245 clickCount = 1; 246 break; 247 case WM_RBUTTONDBLCLK: 248 button = MouseButtons.Right; 249 clickCount = 2; 250 break; 251 } 252 //从回调函数中得到鼠标的信息 253 MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); 254 MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0); 255 OnMouseActivity(this, e); 256 } 257 return CallNextHookEx(hMouseHook, nCode, wParam, lParam); 258 } 259 } 260 }
/// <summary> /// 钩子类型监听鼠标键盘等事件句柄 /// </summary> private enum HookType : int { WH_JOURNALRECORD = 0, WH_JOURNALPLAYBACK = 1, WH_KEYBOARD = 2, WH_GETMESSAGE = 3, WH_CALLWNDPROC = 4, WH_CBT = 5, WH_SYSMSGFILTER = 6, WH_MOUSE = 7,//局部 线程级别 WH_HARDWARE = 8, WH_DEBUG = 9, WH_SHELL = 10, WH_FOREGROUNDIDLE = 11, WH_CALLWNDPROCRET = 12, WH_KEYBOARD_LL = 13, WH_MOUSE_LL = 14 //全局 } /// <summary> /// 鼠标或键盘事件常量值 /// </summary> 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;
转载:http://blog.163.com/epeda@126/blog/static/418034782012798394905/