当前位置: 首页 > news >正文

Qt使用API实现鼠标点击操作

前段时间,工作需要进行数据录入,每次都要点击3次按钮,想让鼠标自行点击,只要下位机接入,就自动点击按钮把数据读出,录入到服务端,并且进行检测,说干就干,没有经验,那只有面向百度编程.

根据查到的资料,可以使用WinAPI进行鼠标模似.可以使用的函数有两个,一个是SendMessageA(),一个是mouse_evnet();进行鼠标操作的模似;

SendMessageA()的参数说明:

LRESULT SendMessageA([in] HWND   hWnd,[in] UINT   Msg,[in] WPARAM wParam,[in] LPARAM lParam
);

hWnd:指定要接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

Msg:指定被发送的消息。

wParam:指定附加的消息特定信息。

IParam:指定附加的消息特定信息。

返回值:返回值指定消息处理的结果,依赖于所发送的消息。

备注:需要用HWND_BROADCAST通信的应用程序应当使用函数RegisterWindowMessage来为应用程序间的通信取得一个唯一的消息。

如果指定的窗口是由正在调用的线程创建的,则窗口程序立即作为子程序调用。如果指定的窗口是由不同线程创建的,则系统切换到该线程并调用恰当的窗口程序。线程间的消息只有在线程执行消息检索代码时才被处理。发送线程被阻塞直到接收线程处理完消息为止。

mouse_evnet()的参数说明

VOID mouse_event(DWORD     dwFlags,     // motion and click optionsDWORD     dx,          // horizontal position or changeDWORD     dy,          // vertical position or changeDWORD     dwData,      // wheel movementULONG_PTR dwExtraInfo  // application-defined information
);

dwFlags

标志位集,指定点击按钮和鼠标动作的多种情况。此参数可以是下列值的某种组合:

名称

说明

MOUSEEVENTF_ABSOLUTE

dX和dY参数含有规范化的绝对坐标。如果不设置,这些参数含有相对数据:相对于上次位置的改动位置。此标志可设置,也可不设置,不管鼠标的类型或与系统相连的类似于鼠标的设备的类型如何。要得到关于相对鼠标动作的信息,参见下面备注部分。

MOUSEEVENTF_MOVE

这表示鼠标移动

MOUSEEVENTF_LEFTDOWN

这表示鼠标左键按下

MOUSEEVENTF_LEFTUP

这表示鼠标左键松开

MOUSEEVENTF_RIGHTDOWN

这表示鼠标右键按下

MOUSEEVENTF_RIGHTUP

这表示鼠标右键松开

MOUSEEVENTF_MIDDLEDOWN

这表示鼠标中键按下

MOUSEEVENTF_MIDDLEUP

这表示鼠标中键松开

MOUSEEVENTF_WHEEL

这表示鼠标轮被滚动,如果鼠标有一个滚轮。滚动的数量由dwData给出。

dx

指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。

dy

指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。

dwData

如果dwFlags为MOUSEEVENTF_WHEEL,则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。一个轮击定义为WHEEL_DELTA,即120。如果dwFlagsS不是MOUSEEVENTF_WHEEL,则dWData应为零。

dwExtralnfo

指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessageExtraInfo来获得此附加信息。

简单的翻译一下上在面的说明就是SendMessageA()可以用来发送任何消息,包括鼠标消息,发送的时候,有返回值,非0就是成功.但是此函数发送鼠标消息的时候不需要控制鼠标.

而mouse_evnet(),则需要控制鼠标移动到目标上操作.

好处是,SendMessageA()是相当于后台操作,属于是静默型,而mouse_evnet()则需要控制鼠标实际移动,也就是你使用了这个,任务没有安成前,你是无法使用鼠标的.

OK,了解了具体的函数之后,开始准备编写代码.经过测试

SendMessageA()需要传入组件的句柄,才可以进行消息传递,(经过测试,使用相对坐标,无法无成消息传递),

使用举例:SendMessageA(hwind,msg,wParam,lParam);

hwind:指的是窗口句柄,也就是窗口的唯一标识号,你要在哪个窗口传递消息,就指定窗口句柄即可.

msg:消息类型,指的是,你要给指定口传递什么消息.

wParam:消息附加说明,此处可以填写0,或者指定说明

lParam:组件句柄(这里貌似只能填写句柄,填写相对坐标是无法成功的个人已经测试验证)

Qt中使用方式:

//使用此函数,必须引入windows.h头文件
#include <windows.h>SendMessageA((HWND)winId(), WM_LBUTTONDOWN, BM_CLICK, 0);
SendMessageA((HWND)winId(), WM_LBUTTONUP, BM_CLICK, 0);
//WM_LBUTTONUP 左键抬起,
//BM_CLICK 按钮消息 点击

最后一个参数,其实是要填写按钮的句柄,如果你要发消的窗口是自绘的,那么此函数就不适用了.

此时可以采用第mouseEvent()具体的使用方法

//第一个参数:鼠标移动事件,也就是把鼠标移动到指定的坐标,第二个参数,和第3个参数是坐标的X和Y,此处需要进行计算点击位置相对于窗口的相对坐标,这里不坐讨论,网上有很多相关的资料,此处演示的是其中的一种,
//窗口左*65535/当前分辨率的X,窗口左*65535/当前分辨率的Y,最后两个参数不设置,填0
mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, getDzzcleft * 65535 / resolution_x, getDzzcTop * 65535 / resolution_y,0 ,0);
//第一个参数,左键按下
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
//第一个参数,左键抬起mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);

思路:首先你需要获取组件在窗口上的相对坐标,然后再进行点击,这是因为,组件相对于窗口,这个坐标是恒定不变的,变化的只是窗口本身在桌面的位置,获取窗口在桌面的位置,需要先获取当前显示器的分辨率

这其中还有一个缩放比的问体,就是用户把窗体的大小改变了一点,此时,就需要重新计算了,我为了实现基本功能,把窗体的大小进行了固定,所以就规避了计算缩放比的问题.

EnumDisplaySettings()
获取分辨率的函数

思路:首先你需要获取组件在窗口上的相对坐标,然后再进行点击,这是因为,组件相对于窗口,这个坐标是恒定不变的,变化的只是窗口本身在桌面的位置,获取窗口在桌面的位置,需要先获取当前显示器的分辨率

这其中还有一个缩放比的问体,就是用户把窗体的大小改变了一点,此时,就需要重新计算了,我为了实现基本功能,把窗体的大小进行了固定,所以就规避了计算缩放比的问题.

brEnumDisplaySettings()br获取分辨率的函数

第一步我们需要获取这个目标窗口

使用GetWindowrect();获取窗口矩形,然后显示这个窗口,使用ShowWindow显示的目录是为了激活目标窗体,并且将其置于顶层.

声明一个矩形变量 RECT rec

GetWindowRect(WindowHandle,&rec);
ShowWindow(WindowHandle, SW_NORMAL);

然后通把rec.left + 组件坐标.x 获取鼠标点击位置的x,rec.top + 组件坐标.y 获取鼠标点击位置的y

SetCursorPos(x,y);

将鼠标指针移动到 x,y,再使用mouse_event(),则实现了点击.

此方法使用QT5.9已经测试成功。

http://www.lryc.cn/news/35380.html

相关文章:

  • JavaWeb学习-Tomcat
  • 【蓝牙系列】蓝牙5.4到底更新了什么(2)
  • js中window自带的四舍五入toFixed方法中的坑以及解决办法
  • JeecgBoot 3.5.0 版本发布,开源的企业级低代码平台
  • 行测-判断推理-图形推理-样式规律-空间重构-四面体和八面体
  • HTML5新特性
  • TDengine Schemaless(无模式写入)常见问题的原因及故障排除
  • 【前端八股文】浏览器系列:浏览器渲染、前端路由、前端缓存(HTTP缓存)、缓存存储(HTTP缓存存储、本地存储)
  • SpiderFlow爬虫获取网页节点
  • “微服务架构:优点、缺点及实现方式“
  • c/c++实现crc码计算和校验
  • 漏洞分析丨cve20110104
  • 关于vue-router路径配置的问题(此文主要是记录三级路由的访问路径,以及安装、路由组件、路由重定向)
  • SpringBoot 整合 clickhouse和mysql 手把手教程全网最详细
  • Leetcode-java 数据结构回顾 Day01
  • Java spring cloud 企业工程管理系统源码+项目模块功能清单
  • 用Biome-BGC模型如何模拟水循环过程
  • 【目标检测论文解读复现NO.33】改进YOLOv5的新能源电池集流盘缺陷检测方法
  • 二进制转换之命理学习
  • es6 常见规范
  • 大学计算机基础填空题
  • 低代码开发平台是什么意思?低代码开发平台优势!
  • CSAPP - Bomb Lab
  • Docker 常见操作及部署springboot、Shiro、SpringData脚手架(下)
  • 【前端学习】D3:CSS进阶
  • 中移杭研面试经历
  • [CV学习笔记] yolotensorrt多线程推理-第一部分
  • element ui 的滚动条,Element UI 文档中没有被提到的滚动条
  • 项目四:使用路由交换机构建园区网-任务三:配置路由交换机并进行通信测试
  • 数据仓库面试题汇总