Why after I press the directional arrow ON, the function GetKeyState continues to give me a value greater than 0?
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
for(int i = 0; i < 1000; ++i)
{
if(GetKeyState(VK_UP))
{
cout << "UP pressed" << endl;
}
else
cout << "UP not pressed" << endl;
Sleep(150);
}
return 0;
}
From the documentation:
The key status returned from this function changes as a thread reads
key messages from its message queue. The status does not reflect the
interrupt-level state associated with the hardware. Use the
GetAsyncKeyState function to retrieve that information.
Since you are not processing messages, you'll want to call GetAsyncKeyState instead.
Test for the key being pressed like this:
if (GetAsyncKeyState(VK_UP) < 0)
// key is pressed
GetKeyState doesn't return a "boolean-like".
Take a look at the documentation :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
It seems that you need to do :
if (GetKeyState(VK_UP) & 0x8000)
{
//Your code
}
else
{
// Not pressed
}
0x8000 if the result is a short or -127/-128 if the result is a char. Check the "return value" section of the documentation to see what you want
and also, GetKeyState() function, can be used for normal character keys like 'a' ~ 'Z'. (it's not case sensitive)
if (GetKeyState('A' & 0x8000)
{
// code for Pressed
}
else
{
// code for Not Pressed
}
Related
So i am making a software to help me with an arduino project, it is supossed to be like PUTTY. I programed the arduino to play different notes from Q-I(C4-C5) and the software is supossed to play thoes notes but i need to make it detect when the Key is pressed and released, how do i do that? I searched and found something but it is not working like it's supposed to here is the code:
int main(){
int KeyGet;
while(1)
{
KeyGet = getch();
if (GetKeyState(0x51) & 0x8000)
{
cout<<"key is pressed"<< endl;
}
else if(GetKeyState(0x51)& 0x0001)
{
cout<<"key is released"<< endl;
}
}
return 0;
The program just prints "key is pressed" when i press Q(0x51) and not "key released" as it should, insted it prints "key released" when i press something else other the Q. And i tried GetAsyncKeyState and tried
If (GetKeyState(0x51) != 0)
it still doesent work.
GetKeyState() requires a window and a message loop to keep the state machine updated. But you do not have a message loop. Also, getch() would swallow any key press+release anyway.
Also, GetKeyState(0x51) & 0x0001 is not the right way to detect a key release. That bit is meant for detecting the toggle state of togglable keys like CapsLock, etc.
In your example, you would need to get rid of getch() and use GetAsyncKeyState() instead, eg:
int main(){
bool down = false;
while (1) {
if (GetAsyncKeyState(0x51) < 0) {
if (!down) {
down = true;
cout << "key is pressed" << endl;
}
}
else {
if (down) {
down = false;
cout << "key is released"<< endl;
}
}
Sleep(0);
}
return 0;
}
Otherwise, you can use a WH_KEYBOARD[_LL] hook via SetWindowsHookEx() instead, so you can receive actual key down/up notifications in real-time.
I am trying to get current key state for key ALT?
But its not work,why?
Here is the code
#include <iostream>
#include <Windows.h>
bool KeyPressed(short p_key)
{
if (GetAsyncKeyState(p_key) & 0x8000)
{
std::cout << "KEYPRESSED";
return true;
}
else return false;
}
int main()
{
std::cout << "Test";
while (true)
{
KeyPressed(0x4A);
}
std::cout << "";
}
It should get the state everytime it check,but its not at all
Try to use something like this:
if (GetKeyState(VK_MENU) & 0x8000))
{
// ALT key is down.
}
VK_MENU is the virtual-key code for the ALT key
Found this information in following article:
https://learn.microsoft.com/en-us/windows/win32/learnwin32/keyboard-input
In the program I am writing when I hit the 'escape' key, I want it to register immediately, even during the sleep period. Currently it waits until the end of the sleep statement before registering the key press. The sleep time is important to the program, so it is not a matter of just adding a pause and waiting on user input.
int main()
{
bool ESCAPE = false; // program ends when true
while (!ESCAPE) {
// Stop program when Escape is pressed
if (GetAsyncKeyState(VK_ESCAPE)) {
cout << "Exit triggered" << endl;
ESCAPE = true;
break;
}
Sleep(10000);
}
system("PAUSE");
return 0;
}
EDIT: To clarify, the reason for the sleep is that I am performing an action repeatedly on a time interval.
Instead of sleeping for 10 seconds, you can check if 10 seconds is passed, and do whatever needs to be done at that point. This way the loop is checking constantly for a keypress.
#include <chrono>
...
auto time_between_work_periods = std::chrono::seconds(10);
auto next_work_period = std::chrono::steady_clock::now() + time_between_work_periods;
while (!ESCAPE) {
// Stop program when Escape is pressed
if (GetAsyncKeyState(VK_ESCAPE)) {
std::cout << "Exit triggered" << std::endl;
ESCAPE = true;
break;
}
if (std::chrono::steady_clock::now() > next_work_period) {
// do some work
next_work_period += time_between_work_periods;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
I'm a bit new to C++, so I beg your pardon for being a bit nooby.
Is there a function I can use to make the console pause until a specific key is pressed?
Example being:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
if (specific key pressed) {
i = 1;
} else if (other key pressed) {
i = 2;
}
cout << i << endl;
return 0;
}
The console should output 1 if the right key is pressed, and 2 if another key is.
What you're trying to do is a bit more complex, C++ makes use of the cin stream where the input into the console is fed into your program. Where as a key-press event would be something the operating system would handle and would vary between operating systems. So using something like this would require the user to press enter/return for the input to be received by the program.
char key;
std::cin >> key;
if (key == 'a') {
std::cout << 1;
}
else {
std::cout << 2;
}
Find some answers here How to handle key press events in c++
Works on Windows only:
#include <iostream>
#include <vector>
#include <Windows.h>
char GetKey(std::vector<char> KeysToCheckFor)
{
while (true)
{
Sleep(1);
for (int i = 0; i < KeysToCheckFor.size(); i++)
{
if (GetKeyState(toupper(KeysToCheckFor[i])) < 0) { return KeysToCheckFor[i]; }
}
}
}
int main()
{
std::cout << "Press one of the keys: a,b,c\n";
char returnedkey = GetKey({ 'a', 'b', 'c' });
std::cout << returnedkey << " has been pressed!\n";
system("pause");
}
How would I effectively cancel a call for user input if there is no input within a certain time? (I'm programming a game for a terminal/cmd window with Mac OS X).
I have tried turning off canonical buffering and using a timer thread that joins after the call for user input. I also tried implementing the call to pthread_join() within the parameters of the while loop. Still nothing. The problem is that even though canonical buffering is off, the call for user input is still held up when there is no input. It works fine if there is input though.
It would be great if I could do this without fiddling around with downloading and installing ncurses, but I'll do it if I have to.
Edit: Source code:
//Most headers only pertain to my main program.
#include <iostream>
#include <termios.h>
#include <pthread.h>
#include <time.h>
#include <cstring>
#include <stdio.h>
#include <string.h>
using namespace std;
//Timer function.
void *Timer(void*) {
time_t time1, time2;
time1 = time(NULL);
while (time2 - time1 < 1) {
time2 = time(NULL);
}
pthread_exit(NULL);
}
int main() {
//Remove canonical buffering.
struct termios t_old, t_new;
tcgetattr(STDIN_FILENO, &t_old);
t_new = t_old;
t_new.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &t_new);
cout << "Press any key to continue." << endl;
string szInput;
int control = 0;
do {
pthread_t inputTimer;
pthread_create(&inputTimer, NULL, Timer, NULL);
szInput = "";
while (szInput == "") {
szInput = cin.get();
//Handle keypresses instantly.
if (szInput == "a") {
cout << endl << "Instant keypress." << endl;
}
}
pthread_join(inputTimer, NULL);
cout << endl << "One second interval." << endl;
control ++;
} while (control < 25);
cout << "Game Over." << endl;
return 0;
}
See if this works!
char ch; //Input character
int time = 0; //Time iterator
int TIMER = 5000; //5 seconds
while(time<TIMER)
{
if(!kbhit())
{
time = 0;
ch = getch();
//Do your processing on keypress
}
time++;
delay(1);
}
kbhit() detects if any keystroke has occurred. If yes, then get the key character in ch.
One way of checking if there is input is to poll the file descriptor STDIN_FILENO using e.g. the select system call. If STDIN_FILENO is readable, then you can read at at least one character. You can also pass a timeout to the select call.
Thanks Shashwat, it works with the below modifications:
1) Changing if(!kbhit()) to if(kbhit())
2) Changing delay(1); to Sleep(1);
I do not have enough rep to post a comment, hence adding as an answer.