全局钩子监听鼠标和键盘消息

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Service
{
    public class HookExUtils
    {
        private static IntPtr _keyboardHookId;
        private const int WH_KEYBOARD_LL = 13; //键盘钩子
        private const int WM_KEYUP = 0x0101;
        private const int WM_KEYDOWN = 0x0100;

        private const int WH_MOUSE_LL = 14;//鼠标钩子

        private readonly LowLevelKeyboardProc _keyboardProc;
        private static IntPtr _hookId ;
        private readonly HookProc _mouseProcCallback;

        public HookExUtils( )
        {
            _keyboardHookId = IntPtr.Zero;
            _hookId = IntPtr.Zero;
            _keyboardProc = KeyboardHookCallback;
            _mouseProcCallback = HookCallback;
        }

        public static event Action LinseerCopilotKeyUp;
        public static event MouseEventHandler MouseLeftButtonUp;
        public static event MouseEventHandler MouseRightButtonUp;
        public static event MouseEventHandler MouseLeftButtonDown;
        public static event MouseEventHandler MouseMove;

        //todo 测试
        public static event Action ControlCenterKeyUp;

        // 钩子委托定义
        public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
        /// <summary>钩子事件回调函数地址</summary>
        /// <param name="nCode">为传给钩子过程的事件代码</param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);

        public void SetHook()
        {
            _keyboardHookId = SetHook(_keyboardProc, WH_KEYBOARD_LL);
            _hookId = SetHook(_mouseProcCallback, WH_MOUSE_LL);
        }

        public void Unhook()
        {
            if (_keyboardHookId != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_keyboardHookId);
                _keyboardHookId = IntPtr.Zero;
            }

            if (_hookId != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_hookId);
                _hookId = IntPtr.Zero;
            }
        }

        private IntPtr SetHook(Delegate proc, int hookType)
        {
            using var curProcess = Process.GetCurrentProcess();
            using var curModule = curProcess.MainModule;
            return SetWindowsHookEx(hookType, proc, GetModuleHandle(curModule.ModuleName), 0);
        }

        private  IntPtr KeyboardHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode == 124) 
                {
                    LinseerCopilotKeyUp?.Invoke();
                    return (IntPtr)1;
                }
                //if (vkCode == 162)
                //{
                //    ControlCenterKeyUp?.Invoke();
                //    return (IntPtr)1;
                //}
            }

            return CallNextHookEx(_keyboardHookId, nCode, wParam, lParam);
        }

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode != 0 || wParam == IntPtr.Zero)
            {
                return CallNextHookEx(_hookId, nCode, wParam, lParam);
            }
            var mouseMessage = (MouseMessages)wParam;
            var hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
            switch (mouseMessage)
            {
                case MouseMessages.WM_LBUTTONDOWN:
                    MouseEventArgs mouseArgs1 = new MouseEventArgs(MouseButtons.Left, 1, hookStruct.pt.x, hookStruct.pt.y, (int)hookStruct.mouseData);
                    MouseLeftButtonDown?.Invoke(this, mouseArgs1);
                    break;
                case MouseMessages.WM_LBUTTONUP:
                    MouseEventArgs mouseArgs2 = new MouseEventArgs(MouseButtons.Left, 1, hookStruct.pt.x, hookStruct.pt.y, (int)hookStruct.mouseData);
                    MouseLeftButtonUp?.Invoke(this, mouseArgs2);
                    break;
                case MouseMessages.WM_RBUTTONUP:
                    MouseEventArgs mouseArgs3 = new MouseEventArgs(MouseButtons.Right, 1, hookStruct.pt.x, hookStruct.pt.y, (int)hookStruct.mouseData);
                    MouseRightButtonUp?.Invoke(this, mouseArgs3);
                    break;
                case MouseMessages.WM_MOUSEMOVE:
                    MouseEventArgs mouseArgs5 = new MouseEventArgs(MouseButtons.Left, 1, hookStruct.pt.x, hookStruct.pt.y, (int)hookStruct.mouseData);
                    MouseMove?.Invoke(this, mouseArgs5);
                    break;
            }
            return CallNextHookEx(_hookId, nCode, wParam, lParam);
        }

        public enum MouseMessages
        {
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202,
            WM_MOUSEMOVE = 0x0200,
            WM_MOUSEWHEEL = 0x020A,
            WM_RBUTTONDOWN = 0x0204,
            WM_RBUTTONUP = 0x0205
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct POINT
        {
            public int x;
            public int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public nint dwExtraInfo;
        }

        // P/Invoke 函数定义
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, Delegate lpfn, IntPtr hMod, uint dwThreadId);
        [DllImport("user32.dll")]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
        [DllImport("user32.dll")]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    }
}

注册钩子以及应用退出取消钩子注册

private HookExUtils _hookExUtils;
public void CreateHook()
{
_hookExUtils = new HookExUtils();
_hookExUtils.SetHook();
}
private void App_Exit(object sender, ExitEventArgs e)
{
_hookExUtils?.Unhook();
}

  

 

posted on 2025-08-12 17:54  TanZhiWei  阅读(15)  评论(0)    收藏  举报