IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 模拟键鼠详细总结 -> 正文阅读

[C++知识库]C++ 模拟键鼠详细总结

简介

下面这些操作,一定要看官方文档,这样能少走很多弯路。

键鼠状态查询

虚拟键码

// 获取鼠标位置
POINT p;
GetCursorPos(&p);
qDebug() << "cur mouse:" << p.x << "," << p.y;
// 判断鼠标左键是否被按下
if((GetAsyncKeyState(VK_LBUTTON)& 0x8000)? 1:0){
    qDebug()<<"lbutton down";
}
// 判断 K 是否被按下
if((GetAsyncKeyState(0x4B)& 0x8000)? 1:0){
    qDebug()<<"k down";
}

GetKeyState和GetAsyncKeyState的区别

GetAsyncKeyState就是检查在调用该函数时,某一key的状态。而GetKeyState是检查window message发生时,某一key的状态。

如果在MSG产生的时候,Ctrl是没有按下的;而在调用GetAsyncKeyState的那一刻,Ctrl是按下的。那么GetAsyncKeyState会通知你Ctrl是按下的。反之通知你Ctrl是没有按下的。
如果在MSG产生的时候,Ctrl是按下的,那么GetKeyState会通知你Ctrl是按下的。反之通知你Ctrl是没有按下的。与调用GetKeyState那一刻Ctrl的状态是没有关系的。

虚拟键码与扫描码

MapVirtualKeyW,该函数可用于虚拟键码和扫描码之间的转换

// 返回结果为翻译结果
UINT WINAPI MapVirtualKeyW(   
  _In_  UINT uCode,    // 扫描码或虚拟键码
  // 0: 虚拟键码->扫描码
  // 1: 扫描码->虚拟键码
  _In_  UINT uMapType
);

扫描码:键盘硬件对应的按键的编码;虚拟键码:操作系统对应的按键的编码;
当用户按下某个按键时:
1)键盘会检测到这个动作,并通过键盘控制器把扫描码(scan code) 传送到计算机; 键盘扫描码跟具体的硬件有关的,不同厂商对同一个键的扫描码有可能不同。  
2)计算机接收到 扫描码 后,将其交给键盘驱动程序;
3)键盘驱动程序 把这个 扫描码转换为键盘虚拟码;虚拟码与具体硬件无关,不同厂商的键盘,同一个键的虚拟码总是相同的。
4)然后,键盘驱动程序 把该键盘操作的 扫描码和虚拟码以及其它信息传递给 操作系统;操作系统将获得 的信息封装在一个键盘消息中,并把该键盘消息插入到消息列队。
5)通过Windows的消息系统,该键盘消息被送到某个窗口中;
6)窗口所在的应用程序接收到消息后,可以了解到有关 键盘操作的信息,然后决定作出一定的响应。

控制键鼠

  • 官网已不建议使用 mouse_event函数 了,但是,mouse_event 使用起来比 SendInput 方便,且不会被360限制(我测试的时候,发现SendInput 会被360杀毒拦截。。。)
  • 官网建议使用 SendInput 函数,它集成了键鼠的所有操作

我使用SendInput没成功,所以大家如果想用它的话,请参考官方文档。我这里介绍 mouse_event 和 keybd_event 两个函数来实现相应的操作

mouse_event

官方文档

void mouse_event(
  [in] DWORD     dwFlags, // 操作类型
  [in] DWORD     dx, // 相对或绝对的移动量
  [in] DWORD     dy, // 相对或绝对的移动量
  [in] DWORD     dwData, // 如果有滚轮事件则代表滚轮的变化量,可正负,一圈为120(WHEEL_DELTA),如果没有滚轮事件,该值应当设为0
  [in] ULONG_PTR dwExtraInfo // 给0就行
);

可用的操作类型参考官方文档,里面写的很详细,这里提供简单的案例。

// 模拟鼠标左键
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
Sleep(50);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);

keybd_event

官方文档
虚拟键码

这里只提供简单的案例,具体的事件课填什么请参考官方文档

void keybd_event(
  [in] BYTE      bVk, // 虚拟键码
  [in] BYTE      bScan, // 一般设置为0即可,可以用 MapVirtualKeyW(虚拟键码值,0)得到
  [in] DWORD     dwFlags, // 具体的事件,0代表按下,KEYEVENTF_KEYUP代表松开
  [in] ULONG_PTR dwExtraInfo // 一般设置为0即可
);

// 模拟按键K
keybd_event(0x4B,MapVirtualKeyW(0x4B,0),0,0); // 按下
Sleep(50);
keybd_event(0x4B,MapVirtualKeyW(0x4B,0),KEYEVENTF_KEYUP,0); // 抬起

后记

写这篇文章的时候,我已经走了很多弯路,所以为让大家少走弯路,我把这些经验总结了一下,有许多内容是来自官方文档或者别的博客,由于看的内容比较碎,我也忘了是来源于哪个博客了,感谢各位博主的探索。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 10:59:30  更:2022-05-05 11:00:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 0:56:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码