检测钥匙何时被释放

时间:2014-09-22 12:28:47

标签: c++ winapi

我想检查一个密钥何时被释放,但是如果没有无限循环就不能这样做,这会使其余的代码暂停。如何在没有无限循环的情况下运行程序的其余部分时检测是否释放了某个键?这是我找到的代码,我一直在使用:

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    int counter=0;
    ofstream myfile;
    short prev_escape = 0, curr_escape = 0;
    myfile.open("c:\\example.txt");
    while(true)
    {
        if(GetAsyncKeyState(VK_ESCAPE))
            curr_escape = 1;
        else
            curr_escape = 0;
        if(prev_escape != curr_escape)
        {
            counter++;
            if(curr_escape)
            {
                myfile <<"Escape pressed : " << counter << endl;
                cout<<"Escape pressed !" << endl;
            }
            else
            {
                myfile <<"Escape released : " << counter << endl;
                cout<<"Escape released !" << endl;
            }
            prev_escape = curr_escape;
        }        
    }
    myfile.close();
    return 0;
}

2 个答案:

答案 0 :(得分:2)

首先,测试GetAsyncKeyState()的返回值的方式不正确。测试返回值是否为负以检测密钥是否已关闭。因此,您的if应为:

if (GetAsyncKeyState(VK_ESCAPE) < 0)

如果您希望在不阻塞主线程的情况下执行该代码,那么您需要将busy循环放入单独的线程中。这可能仍然是一个糟糕的主意,因为你正在运行一个繁忙的循环。

在GUI过程中,您将拥有一个能够接收WM_KEYDOWN条消息的窗口消息循环。但是你有一个控制台应用程序。在这种情况下,您最好使用PeekConsoleInput,您可以定期调用它来检查输入缓冲区中是否有退出键等待。可以在此处找到如何执行此操作的示例:Intercept ESC without removing other key presses from buffer

答案 1 :(得分:1)

if (GetAsyncKeyState(VK_SHIFT) < 0 && shift == false)
    {
        shift = true;
    }
    if (GetAsyncKeyState(VK_SHIFT) == 0 && shift == true)
    {
        shift = false;
    }

这是我在CLI游戏中使用的更精致的版本,我刚刚从Davids的答案中采用了该版本(感谢David,我正在绞尽脑汁想自己弄清楚这一点)。按下Shift键时顶部执行,释放Shift键时底部执行。

编辑:必须先将布尔值“ shift”初始化为false才能起作用。