添加钩子监听全局鼠标或键盘事件

  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/

原文地址:https://www.cnblogs.com/jieliu726/p/5013739.html