winform监听全局鼠标事件

如果您希望监听全局鼠标事件,即使在其他应用程序(如浏览器或其他软件)中按下鼠标按钮也能捕捉到这些事件,您需要使用低级别的Windows API钩子。WinForms本身并不直接支持全局事件监听,但通过调用Windows API,可以实现这一功能。

winform监听全局鼠标事件

如果您希望监听全局鼠标事件,即使在其他应用程序(如浏览器或其他软件)中按下鼠标按钮也能捕捉到这些事件,您需要使用低级别的Windows API钩子。WinForms本身并不直接支持全局事件监听,但通过调用Windows API,可以实现这一功能。

使用全局鼠标钩子

为了实现全局鼠标事件监听,您可以使用SetWindowsHookEx函数来安装一个鼠标钩子。这将允许您的应用程序接收所有鼠标事件的通知,而不论鼠标指针位于哪个窗口之上。

步骤 1: 定义必要的常量和结构体

首先,定义一些常量和结构体,以便与Windows API进行交互

复制代码
  public class GlobalMouseHook : IDisposable
  {
        // 钩子类型 - 全局鼠标钩子
        private const int WH_MOUSE_LL = 14;
​
        // 鼠标消息
        private const int WM_LBUTTONDOWN = 0x0201;
        private const int WM_RBUTTONDOWN = 0x0204;
​
        // 钩子句柄
        private IntPtr _hookID = IntPtr.Zero;
​
        // 钩子过程委托
        private LowLevelMouseProc _proc;
​
        // 钩子过程委托类型
        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
​
        // MSLLHOOKSTRUCT 结构
        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }
​
        // POINT 结构
        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public int x;
            public int y;
        } // 设置钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
​
        // 移除钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
​
        // 调用下一个钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
​
        // 获取当前进程模块句柄
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
        private Mainform _mainForm; // 用来存储 MainForm 实例
        public GlobalMouseHook(Mainform mainForm)
         {
            _mainForm = mainForm;
            _proc = HookCallback;
            _hookID = SetHook(_proc);
        }
​
        private IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }
​
        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && (wParam == (IntPtr)WM_LBUTTONDOWN || wParam == (IntPtr)WM_RBUTTONDOWN))
            {
                MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
                if (wParam == (IntPtr)WM_LBUTTONDOWN)
                {
                    _mainForm.richTextBox1.Text = "全局鼠标左键按下";
                    //MessageBox.Show($"全局鼠标左键按下:({hookStruct.pt.x}, {hookStruct.pt.y})");
                }
                else if (wParam == (IntPtr)WM_RBUTTONDOWN)
                {
                    _mainForm.richTextBox1.Text = "全局鼠标右键按下";
​
                    //MessageBox.Show($"全局鼠标右键按下:({hookStruct.pt.x}, {hookStruct.pt.y})");
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
​
        public void Dispose()
        {
            UnhookWindowsHookEx(_hookID);
        }
    }

// 创建 GlobalMouseHook 实例并传递当前 MainForm 实例 GlobalMouseHook mouseHook = new GlobalMouseHook(this);

相关推荐
_李小白8 小时前
【OSG学习笔记】Day 49: 实战鼠标拾取与高亮显示
笔记·学习·计算机外设
科技重器10 小时前
科技+绿色|京东方推出低碳3.0显示器,集高性能与绿色低碳于一身
科技·计算机外设
rit84324991 天前
基于STM32的触控USB鼠标设计
stm32·嵌入式硬件·计算机外设
陳10302 天前
Linux:进程的基本理解
linux·计算机外设·进程
站长工具箱2 天前
基于浏览器的键盘按键测试工具功能解析
测试工具·计算机外设
ACP广源盛139246256733 天前
破局 Type‑C 切换器痛点@ACP#GSV6155+LH3828/GSV2221+LH3828 黄金方案
c语言·开发语言·网络·人工智能·嵌入式硬件·计算机外设·电脑
网络探索者4 天前
换了新显示器怎么验?我做了一个开箱即用的全平台屏幕检测工具
计算机外设
weixin_423995004 天前
unity 物体转向鼠标点击方向2d和3d
unity·计算机外设·游戏引擎
破烂儿5 天前
TMUX历史输出滚动查看全攻略(原生快捷键 + 鼠标配置优化)
服务器·学习·计算机外设
开开心心就好6 天前
支持自定义名单的实用随机抽签工具
windows·计算机视觉·计算机外设·excel·散列表·启发式算法·csdn开发云