GetAsyncKeyState 使用 cin 创建问题

Posted

技术标签:

【中文标题】GetAsyncKeyState 使用 cin 创建问题【英文标题】:GetAsyncKeyState creating problems with cin 【发布时间】:2011-12-11 23:58:57 【问题描述】:

我目前正在为学校创建一个控制台游戏,但在我的主菜单中使用 GetAsyncKeyState 时遇到了问题。我的主菜单在无限循环中运行,只有在按下一个键时才会中断。例如我有:

if(GetAsyncKeyState('1'))
   
    Play();
    break;

仅此一项,就可以正常工作。问题是,在我的 Play() 方法中,我有一个 cin 语句,并且 Menu() 中的“1”进入了我的 Play()。我试过 cin.clear() 无济于事,而 cin.ignore(...) 阻止了从 Menu() 到 Play() 的瞬时变化。有什么办法可以防止这种情况发生吗?

【问题讨论】:

用户的肘部放在“1”键上。当您要求输入时,您希望显示什么?想一想,你不能两全其美。 请注意,您正在错误地检查 GetAsyncKeyState 的返回值。但这里的问题是,您的程序在用户放开“1”键之前就已经向前推进了。您可能应该等到按键被释放后再退出菜单。 GetAsyncKeyState 读取键盘状态,即使您的应用程序没有焦点。您可能希望使用 GetNumberOfConsoleInputEventsReadConsoleInput(或旧的 conio.h 接口)来只读控制台输入。 【参考方案1】:

在致电Play()之前试试这个

FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));

此外,当您使用 GetAsyncKeyState 时,您应该屏蔽除高位以外的所有内容,如下所示:

if ((GetAsyncKeyState('1') & 0x8000) != 0)

请参阅“返回值”下的文档以了解原因:http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293%28v=vs.85%29.aspx

【讨论】:

这对GetAsyncKeyState没有影响。 @RaymondChen:当我尝试以下代码时:ideone.com/fAMby 当循环完成时,我按下的所有键的字符都会溢出到标准输入,包括 1。但有以下修改: ideone.com/lJyKY 循环后控制台为空。那么,你在说什么? @RaymondChen:同时,应用您的建议:ideone.com/NtetV 准确吗?这似乎根本没有帮助。 谢谢本杰明!将您的 FlushConsoleInputBuffer 想法与仅检查 GetAsyncKeyState 的高位一起使用。单独要么只工作了一半的时间,他们似乎每次都在工作。我很想知道为什么会这样,但在这一点上,我很高兴问题得到解决。再次感谢! @smearedblackink:哦,是的,我应该提到只检查高位的部分。闪退了,我会把它添加到我的答案中。

以上是关于GetAsyncKeyState 使用 cin 创建问题的主要内容,如果未能解决你的问题,请参考以下文章

杂文虚拟键码表(供函数GetAsyncKeyState()使用)

为啥在 Win32 中使用 `GetAsyncKeyState()` 时我的热键会出错?

使用 GetAsyncKeyState() 识别按下的热键仅在 [重复]

将 GetAsyncKeyState() 重置为默认值

C#GetAsyncKeyState 不起作用

GetAsyncKeyState(int vKey)中的点逗号减号