C++捕获键盘特定键,即使在游戏中也是如此
C++ Capturing Keyboard Specific Keys even when in a game
我编写了一个程序来更新流媒体时的k/d比率,我希望它易于使用,基本上可以按"shift+1"来增加我的击杀等。。现在,当我在谷歌chrome和其他一些应用程序中时,它可以工作,但当我在游戏中,在这种情况下是Arma,当我按下这些键时,它根本无法工作,我必须alt+tab,然后按下键,它就会工作。有没有办法让程序的关键捕获优先级是绝对的,也就是说比阿玛更重要,即使我在游戏中也会被捕获?
感谢
代码:
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, const char * argv[]) {
RegisterHotKey(NULL, 1, MOD_SHIFT, 0x31); // shift + 1
RegisterHotKey(NULL, 2, MOD_SHIFT, 0x32);// shift + 2
RegisterHotKey(NULL, 3, MOD_SHIFT, 0x33);// shift + 3
RegisterHotKey(NULL, 4, MOD_SHIFT, 0x30);// shift + 0
//shift + 1 = kill
//shift + 2 = death
//shift + 3 = reset
//shift + 0 = close;
int exit = 0;
int kill = 0;
int death = 0;
cout << "K: " << kill << endl;
cout << "D: " << death;
do
{
int showKill = kill;
int showDeath = death;
do
{
MSG msg = {0};
if (GetMessageA(&msg, NULL, 0, 0) != 0)
if(msg.message == WM_HOTKEY)
{
if(msg.wParam == 1)
kill++;
else if(msg.wParam == 2)
death++;
else if(msg.wParam == 3)
{
kill = 0;
death = 0;
}
else
{
exit++;
break;
}
}
}
while(kill == showKill && death == showDeath);
system("CLS");//clear the console
cout << "K: " << kill << endl;
cout << "D: " << death;
}
while(exit == 0);
UnregisterHotKey(NULL, 1);
UnregisterHotKey(NULL, 2);
UnregisterHotKey(NULL, 3);
UnregisterHotKey(NULL, 4);
return 0;
}
根据我的想法,假设你在Windows上玩游戏,有两种非常简单的方法可以解决这个问题:
- 您编写一个钩子,并在运行时将其注入game.exe
- 您可以使用SetWindowsHookEx并捕获键盘低级输入事件
第一种方法要求你编写一个dll模块,这样你就可以使用大部分已经编写的代码,它应该是这样的:
#include <windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI KeyThread(LPVOID)
{
RegisterHotKey(NULL, 1, MOD_SHIFT, 0x31); // shift + 1
RegisterHotKey(NULL, 2, MOD_SHIFT, 0x32);// shift + 2
RegisterHotKey(NULL, 3, MOD_SHIFT, 0x33);// shift + 3
RegisterHotKey(NULL, 4, MOD_SHIFT, 0x30);// shift + 0
//shift + 1 = kill
//shift + 2 = death
//shift + 3 = reset
//shift + 0 = close;
int exit = 0;
int kill = 0;
int death = 0;
// There's no console here so cout won't work, you'll need to use MessageBox or make a file log somewhere
cout << "K: " << kill << endl;
cout << "D: " << death;
do
{
int showKill = kill;
int showDeath = death;
do
{
MSG msg = {0};
if (GetMessageA(&msg, NULL, 0, 0) != 0)
if(msg.message == WM_HOTKEY)
{
if(msg.wParam == 1)
kill++;
else if(msg.wParam == 2)
death++;
else if(msg.wParam == 3)
{
kill = 0;
death = 0;
}
else
{
exit++;
break;
}
}
}
while(kill == showKill && death == showDeath);
system("CLS");//clear the console
cout << "K: " << kill << endl;
cout << "D: " << death;
}while(exit == 0);
UnregisterHotKey(NULL, 1);
UnregisterHotKey(NULL, 2);
UnregisterHotKey(NULL, 3);
UnregisterHotKey(NULL, 4);
}
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
CreateThread(NULL, NULL, KeyThread, NULL, NULL, NULL);
}
return TRUE;
}
编译dll后,您需要将其注入游戏进程,我建议使用Winject或Extreme Injector。如果你是个冒险家,你可以自己去写一本。我必须注意的是,如果你的游戏是基于多人游戏的,并且它使用了Antiheat,那么如果Antiheat使用白名单系统而不是黑名单系统来扫描游戏模块,你可能会引发某种攻击。
第二种方法是制作普通的可执行文件和SetWindowsHookEx来监视低级键盘事件。我自己很久以前就写过这篇文章,但由于我找不到它,我将简单地为您提供一个使用这种方法的键盘记录程序的例子,进行一些轻微的修改,它应该可以完美地工作,我已经自由地为您布局了一个基本的东西:
#include <windows.h>
#include <stdio.h>
HHOOK hKeyboardHook = NULL;
LRESULT WINAPI LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if ((nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)))
{
KBDLLHOOKSTRUCT hooked_key = *((KBDLLHOOKSTRUCT*)lParam);
DWORD dwMsg = 1;
dwMsg += hooked_key.scanCode << 16;
dwMsg += hooked_key.flags << 24;
char lpszKeyName[1024] = { 0 };
lpszKeyName[0] = '[';
int i = GetKeyNameText(dwMsg, (lpszKeyName + 1), 0xFF) + 1;
int key = hooked_key.vkCode;
lpszKeyName[i] = ']';
if (key >= 'A' && key <= 'Z')
{
if (GetAsyncKeyState(VK_SHIFT) >= 0)
{
key += 0x20;
}
printf("%c n", key);
}
else
{
printf("%s n", lpszKeyName);
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
int main()
{
MSG message;
HINSTANCE hins;
hins = GetModuleHandle(NULL);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)LowLevelKeyboardProc, hins, 0);
// Message pump
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWindowsHookEx(hKeyboardHook);
return 0;
}
第二种方法可能会被一些反病毒检测为恶意软件,但它将能够在不进行任何调整的情况下将内容打印到控制台中,并且对初学者来说不那么复杂和简单。
我必须提到的是,代码示例没有经过测试,所以可能存在一些语法错误,但逻辑本身应该是正确的。
对于特定于Windows的应用程序,应该很容易使用:
GetAsyncKeyState()
阅读文档,因为它给出了键的状态,当键向下/向上时,特定的位是开/关的。
- 物理键盘上的触发器按键
- 如何使用C/C++在MacOSX中获得键盘布局
- 在C++游戏中与库存系统作斗争
- 换位表导致测试失败(但在游戏中运行良好)
- Craps游戏问题,忽略if语句
- 矢量下标超出SFML游戏中的范围
- 我是 c++ 的新手.学习基本知识后,我想做井字游戏.对于印刷板,我在下面写代码,但它显示错误
- 视窗键盘输入 c++
- 我在贪吃蛇游戏中收到了错误代码 -1073741571
- 我应该在简单的策略游戏中为各个派系使用类吗 - C++
- 游戏体验和升级
- 我的代码运行良好,但在游戏循环中中断
- 如何使用 SFML 在贪吃蛇游戏中定义游戏结束?
- 我可以使用任何好的逻辑来阻止计算机将 O 放在井字游戏中的现有 X 上
- 将鼠标和键盘输入发送到 unity3d 游戏 (Rust)
- C ++异步键盘输入(标准方式)
- 在猜谜游戏 c++ 中不计算尝试次数
- 如何将键盘和鼠标输入发送到不是Windows7上活动窗口的游戏
- C++捕获键盘特定键,即使在游戏中也是如此
- 游戏键盘输入和事件