How to Check If a Key Is Pressed on C++

c programming check if key pressed without stopping program

You can use kbhit() to check if a key is pressed:

#include <stdio.h>
#include <conio.h> /* getch() and kbhit() */

int
main()
{
char c;

for(;;){
printf("hello\n");
if(kbhit()){
c = getch();
printf("%c\n", c);
}
}
return 0;
}

More info here: http://www.programmingsimplified.com/c/conio.h/kbhit

Is there a way to detect if a key has been pressed?

I use the following function for kbhit(). It works fine on g++ compiler in Ubuntu.

#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;

tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

ch = getchar();

tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);

if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}

return 0;
}

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

_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.

How do I check if a Key is pressed on C++

As mentioned by others there's no cross platform way to do this, but on Windows you can do it like this:

The Code below checks if the key 'A' is down.

if(GetKeyState('A') & 0x8000/*Check if high-order bit is set (1 << 15)*/)
{
// Do stuff
}

In case of shift or similar you will need to pass one of these: https://msdn.microsoft.com/de-de/library/windows/desktop/dd375731(v=vs.85).aspx

if(GetKeyState(VK_SHIFT) & 0x8000)
{
// Shift down
}

The low-order bit indicates if key is toggled.

SHORT keyState = GetKeyState(VK_CAPITAL/*(caps lock)*/);
bool isToggled = keyState & 1;
bool isDown = keyState & 0x8000;

Oh and also don't forget to

#include <Windows.h>

How to check if a key was pressed in C#? (.NET 6)

If you need to detect a modifier key outside of a KeyEventHandler method, you can use the static Keyboard class from System.Windows.Input.

Example from my WPF .NET 6.0 Application on Windows

if (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt))
{
// Do something
}

C: Fastest way to determine, if any key on the keyboard has been pressed

As comment, you could use RegisterRawInputDevices as this sample.

  1. Create a Message-Only Window.
  2. Set RAWINPUTDEVICE.hwndTarget to the window create in step 1, so that you don't need to focus on the window.
  3. Call GetRawInputData to get the input data.

Sample(removed the error checking):

#include <windows.h>
#include <iostream>
using namespace std;
LRESULT CALLBACK WindProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_INPUT)
{
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
RAWINPUT input = { 0 };
UINT size = sizeof(input);
GetRawInputData(hRawInput, RID_INPUT,&input,&size,sizeof(RAWINPUTHEADER));

printf("vkey: %x, flag: %d\n",input.data.keyboard.VKey, input.data.keyboard.Flags);
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}

int main()
{
WNDCLASSEX wcx = { 0 };
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.lpfnWndProc = WindProc;
wcx.hInstance = GetModuleHandle(NULL);
wcx.lpszClassName = TEXT("RawInputClass");
RegisterClassEx(&wcx);
HWND hWnd = CreateWindowEx(0, TEXT("RawInputClass"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);

RAWINPUTDEVICE rid = { 0 };
rid.usUsagePage = 0x01;
rid.usUsage = 0x06; //keyboard
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = hWnd;

RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return 0;
}


Related Topics



Leave a reply



Submit