C++: GetKeyState() has to run once

I need to listen keyboard key states for my tiny application.

#include <windows.h>
#include <fstream>
#include <iostream>

using namespace std;

int main()
{
    while(1)
    {
        if(GetKeyState(VK_SPACE) & 0x80)
        {
            cout << "Space pressed.\r\n";
            DoSpaceKeyTask();
        }

        if(GetKeyState(OTHER_KEY) & 0x80)
        {
            cout << "Other key pressed.\r\n";
            DoOtherKeyTask();
        }
    }
    return 0;
}

Once I click some keys from my keyboard, these functions has to run once. They're just some tiny tasks for my applications, which is not related in this topic.

My problem is, when I press a key, it executes the functions few times, due to while(1) looping few times during key press. I cannot use Sleep() in this case, because it still won't be effective.

I'm looking for a solution like this.

  1. I press SPACE key.
  2. DoSpaceKeyTask() executes "once."
  3. I press OTHER key.
  4. DoOtherKeyTask() executes "once."

I have like 5 keys that I will be using. Could anyone help me on this case?

Ps. If GetKeyState() function isn't useful on this task, feel free to suggest yours. My function knowledge is pretty limited on C++.

Your functions are called multiple times because of the duration time the button stays pressed. The system is very sensitive. So this is a workaround.

You could do something like this (set a flag that will assign a value when the key is down, and then reasign it when the key is up).

int k=0;//Flag
while(1){
    //check if the key was pressed (key_down)
    if((GetAsyncKeyState('0') & 0x8000) && (k == 0)){k=1; cout<<"'0' PRESSED."<<k<<endl;}//do your stuff here
    //check if the key was released (key up)
    else if(GetAsyncKeyState('0') == 0) k = 0;//reset the flag
}

C Programming Tutorial for Beginners, Learn C the Hard Way: Practical Exercises on the Computational Subjects You Keep Avoiding (Like C) C (/ s iː /, as in the letter c) is a general-purpose, procedural computer programming language supporting structured programming, lexical variable scope, and recursion, with a static type system. By design, C provides constructs that map efficiently to typical machine instructions.

Try this approach:

#include <windows.h>
#include <fstream>
#include <iostream>

using namespace std;

int main()
{
    char lastSpaceState = 0, lastOtherKeyState = 0, spaceState, otherKeyState;
    while(1)
    {
        spaceState = (GetKeyState(VK_SPACE & 0x80) != 0);
        lastSpaceState = (spaceState && !lastSpaceState);
        if(lastSpaceState)
        {
                cout << "Space pressed.\r\n";
                DoSpaceKeyTask();
        }

        otherKeyState = (GetKeyState(OTHER_KEY) & 0x80 != 0);
        lastOtherKeyState = (otherKeyState && !lastOtherKeyState);
        if(lastOtherKeyState)
        {
                cout << "Other key pressed.\r\n";
                DoOtherKeyTask();
        }

    }

    return 0;
}

or as Chris suggest in OP comment more "modern" async approach.

"C" Programming Language: Brian Kernighan, This course will give you a full introduction into all of the core concepts in the C programming Duration: 3:46:13 Posted: Aug 15, 2018 The digraph ck is often used to represent the sound / k / after short vowels, like "wicket". C is the eleventh least frequently used letter in the English language (after G, Y, P, B, V, K, J, X, Q, and Z ), with a frequency of about 2.20% in words.

I was having the same issue. I have several keys that act like toggle buttons and only want to register the key events once per press. My solution was to make a simple object to handle the logic. This keeps the main code clean:

class KeyToggle {
public:
    KeyToggle(int key):mKey(key),mActive(false){}
    operator bool() {
        if(GetAsyncKeyState(mKey)){
            if (!mActive){
                mActive = true;
                return true;
            }  
        }
        else
            mActive = false;
        return false;
    }
private:
    int mKey;
    bool mActive;
};

And here is the usage:

#include <windows.h>

KeyToggle toggleT(0x54);  // T key toggle
KeyToggle toggleF(0x46);  // F key toggle

void main(void)
{
    while(true){
        if(toggleT) {;} // do something
        if(toggleF) {;} // do something
    }
}

C Tutorial, "C" is one of the most widely used programming languages of all time. Prof Brian Kernighan Duration: 8:26 Posted: Aug 18, 2015 C is a procedural programming language. It was initially developed by Dennis Ritchie as a system programming language to write operating system. The main features of C language include low-level access to memory, simple set of keywords, and clean style, these features make C language suitable for system programming like operating system or compiler development.

I think that you will prefer to execute your functions "once" only when you have released up your keys, not when you have depressed (pressed) them down.

You don't need any additional flags and helper variables to define, allocate, assign to 0, and set each one to 1 and reset to 0 and so on, in order to achieve this goal. All what you need is just: First you have to use GetKeyState function inside the scope of while(1) to check when you have depressed a key. When the expression returns true, the executor pointer (the arrow that carry out a code line and then proceeds forward to the next code line when you either step into or step over) will enter into the if statement's scope. Then immediately trap it inside a loop and keep it trapped in there while the key you have depressed is still down and stop it before it is going to execute the function and free it when you have released that key up and then let it to execute the function.

For example, to execute the DoSpaceKeyTask function only "once" when you have depressed and released the space bar, then do the following code that should work:

while (1)
{
    if (GetKeyState(VK_SPACE) & 0x80)
    {
        //The code here executes ONCE at the moment the space bar was pressed
        cout << "Space pressed.\r\n";
        while (GetKeyState(VK_SPACE) & 0x80) //You can write there ';' instead '{' and '}' below
        {
            //The executor pointer is trapped here while space bar is depressed and it will be free once space bar is released
        }
        //The code here executes ONCE at the moment the space bar was released
        cout << "Space released.\r\n";
        DoSpaceKeyTask();
    }
}

Just the same with DoOtherKeyTask function:

while (1)
{
    if (GetKeyState(OTHER_KEY) & 0x80)
    {
        //The code here executes ONCE at the moment the other key was pressed
        cout << "Other key pressed.\r\n";
        while (GetKeyState(OTHER_KEY) & 0x80) //You can write there ';' instead '{' and '}' below
        {
            //The executor pointer is trapped here while other key is depressed and it will be free once other key is released
        }
        //The code here executes ONCE at the moment the other key was released
        cout << "Other key released.\r\n";
        DoOtherKeyTask();
    }
}

If you have already used either BT_'s idea or Pawel Zubrycki's idea, and now you want to use my idea, then you can delete all flags and variables that they suggested, because you don't need them anymore.

By the way, I have already tried the code that Pawel Zubrycki posted, but it doesn't work for me. The output that says that I have pressed either space bar or other key was not displayed when I have really pressed the space bar or other key that I chose.

Learn C, C programming is a general-purpose, procedural, imperative computer programming language developed in 1972 by Dennis M. Ritchie at the Bell Telephone� This is a list of operators in the C and C++ programming languages.All the operators listed exist in C++; the fourth column "Included in C", states whether an operator is also present in C. Note that C does not support operator overloading.. When not overloaded, for the operators &&, ||, and , (the comma operator), there is a sequence point after the evaluation of the first operand.

I know that this is pretty old thread but I still want to share my solution. I think that creating some kind of "flags" or "switches" is really not needed. Here is my code of looping all keycodes:

    while (true) 
    {
        for (int i = 0x01; i < 0xFE; i++) 
        {
            if (GetKeyState(i) & 0x8000)
            {
                std::cout << (char)i << "\n";
                while (GetKeyState(i) & 0x8000) {}
            }
        }
    }

As you can see, you can easily just use while and the same GetKeyState function to wait for the key unpress. Much simpler solution.

Learn C Programming, learn-c.org is a free interactive C tutorial for people who want to learn C, fast. As well as C and Simula's influences, other languages also influenced this new language, including ALGOL 68, Ada, CLU and ML . Initially, Stroustrup's "C with Classes" added features to the C compiler, Cpre, including classes, derived classes, strong typing, inlining and default arguments.

Cprogramming.com: Learn C and C++ Programming, C is a powerful general-purpose programming language. Our C tutorials will guide you to learn C programming one step at a time with the help of examples. C++ is a middle-level programming language developed by Bjarne Stroustrup starting in 1979 at Bell Labs.C++ runs on a variety of platforms, such as Windows, Mac OS, and the various versions of UNIX. This C++ tutorial adopts a simple and practical approach to describe the concepts of C++ for beginners to advanded software engineers.. Why to Learn C++. C++ is a MUST for students and working

C Programming Language, The best site for C and C++ programming. Popular, beginner-friendly C and C++ tutorials to help you become an expert! Microsoft C++, C, and Assembler documentation. Learn how to use C++, C, and assembly language to develop applications, services, and tools for your platforms and devices.

What is C?, This page contains all topics of C with clear explanations and examples. It also contains job interview questions, MCQ quizzes and output based questions. C# (pronounced see sharp, like the musical note C♯, but written with the number sign) is a general-purpose, multi-paradigm programming language encompassing strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines. It was developed around 2000 by Microsoft as part of its .NET initiative and

Comments
  • 1. You want GetAsyncKeyState for that loop. 2. You have to mask it with 0x8000. Also, you can use while (GetAsyncKeyState(...) & 0x8000) to wait for it to go up.
  • Here's a good blurb on point 1: blogs.msdn.com/b/oldnewthing/archive/2004/11/30/272262.aspx
  • Hi chris, it is still the same with GetAsyncKeyState and 0x8000. Any ideas?
  • You should either use a state mechanism, as seen below, or use something that notifies you of key presses/depresses, like a window or a hook.
  • Oh, that clears things up a bit better. The function you're looking for is SetWindowsHookEx. There are quite a few good examples of the various hooks, but the one you want is to hook the game window's message procedure. Hook it to check for key events, and handle them appropriately.
  • It's not really a case of old or modern. GetKeyState is for messages when you need the state at the time the message was sent. GetAsyncKeyState is for the state right now. Also, 0x80 is 10000000. The documentation says the high bit will be set if it's down, and that it returns short, hence 1000000000000000, or 0x8000.
  • I appreciate your reply, but with 5 or more keys, it will be a complete mess.
  • @AnılÜnal, you can do almost the same thing using a hook. Something like (not real syntax): if (WM_KEYDOWN) { switch (code) { case SPACE: if (last == UP) DoSomething(); ... } } and set the state using WM_KEYDOWN and WM_KEYUP messages. A hook shouldn't get called until keyboard actions occur too; it should be idle otherwise.