天天看点

GetKeyState和GetAsyncKeyState到底有什么区别?

经常有朋友问起,GetKeyState和GetAsyncKeyState到底有什么区别,分别应该在什么场景下使用。

那么,今天我就来翻译翻译,什么叫惊喜。

GetKeyState会返回虚拟按键的状态。换句话说,GetKeyState会基于你从输入队列中检索到的消息来报告键盘按键的状态。这个状态是虚拟的,也就是说,它和键盘的物理状态是不一样的。

> 如果用户在你调用PeekMessage或者GetMessage之前就进行了键盘输入,则GetKeyState不会报告任何键盘输入的变化。

> 如果用户切换到了其他程序,那么GetKeyState不会返回用户在那个程序中的任何输入,因为操作系统并没有将其他程序的键盘输入发送至你的程序的输入队列之中。

而GetAsyncKeyState返回的是按键的物理状态,它是直接获取硬件中断的状态。

那么,什么时候应该使用GetKeyState,什么时候又应该使用GetAsyncKeyState呢? 好问题!

从用户体验的角度出发,你应该几乎总是使用GetKeyState。为何?

如果你正在处理某一条输入消息并想知道在生成此消息时,用户都按下了哪些键,那么你就需要使用 GetKeyState。例如,如果要区分鼠标左键单击和 Alt + 鼠标左键单击,则必须使用 GetKeyState 来查询 ALT 键的状态(基于历史的原因,我们称之为 VK_MENU)。那是因为你想知道当用户单击鼠标时 ALT 键是否按下,而不是此时键是否按下。用户是否在单击和处理消息之间释放 ALT 键无关紧要。你所关心的只是 ALT 键在单击时是否按下了。

请注意,如果你要实现上下文菜单处理程序,则你不应使用 GetKeyState 或 GetAsyncKeyState,因为无需任何用户操作即可以编程方式调用上下文菜单。对于

IContextMenu::QueryContextMenu,你应该测试 CMF_EXTENDEDVERBS 标志以检测是否应该显示扩展命令而不是直接查询键盘按键的装填。类似地,对于 IContextMenu::InvokeCommand,如果你想根据转换状态改变程序的行为,那么应该测试 CMIC_MASK_CONTROL_DOWN 和CMIC_MASK_SHIFT_DOWN 标志位是否存在。

总结

在拓扑梅尔智慧办公平台(Topomel Box)的开发过程中,我也使用到了GetKeyState,感觉良好。

最后