C++ 实现按键精灵
最近玩游戏需要用到按键精灵,Google 结果一堆不安全链接,担心有风险,索性就自己找资料写。
本文主要介绍两个函数 keybd_event 和 SendMessage ;两者都可以实现按键功能,SendMessage 的优势是支持后台。
1.keybd_event 实现
参考 https://blog.csdn.net/yizhou2010/article/details/6178115
参考 https://zhidao.baidu.com/question/579000692.html
参考 https://blog.csdn.net/lhrsdl/article/details/52579286
1.1 函数说明
keybd_event 是 windows 提供的模拟键盘 API 函数,使用该函数可以触发相应的键盘动作。
Keybd_event()函数能触发一个按键事件,也就是说会产生一个 WM_KEYDOWN 或 WM_KEYUP 消息。
函数原型如下:
void keybd_event(
BYTE bVk, // virtual-key code
BYTE bScan, // hardware scan code
DWORD dwFlags, // flags specifying various function options
DWORD dwExtraInfo // additional data associated with keystroke
);
-参数 1 为按键的虚拟键值,如回车键为vk_return, tab键为vk_tab(其他具体的参见附录:常用模拟键的键值对照表);
-参数 2 为扫描码,一般不用设置,用0代替就行;
-参数 3 为选项标志,如果为keydown则置0即可,如果为keyup则设成"KEYEVENTF_KEYUP";
-参数 4 一般也是置0即可。
1.2 关于扫描码的补充说明
如果扫描码设置为 0 ,那么 keybd_event 在游戏中是失效的。
keybd_event 的本质是传递一个与 OEM 相关的硬件扫描码给系统,系统再将扫描码转换成虚拟键码,并模拟按键信号。关键就在 虚拟键码 上,它只是向操作系统发送按键码而已,实际硬件上并没有这个信号。
因此,游戏程序只需要判断这个按键信号是否来自于硬件,就能屏蔽我们的虚拟按键。解决方法也很简单,将扫描码由 0 替换为按键对应的扫描码即可。
虚拟键值表和扫描码表,搜索下很容易找到,这里放一张常用键值对照表。
1.3 示例代码
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
cout << "请把光标移动到输入框" << endl;
Sleep(2000);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);//模拟单击鼠标左键
for (;;)
{
//字母 A 按下
keybd_event(65, 0x1E, 0, 0);
keybd_event(65, 0x1E, KEYEVENTF_KEYUP, 0);
Sleep(100);
//字母 S 按下
keybd_event(83, 0x1F, 0, 0);
keybd_event(83, 0x1F, KEYEVENTF_KEYUP, 0);
Sleep(100);
//system("cls");//清屏
}
return 0;
}
如果不能正常运行,可以试试以管理员身份运行。
2.SendMessage 实现
参考 https://www.cnblogs.com/wind-net/archive/2012/11/01/2750123.html
参考 https://blog.csdn.net/u011296732/article/details/51668937
参考 https://blog.csdn.net/u014038534/article/details/47298665
2.1 函数说明
Windows是一个消息驱动式系统,SendMessage 是应用程序和应用程序之间进行消息传递的主要手段之一。
LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
参数1:hWnd-窗口句柄。窗口可以是任何类型的屏幕对象。
参数2:Msg-用于区别其他消息的常量值.
参数3:wParam-通常是一个与消息有关的常量值,也可能是窗口或控件的句柄.
参数4:lParam-通常是一个指向内存中数据的指针。
通过改变 Msg 可以实现不同的功能,比如创建窗口、移动窗口、改变窗口大小等等……
这里只展示操作按键的代码。
2.2 示例代码
#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include<iostream>
using namespace std;
int main()
{
LPCWSTR lpszCreate = TEXT("QQ三国1.0Beta78Build41 一代枭雄 1线");
HWND hq = FindWindow(NULL, lpszCreate); //寻找句柄
if (hq == NULL)
{
printf("Find windod fail !\n");
}
for (;;)
{
printf("程序执行中……\n");
SendMessage(hq, WM_KEYDOWN, 'A', 0);
Sleep(100);
SendMessage(hq, WM_KEYDOWN, 'S', 0);
Sleep(100);
SendMessage(hq, WM_KEYDOWN, 'D', 0);
}
return 0;
}
2.3查找句柄
SendMessage 在使用之前需要先获取窗口的句柄,这里介绍一下使用 visual stduio 的 spy 工具先来获取窗口标题,在寻找句柄的方法。
打开 visual stduio -> 工具 -> spy++ -> 搜索-> 查找窗口。
拖动红框内的标志到你要操作的窗口的标题栏上,spy 工具便能自动获取标题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2017-11-24 windows服务和进程的区别和联系
2017-11-24 Daemon Process
2017-11-24 C++11中的原子操作(atomic operation)
2013-11-24 MFC消息顺序