【发布时间】:2018-05-31 15:59:50
【问题描述】:
根据microsoft's documentation,据说GetAsyncKeyState()
确定调用函数时按键是向上还是向下
我一直在构建一个 UI 自动化库,问题归结为这个
#include <Windows.h>
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
bool IsKeydownAsync(int key) {
return GetAsyncKeyState(key) & 0x8000;
}
int main(){
while (1) {
if (IsKeydownAsync('A')) {
cout << "triggered" << endl;
}
this_thread::sleep_for(chrono::milliseconds(10));
}
}
所以我的理解是,我的应用程序是否处于焦点并不重要,GetAsyncKeyState() 应该始终返回物理键在被调用时是向上还是向下。
我已经在各种应用程序上对此进行了测试,并且在大多数情况下,它的行为与描述的一样。但是,在某些游戏中,这种行为会中断,并且不再报告键是向上还是向下。按住键时不会调用cout << "triggered" << endl。
有什么我忽略的吗?
【问题讨论】:
-
请注意文档的返回值和备注部分。
GetAsyncKeyState可能不是输入处理或 UI 自动化的最佳选择。你应该使用别的东西。 -
@VTT 返回值和备注部分仅提到 LSB 不可靠,但我仅测试 MSB 以查看密钥是否已关闭。我正在考虑使用 RAWINPUT,但这将是我最后的手段,因为我对它不太熟悉
-
@ShawnLi 您能否明确提及破坏行为的游戏?我是否理解正确:您在记事本中按 A 键,然后您的程序显示“已触发”,但如果您在您提到的某个游戏中按 A 键,则不再显示“已触发”?
-
众所周知,游戏使用原始输入来读取键盘,在通过正常管道处理之前截取击键。这是一种非常便宜的反作弊方法,只能通过修补驱动程序来破解。