当应用程序失焦时,GetKeyState修改了WINAPI GetKeyboardState行为?

时间:2017-08-16 16:46:37

标签: winapi keyboard focus hook keyboard-events

从WPF应用程序(以及假设其他应用程序)调用WINAPI命令GetKeyboardState(aByteArray)时,只有在应用程序具有焦点时才能正确检测到SHIFT键。当应用程序没有焦点时,方法调用后aByteArray[VK_SHIFT]0

但是,如果在GetKeyState(aVKCode)之前调用GetKeyboardState(aByteArray), aVKCode的任何值,即使返回值被丢弃,那么GetKeyboardState(aByteArray)也会提供正确的值 - 当应用程序未处于焦点时,保留SHIFT键的状态。

这种行为违反直觉,似乎已经引起许多程序员的悲痛。我相信GetKeyboardState的文档中有相关信息,其中包含:

  

当线程从其消息队列中删除键盘消息时,状态会发生变化。当键盘消息被发布到线程的消息队列时,状态不会改变,当键盘消息被发布到其他线程的消息队列或从其他线程的消息队列中检索时,状态也不会改变。

潜在地,GetKeyState()与消息队列交互的方式必须在GetKeyboardState()之前调用,以使GetKeyboardState()按照需要行事。但是,我不熟悉消息队列的概念以及Windows如何添加和删除项目,所以我想我在这里问。任何人都可以解释为什么单独调用GetKeyboardState()无法捕获没有应用程序焦点的SHIFT密钥?

1 个答案:

答案 0 :(得分:1)

GetKeyState始终与线程的最后处理消息相关联。因此,当您在消息处理程序中使用GetKeyState时,可以在将此消息放入消息队列时获取keystate。

如果消息处理延迟,这可以保证程序员可以处理每条消息,并且可以检测当时的关键状态。 I.E。:“当鼠标点击发生时,Shift键是否按下?”

如果在其间处理其他消息,只使用GetKeyState可能会跳过状态或消息。

要检测当前键状态,您必须使用GetAsyncKeyState

这些功能都有详细记录。

最后:GetKeyState和GetAsyncKeyState都不是检测程序中是否按下shift键的好方法。处理消息并检测WM_KEYDOWN。