【发布时间】:2014-02-27 02:24:25
【问题描述】:
我编写了一个使用 GetAsyncKeyState() 的小程序,它自己运行良好。
问题是当我运行某个外部应用程序(不是我的)时,我的 GetAsyncKeyState() 完全停止接收输入。我希望能够同时运行这两个应用程序。
我可以做些什么来强制我的程序再次接收键盘输入吗?什么可能导致这个问题?
谢谢!
**更多详情**
我正在使用 MFC 并处理导致捕获键盘输入的 WM_TIMER 消息。我使输入可配置,然后调用
if(GetAsyncKeyState(chVirtualKey) < 0) { //stuff happens }
**更新** 我用我对它们的有限知识制作了另一个测试应用程序(非 MFC)设置了一个钩子:
SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, hInstance, NULL);
然后处理它:
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*) lParam;
if (p->vkCode == VK_SPACE) // spacebar key
{
SetCursorPos(400, 400); //just to test
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
此钩子有效,但仅在其他应用程序未运行时才有效,因此我仍然卡住...
【问题讨论】:
-
停止接收输入是什么意思?
GetAsyncKeyState本身不会“接收输入”。你什么时候打电话?你在投票吗?打电话来回复消息?显示一些源代码... -
Get(Async)KeyState()依赖于在调用线程中本地缓存的键盘数据。外部进程可以干扰的唯一方法是,如果它使用BlockInput(),或者使用钩子在键盘消息到达线程的消息队列之前拦截和丢弃/修改它们。 -
我可以建议一个实验:创建一个简单的基于对话框的应用程序,处理
WM_TIMER和GetAsyncKeyState并查看当其他应用程序运行时是否也“损坏”。这将告诉您这完全是其他应用的错,还是您的应用也以某种方式做出了贡献。 -
除了自己钩住键盘(看
SetWindowsHookEx()或RegisterRawInputDevices()),或者提示用户不要运行其他应用程序之外,您可能无能为力。也许联系其他应用的所有者并抱怨它干扰了您的应用。 -
@Soran:
SetWindowsHookEx()-WH_KEYBOARD和WH_KEYBOARD_LL只有两个键盘挂钩可用。试试他们两个。但是原始输入会更好,因为数据直接来自键盘而不是一组系统队列。不过不知道是不是受到BlockInput()的影响。