CodyT96
CodyT96

Reputation: 175

How can I detect if any key is pressed in C++?

I'm looking for a way to detect if any key is pressed in a Windows environment C++ console application. Emphasis on any, not a specific key or set of keys. I've searched all over this website and I can't find an answer. The best I've found is to use the GetKeyState function or the GetAsyncKeyState but with no examples of how to use it, and I've checked the documentation on Microsoft's website too and still am unsure of how I would use it.

If this is relevant and it helps, I am using Visual Studio, and when creating this project, I selected Empty Project, not Console App.

The outline of the program is expected to look like this:

Clock flowchart

Here is the code I have used so far in my main .cpp file:

#ifndef MAINCPP
#define MAINCPP

#include "TwelveClock.h"
#include "TwentyFourClock.h"
#include <iostream>
#include <iomanip>
#include <Windows.h>
using namespace std;

void displayMenu() {
    cout << setw(27) << setfill('*') << "" << endl;
    cout << "* 1 -- Add One Hour" << setfill(' ') << setw(8) << '*' << endl;
    cout << "* 2 -- Add One Minute" << setw(6) << '*' << endl;
    cout << "* 3 -- Add One Second" << setw(6) << '*' << endl;
    cout << "* 4 -- Exit Program" << setw(8) << '*' << endl;
    cout << setw(27) << setfill('*') << "" << endl;
}

void displayClocks(TwentyFourClock& tfc, TwelveClock& tc) {
    cout << setfill('*') << setw(24) << "" << "    " << setw(25) << "" << endl;
    cout << setfill(' ') << "*" << setw(17) << "12-Hour Clock" << setw(6) << "*" << "    *" << setw(17) << "24-Hour Clock" << setw(7) << "*" << endl;

    cout << "*" << setw(5) << "" << setw(2) << setfill('0') << tc.Get_hour() << ":" << setw(2) << tc.Get_minute() << ":" << setw(2) << tc.Get_second() << " " << tc.Get_strPM_status() <<setfill(' ') << setw(7) << "*";
    cout << "    *" << setw(7) << "" << setw(2) << setfill('0') << tfc.Get_hour() << ":" << setw(2) << tfc.Get_minute() << ":" << setw(2) << tfc.Get_second() << setfill(' ') << setw(9) << "*" << endl;

    cout << setfill('*') << setw(24) << "" << "    " << setw(25) << "" << endl;
}

int main() {
    TwentyFourClock TwentyFour;
    TwelveClock Twelve;

    while (1) {

        system("cls"); 
        displayClocks(TwentyFour, Twelve);

        //FIXME: check if button is pressed 

        TwentyFour.Set_second(TwentyFour.Get_second() + 1);
        Twelve.Set_second(Twelve.Get_second() + 1);
        Sleep(1000);
    }

    return 0;
}

#endif

Also I'm concerned that my program won't even be able to detect any input because of the sleep function pausing the execution. If this is the case, what would be a better approach to this? I appreciate all help I get.

Upvotes: 5

Views: 5841

Answers (1)

IInspectable
IInspectable

Reputation: 51345

_kbhit allows you to check whether a key has been pressed. Unlike _getch it returns immediately, and doesn't block in case there is no data in the input buffer to be read.

Both functions are Microsoft-specific extensions to the C Runtime (CRT), and aren't part of Standard C or C++.


Answers to secondary questions:

I'm concerned that my program won't even be able to detect any input because of the sleep function pausing the execution.

Console input is handled by the OS, and buffered for you while you aren't listening for input. The thread reading from console input need not be awake at the time the input arrives. It will always be able to observe input from the buffer when it wakes up to check.

If this is the case, what would be a better approach to this?

This won't happen. And yet, there are better options to implement the requirements. As it's currently implemented, the application will not be able to respond to input before the Sleep timeout expires. While reliable, this results in an observable delay between the user hitting a key and the application responding to it.

There are ways to address this. Both the Windows API as well as the C++ programming language offer services that allow you to implement a wait operation that returns as soon as one of several conditions is met (e.g. wait until a key is pressed or a timeout has expired).

The solutions are involved and require profound familiarity with the Windows API or C++ – ideally both – to digest. I doubt you'd benefit much (to try) to learn those at this point. Continue your journey and come back to this at a later time, enjoying the comfort of knowing that this can be solved.

Upvotes: 4

Related Questions