Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

With this wrapped class, you first register the hook and then add the corresponding mouse event. MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) specifies when the mouse event is called and passed. So all other attributes of the MouseEventArg parameter class originally defined are set to 0. The MouseHookProc function is called inside the mouse hook registration method.

    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
 
    }
Copy the code