1

I want to check when a key is released, but I can't do so without having an infinite cycle, and this puts the rest of the code on pause. How can I detect if a key is released while running the rest of my program without an infinite cycle? This is the code I found and that I have been using:

#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;
}
Kos
  • 70,399
  • 25
  • 169
  • 233
Puértolas Luis
  • 235
  • 1
  • 2
  • 13

2 Answers2

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

This is a more refined version that I used in my CLI game which I adopted from Davids answer just now (thank you David, I was racking my brain trying to figure this out myself). The top executes when shift is pressed, the bottom is executed when shift is released.

EDIT: The bool "shift" has to be initialized to false before hand for this to work.

Ytivarg
  • 51
  • 1
  • 3
3

First of all, the way you test the return value of GetAsyncKeyState() is incorrect. Test for the return value being negative to detect whether or not the key is down. So your if should read:

if (GetAsyncKeyState(VK_ESCAPE) < 0)

If you wish for that code to execute without blocking your main thread, then you'd need to put the busy loop into a separate thread. That's probably still a poor idea because you are running a busy loop.

In a GUI process you would have a window message loop that would be able to receive WM_KEYDOWN messages. But you have a console application. In that case you might be best using PeekConsoleInput which you would call periodically to check whether or not there is an escape key press waiting in the input buffer. An example of how to do that can be found here: Intercept ESC without removing other key presses from buffer.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490