windows操作系统 C#编写鼠标钩子
2014-10-22 11:13
225 查看
要做一个东西,由于捕获不到相应的事件,而这个东西又要用鼠标操作,所以找了下质料可以用鼠标钩子实现。自己也没用过鼠标钩子,看了别人的例子,实践到项目中就解决问题了。把代码记录下来以备以后用和更深入的学习。
用该封装的类,首先注册钩子,然后添加相应的鼠标事件。其中鼠标事件什么时候调用和传递的参数都是在鼠标处理函数MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)里面完成,本例中由于鼠标处理不需要参数,仅需要获取按下的是左键还是又见,所以原本定义的MouseEventArg参数类其他属性都赋值为0。而鼠标处理函数MouseHookProc的调用则是在鼠标钩子注册方法里面调用的。
class MouseHook { //枚举定义 public enum WH_Codes : int { /// <summary> /// 底层鼠标钩子 /// </summary> WH_MOUSE_LL = 14 } public enum WM_MOUSE : int { /// <summary> /// 鼠标开始 /// </summary> WM_MOUSEFIRST = 0x200, /// <summary> /// 鼠标移动 /// </summary> WM_MOUSEMOVE = 0x200, /// <summary> /// 左键按下 /// </summary> WM_LBUTTONDOWN = 0x201, /// <summary> /// 左键释放 /// </summary> WM_LBUTTONUP = 0x202, /// <summary> /// 左键双击 /// </summary> WM_LBUTTONDBLCLK = 0x203, /// <summary> /// 右键按下 /// </summary> WM_RBUTTONDOWN = 0x204, /// <summary> /// 右键释放 /// </summary> WM_RBUTTONUP = 0x205, /// <summary> /// 右键双击 /// </summary> WM_RBUTTONDBLCLK = 0x206, /// <summary> /// 中键按下 /// </summary> WM_MBUTTONDOWN = 0x207, /// <summary> /// 中键释放 /// </summary> WM_MBUTTONUP = 0x208, /// <summary> /// 中键双击 /// </summary> WM_MBUTTONDBLCLK = 0x209, /// <summary> /// 滚轮滚动 /// </summary> /// <remarks>WINNT4.0以上才支持此消息</remarks> WM_MOUSEWHEEL = 0x020A } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; } /// <summary> /// 鼠标钩子事件结构定义 /// </summary> /// <remarks>详细说明请参考MSDN中关于 MSLLHOOKSTRUCT 的说明</remarks> [StructLayout(LayoutKind.Sequential)] public struct MouseHookStruct { public POINT Point; public UInt32 MouseData; public UInt32 Flags; public UInt32 Time; public UInt32 ExtraInfo; } #region DLL导入 /// <summary> /// 安装钩子 /// </summary> /// <param name="idHook"></param> /// <param name="lpfn"></param> /// <param name="hInstance"></param> /// <param name="threadId"></param> /// <returns></returns> [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern IntPtr SetWindowsHookEx(WH_Codes idHook, HookProc lpfn, IntPtr pInstance, int threadId); /// <summary> /// 卸载钩子 /// </summary> /// <param name="idHook"></param> /// <returns></returns> [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle); /// <summary> /// 传递钩子 /// </summary> /// <param name="idHook"></param> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(IntPtr pHookHandle, int nCode, Int32 wParam, IntPtr lParam); #endregion DLL导入 //鼠标钩子句柄 private IntPtr m_pMouseHook = IntPtr.Zero; /// <summary> /// 钩子委托声明 /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); /// <summary> /// 鼠标钩子委托实例 /// </summary> /// <remarks> /// 不要试图省略此变量,否则将会导致 /// 激活 CallbackOnCollectedDelegate 托管调试助手 (MDA)。 /// 详细请参见MSDN中关于 CallbackOnCollectedDelegate 的描述 /// </remarks> private HookProc m_MouseHookProcedure; #region 事件定义 /// <summary> /// 鼠标移动事件 /// </summary> /// <remarks>当鼠标移动或者滚轮滚动时触发</remarks> public event MouseEventHandler OnMouseMove; /// <summary> /// 鼠标按下事件 /// </summary> public event MouseEventHandler OnMouseDown; /// <summary> /// 按键释放事件 /// </summary> public event MouseEventHandler OnMouseUp; #endregion #region 私有方法 /// <summary> /// 鼠标钩子处理函数 /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) { if ((nCode >= 0) && (this.OnMouseMove != null) && (wParam == (int)WM_MOUSE.WM_MOUSEMOVE ||wParam == (int)WM_MOUSE.WM_MOUSEWHEEL)) { //MouseHookStruct MouseInfo = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); this.OnMouseMove(null,null); } if ((nCode >= 0) && (this.OnMouseDown != null)&&(wParam==(int)WM_MOUSE.WM_LBUTTONDOWN||wParam==(int)WM_MOUSE.WM_RBUTTONDOWN)) { MouseButtons button = MouseButtons.None; switch (wParam) { case (int)WM_MOUSE.WM_LBUTTONDOWN: //case WM_LBUTTONUP: //case WM_LBUTTONDBLCLK: button = MouseButtons.Left; break; case (int)WM_MOUSE.WM_RBUTTONDOWN: //case WM_RBUTTONUP: //case WM_RBUTTONDBLCLK: button = MouseButtons.Right; break; } MouseEventArgs e = new MouseEventArgs( button, 0, 0, 0, 0 ); this.OnMouseDown(null, e); } if ((nCode >= 0) && (this.OnMouseDown != null) && (wParam == (int)WM_MOUSE.WM_LBUTTONUP || wParam == (int)WM_MOUSE.WM_RBUTTONUP)) { MouseButtons button = MouseButtons.None; switch (wParam) { case (int)WM_MOUSE.WM_LBUTTONUP: //case WM_LBUTTONUP: //case WM_LBUTTONDBLCLK: button = MouseButtons.Left; break; case (int)WM_MOUSE.WM_RBUTTONUP: //case WM_RBUTTONUP: //case WM_RBUTTONDBLCLK: button = MouseButtons.Right; break; } MouseEventArgs e = new MouseEventArgs( button, 0, 0, 0, 0 ); this.OnMouseUp(null, e); } return CallNextHookEx(this.m_pMouseHook, nCode, wParam, lParam); } #endregion #region 公共方法 /// <summary> /// 安装钩子 /// </summary> /// <returns></returns> public bool InstallHook() { IntPtr pInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().ManifestModule); //pInstance = (IntPtr)4194304; // IntPtr pInstanc2 = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly()); // Assembly.GetExecutingAssembly().GetModules()[0] // 假如没有安装鼠标钩子 if (this.m_pMouseHook == IntPtr.Zero) { this.m_MouseHookProcedure = new HookProc(this.MouseHookProc); this.m_pMouseHook = SetWindowsHookEx(WH_Codes.WH_MOUSE_LL, this.m_MouseHookProcedure, pInstance, 0); if (this.m_pMouseHook == IntPtr.Zero) { this.UnInstallHook(); return false; } } return true; } /// <summary> /// 卸载钩子 /// </summary> /// <returns></returns> public bool UnInstallHook() { bool result = true; if (this.m_pMouseHook != IntPtr.Zero) { result = (UnhookWindowsHookEx(this.m_pMouseHook) && result); this.m_pMouseHook = IntPtr.Zero; } return result; } #endregion }
用该封装的类,首先注册钩子,然后添加相应的鼠标事件。其中鼠标事件什么时候调用和传递的参数都是在鼠标处理函数MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)里面完成,本例中由于鼠标处理不需要参数,仅需要获取按下的是左键还是又见,所以原本定义的MouseEventArg参数类其他属性都赋值为0。而鼠标处理函数MouseHookProc的调用则是在鼠标钩子注册方法里面调用的。
相关文章推荐
- [导入]C#利用钩子控制鼠标【月儿原创】
- C#钩子实现简单鼠标键盘的监控和屏蔽
- C#中通过设置钩子监视鼠标移动
- C#鼠标键盘钩子
- 使用C#钩子监视全局鼠标位置
- C#利用钩子控制鼠标【月儿原创】
- C#利用钩子控制鼠标
- C#中通过设置钩子监视鼠标移动
- c#中设置钩子监视鼠标移动
- C#实现鼠标、键盘钩子
- c#中通过设置钩子监视鼠标移动
- c#中通过设置钩子监视鼠标移动
- C#中通过设置钩子监视鼠标移动
- C#中通过设置钩子监视鼠标移动
- C#用鼠标钩子屏蔽任务栏右键弹出菜单
- C#鼠标钩子(你的鼠标坐标我也知道)
- 【转】C#鼠标钩子
- C#中通过设置钩子监视鼠标移动
- c# 安装局部鼠标钩子 张宇轩
- C#全局鼠标钩子