【发布时间】:2013-08-28 23:20:41
【问题描述】:
我有一个需要检查计时器上的键状态的 C++ (MFC) 应用程序。如果用户按住某个键,我们会延迟一些代码的处理。
这是keydown的检查:
if (!GetKeyboardState(keyState))
{
s_executeDeferredResult = e_executeDeferredButtonCheckFailed;
return;
}
s_executeDeferredStuckKeys.clear();
for (int index=0; index<arrsize(keyState); ++index)
{
if (keyState[index] & 0x80)
{
s_executeDeferredStuckKeys.insert(index);
}
}
if (!s_executeDeferredStuckKeys.empty())
{
s_executeDeferredResult = e_executeDeferredButtonsActive;
return;
}
但是,有一些关键组合卡住了:
- 打开 NUMLOCK
- 按 SHIFT
- 按 NumPad8
- 释放 SHIFT
- 发布 NumPad8
(这是一个例子,还有其他例子,包括一个带有 CTRL-ALT-DEL 的笨蛋)
GetKeyboardState 现在将报告VK_UP 被按下。
发生的事件是(对应于上面的动作)。
<None>-
WM_KEYDOWN,VK_SHIFT -
WM_KEYUP,VK_SHIFTWM_KEYDOWN,VK_UPWM_KEYDOWN,VK_SHIFT -
WM_KEYUP,VK_SHIFT -
WM_KEYUP,VK_NUMPAD8
因此,Windows 无法识别出现了向上键,现在 GetKeyboardState 已损坏。
有什么好的方法可以检查密钥的真实状态吗? GetAsyncKeyState 和 GetKeyState 都报告密钥也已关闭。
【问题讨论】:
-
您是否尝试过使用其他键盘?
-
是的,它发生在我们尝试过的所有键盘上。
-
由于这是一个 MFC 应用程序,请务必检查您的
PreTranslateMessage实现。这就是随着时间的推移,各种坏事会累积的地方。另请注意GetKeyboardState文档中的注释:“状态会随着线程从其消息队列中删除键盘消息而发生变化。” 换句话说:如果您的应用程序做了一些可疑的事情,那么@987654344 很可能@ 感到困惑。 -
事实证明,这种行为在一个小型独立测试应用程序中是可重现的。好主意。
标签: c++ windows mfc keyboard-events