using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace RichCreator.Utility { /// /// 鼠标全局钩子 /// public class MouseHook:IDisposable { public MouseHook(MouseEvent mouseEvent) { this.OnMouseActivity = mouseEvent; } public enum MouseButton:Int32 { None =0, MouseMove = 0x200, LeftButtonDown = 0x201, RightButtonDown = 0x204, middleButtonDown = 0x207, LeftButtonUp = 0x202, RightButtonUp = 0x205, MiddleButtonUp = 0x208, LeftButtonClick = 0x203, RightButtonClick = 0x206, MiddleButtonClick = 0x209, } /// /// 鼠标事件 /// /// /// /// /// public delegate void MouseEvent(Int32 x,Int32 y,Int32 clickCount,MouseButton button); /// /// 点 /// [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; } // 钩子回调函数 private delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); private const int WH_MOUSE_LL = 14; // mouse hook constant // 装置钩子的函数 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); // 卸下钩子的函数 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern bool UnhookWindowsHookEx(int idHook); // 下一个钩挂的函数 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); private event MouseEvent OnMouseActivity; // 全局的鼠标事件 private HookProc mouseHookProcedure;// 声明鼠标钩子事件类型 private static int hMouseHook = 0; // 鼠标钩子句柄 private bool isFinalize=false;//是否已主动释放 /// /// 启动全局钩子 /// public void Start() { // 安装鼠标钩子 if (hMouseHook == 0) { mouseHookProcedure = new HookProc(MouseHookProc); Module module = System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]; // 生成一个HookProc的实例. hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseHookProcedure, Marshal.GetHINSTANCE(module), 0); //假设装置失败停止钩子 if (hMouseHook == 0) { Close(); throw new Exception("SetWindowsHookEx failed."); } } } /// /// 停止全局钩子 /// public void Close() { if (isFinalize) { return; } bool retMouse = true; if (hMouseHook != 0) { retMouse = UnhookWindowsHookEx(hMouseHook); hMouseHook = 0; } // 假设卸下钩子失败 if (!(retMouse)) { throw new Exception("UnhookWindowsHookEx failed."); } isFinalize = true; GC.SuppressFinalize(this); } /// /// 鼠标钩子回调函数 /// private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) { // 假设正常执行而且用户要监听鼠标的消息 if ((nCode >= 0) && (OnMouseActivity != null)) { MouseButton button = MouseButton.None; Enum.TryParse(wParam.ToString(), out button); int clickCount = 0; switch (button) { case MouseButton.LeftButtonDown: clickCount = 1; break; case MouseButton.LeftButtonUp: clickCount = 1; break; case MouseButton.LeftButtonClick: clickCount = 2; break; case MouseButton.RightButtonDown: clickCount = 1; break; case MouseButton.RightButtonUp: clickCount = 1; break; case MouseButton.RightButtonClick: clickCount = 2; break; } // 从回调函数中得到鼠标的信息 MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); //MouseEvent e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0); //// 假设想要限制鼠标在屏幕中的移动区域能够在此处设置 //// 后期须要考虑实际的x、y的容差 //if (!Screen.PrimaryScreen.Bounds.Contains(e.X, e.Y)) //{ // //return 1; //} OnMouseActivity(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y,clickCount, button); } // 启动下一次钩子 return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } public void Dispose() { Close(); } } }