GetKeyState()与GetAsyncKeyState()与getch()的区别?

30

使用以下方法获得按键事件的差异是什么?

  • GetKeyState()
  • GetAsyncKeyState()
  • getch()

我应该在何时使用它们?


5
为什么会被踩?我在Stackoverflow上找不到任何结果,即使忽略getch()并搜索GetKeyState() vs. GetAsyncKeyState()也是如此。 - Markus Meskanen
2个回答

27

GetKeyState()和GetAsyncKeyState()是Windows特定的API,而getch()适用于其他非Windows特定的C编译器。

GetKeyState()从线程的消息队列中返回键盘状态。该状态不反映与硬件相关联的中断级状态。

GetAsyncKeyState()指定了自上次调用GetAsyncKeyState()以来按下键和键当前是向上还是向下的状态。如果最高位被设置,则该键是按下状态,如果最低位被设置,则该键在上一次调用GetAsyncKeyState()之后被按下。

在实践中,我发现如果你按住一个键并在按下该键时分配一个行为,如果你使用GetKeyState(),那么比起使用GetAsyncKeyState(),这个行为会被调用更多次。

在游戏中,我更喜欢使用GetAsyncKeyState()。

(您也可以在MSDN博客上查看更多详细信息)。


5

先来看一下 async 所表示的意思。

  • GetAsyncKeyState() 异步获取按键状态,也就是说它不需要等待什么,立即返回结果。

  • GetKeyState() 同步获取按键状态,它会返回你即将调用 getch() 读取的那个按键状态,并且该状态已经在键盘缓冲区中等待被处理。

举个例子,假设以下键位被敲击,但还未被读取:

  • h
  • i
  • shift+1
  • ctrl(按住不放)

GetAsyncKeyState() 立即返回 ctrl 按下

GetKeyState() 将返回 H 按下 直到你调用 getch()

然后,GetKeyState() 将返回 I 按下 直到你再次调用 getch()

接着,GetKeyState() 将返回 shift 和 1 按下 直到你调用 getch(),此时它将返回 !(按下 shift+1 所得到的结果)。

最后,GetKeyState() 将返回 ctrl 按下


感谢您的编辑,我从未知道您可以输入关键符号。 - user2624417
这些函数的签名是"SHORT GetAsyncKeyState( [in] int vKey );"。根据API文档:“如果函数成功,返回值指定键是否自上次调用GetAsyncKeyState以来按下,并且该键当前是向上还是向下。如果最高位设置为1,则表示该键按下,如果最低位设置为1,则表示在上一次调用GetAsyncKeyState之后按下了该键。然而,您不应依赖于此行为;有关更多信息,请参阅备注。”因此,这个答案是误导性的,没有像“我按下”这样的返回值。 - Jedzia
请参阅 https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate。 - Jedzia
因为我也有难以清楚表达我的意思的问题: 使用此函数,您可以“请求”是否按下了之前指定的键。这不会返回所按下的键(因此不像也提到的getch()的行为,这可能使答案变得混乱)。这类似于非阻塞方式,例如使用Esc键:“if ((GetAsyncKeyState(VK_ESCAPE) & 0x01)) { ... ” - Jedzia
抱歉,即使是异步/同步的解释也是错误的。没有ASYNC的“SHORT GetKeyState([in] int nVirtKey);”不会阻塞!GetKeyState返回虚拟键状态,即您的输入队列。GetAsyncKeyState直接检测键盘上的硬件中断。请参见:https://devblogs.microsoft.com/oldnewthing/20041130-00/?p=37173和https://topic.alibabacloud.com/a/the-usage-and-difference-of-getkeystate-and-getasynckeystate-and-getkeyboardstate-functions_8_8_31199734.html。 - Jedzia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接