【问题标题】:Detecting when a key is released检测何时释放键
【发布时间】:2019-02-14 09:51:16
【问题描述】:

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

#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;
}

【问题讨论】:

  • “同时运行我的程序的其余部分”?首先,确定您想要检查按键的具体时间。
  • JustJeff,谢谢,我会调查的。科斯,我需要随时检查。
  • 你应该有一个窗口来接收像WM_KEYUP这样的消息。
  • 您是否需要全局检测(无论活动应用程序是什么),还是应该仅在您的应用程序处于活动状态时才有效?

标签: c++ winapi


【解决方案1】:
if (GetAsyncKeyState(VK_SHIFT) < 0 && shift == false)
    {
        shift = true;
    }
    if (GetAsyncKeyState(VK_SHIFT) == 0 && shift == true)
    {
        shift = false;
    }

这是我在 CLI 游戏中使用的更精致的版本,我从 Davids 刚才的回答中采用了它(谢谢 David,我正在绞尽脑汁试图自己解决这个问题)。按下 shift 时执行 top,释放 shift 时执行 bottom。

编辑: bool "shift" 必须事先初始化为 false 才能正常工作。

【讨论】:

    【解决方案2】:

    首先,你测试GetAsyncKeyState()返回值的方式不对。测试返回值是否为负以检测键是否已关闭。所以你的if 应该是:

    if (GetAsyncKeyState(VK_ESCAPE) < 0)
    

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

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

    【讨论】:

    • 谢谢,我不知道怎么解释,但问题解决了!
    • 它对我不起作用,如果我继续持有这把钥匙,它也是有效的。
    • @HaSeeBMiR 什么不起作用?我认为您没有仔细阅读答案。
    • @DavidHeffernan 你必须像这样检查 keystate 是否为零。if (GetAsyncKeyState(VK_ESCAPE) == 0)
    • @HaSee 你到底在说什么?
    猜你喜欢
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 2014-05-31
    相关资源
    最近更新 更多