マウスフックを書くためのC#

少しの知識、大きな挑戦!この記事は、「プログラマーに必要な知識」の作成に参加しています。

このカプセル化されたクラスを使用して、最初にフックを登録してから、対応するマウスイベントを追加します。マウスイベントが呼び出され、渡されたパラメータがマウス処理関数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
 
    }
复制代码

おすすめ

転載: juejin.im/post/7020222550735061023
おすすめ