windows下侦听全局鼠标事件(利用win32-API)

一、需求说明

正常情况下,Qt获取鼠标事件都是获取窗口内的鼠标事件,当窗口、控件 获取焦点之后,点击窗口内的控件,Qt都可以获取到鼠标事件。 如果窗口没有获取到焦点,或者 点击软件范围外的其他地方,Qt正常的事件捕获就无法监听鼠标的动作了。

现在的需求是: 需要在软件之外,任何地方点击鼠标,Qt程序里都能获取到数据事件,实现全局鼠标事件侦听。

这个可以利用win32的API接口SetWindowsHookEx来实现侦听。

具体实现代码看下面。

二、实现代码

侦听全局鼠标事件用到了windows系统API函数。

完整的测试代码如下:

cpp 复制代码
 #include "widget.h"
 #include "ui_widget.h"
 #include <Windows.h>
 #include <QDebug>
 #pragma execution_character_set("utf-8")
 ​
 #pragma comment(lib, "user32.lib")
 HHOOK hHook = NULL;
 using namespace std;
 ​
 ​
 /*
 WM_MOUSEMOVE = 0x200
 WM_LBUTTONDOWN = 0x201
 WM_LBUTTONUP = 0x202
 WM_LBUTTONDBLCLK = 0x203
 WM_RBUTTONDOWN = 0x204
 WM_RBUTTONUP = 0x205
 WM_RBUTTONDBLCLK = 0x206  双击事件
 WM_MBUTTONDOWN = 0x207
 WM_MBUTTONUP = 0x208
 WM_MBUTTONDBLCLK = 0x209
 WM_MOUSEWHEEL = 0x20A
 WM_XBUTTONDOWN = 0x20B
 WM_XBUTTONUP = 0x20C
 WM_XBUTTONDBLCLK = 0x20D
 WM_MOUSEHWHEEL = 0x20E
 */
 LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
 {
     switch(wParam)
     {
       case WM_LBUTTONDOWN:  //鼠标左键按下
            qDebug() << "鼠标左键按下";
         break;
       case WM_RBUTTONDOWN://鼠标右键键按下
          qDebug() << "鼠标右键键按下";
       break;
     }
     return CallNextHookEx(hHook, nCode, wParam, lParam);
 }
 ​
 ​
 Widget::Widget(QWidget *parent)
     : QWidget(parent)
     , ui(new Ui::Widget)
 {
     ui->setupUi(this);
 ​
     hHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);
     if (hHook == NULL)
     {
         qDebug() << "Hook failed";
     }
     else
     {
         qDebug() << "Hook Success";
     }
 }
 ​
 ​
 Widget::~Widget()
 {
     delete ui;
 }
 ​
 ​

三、利用win32-API模拟鼠标事件发送

3.1 mouse_event函数

cpp 复制代码
 VOID WINAPI mouse_event(
   _In_ DWORD     dwFlags,
   _In_ DWORD     dx,
   _In_ DWORD     dy,
   _In_ DWORD     dwData,
   _In_ ULONG_PTR dwExtraInfo
 );

dwFlags的常用选项如下:

cpp 复制代码
 MOUSEEVENTF_ABSOLUTE 是否使用绝对坐标
 ​
 MOUSEEVENTF_LEFTDOWN 鼠标左键按下
 ​
 MOUSEEVENTF_LEFTUP 鼠标左键松开
 ​
 MOUSEEVENTF_MIDDLEDOWN 鼠标中键按下
 ​
 MOUSEEVENTF_MIDDLEUP 鼠标中键松开
 ​
 MOUSEEVENTF_MOVE 鼠标移动
 ​
 MOUSEEVENTF_RIGHTDOWN 鼠标右键按下
 ​
 MOUSEEVENTF_RIGHTUP 鼠标右键按下
 ​
 MOUSEEVENTF_WHEEL 鼠标滑轮

3.2 包含的头文件与库文件

cpp 复制代码
 #include <Windows.h>
 #pragma comment(lib, "user32.lib")

3.3 使用案例

cpp 复制代码
 使用鼠标模拟单击事件
 int x = 50;
 int y = 50;
 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,x, y, 0, 0);
 ​
 双击事件
 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,x, y, 0, 0);
 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP,x, y, 0, 0);
 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,x, y, 0, 0);
 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP,x, y, 0, 0);
 ​
 滚轮事件,delta为滚轮的值
 mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_WHEEL,p.x(), p.y(), delta, 0);
相关推荐
Victor3563 小时前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
Victor3563 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术4 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
Gogo8165 小时前
BigInt 与 Number 的爱恨情仇,为何大佬都劝你“能用 Number 就别用 BigInt”?
后端
fuquxiaoguang5 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
毕设源码_廖学姐6 小时前
计算机毕业设计springboot招聘系统网站 基于SpringBoot的在线人才对接平台 SpringBoot驱动的智能求职与招聘服务网
spring boot·后端·课程设计
野犬寒鸦8 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
逍遥德8 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
MX_93599 小时前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
程序员泠零澪回家种桔子10 小时前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构