Reputation: 7243
I am using a simple loop for catching user keypresses;
while (1)
{
for(i = 8; i <= 190; i++)
{
if (GetAsyncKeyState(i) == -32767){
//Do stuff
}
}
}
Which will 'do stuff' when a user presses a certain key, however obviously as it's looping indefinitely and as i'm new to C++ it's taking up 100% CPU which is not good for a simple input.
What am I doing wrong? I've tried the Sleep() function (if I put it in the 'for loop' it misses keypresses and if I put it in the 'while loop' it doesn't lower CPU at all, afaik)
How can I make it catch keypresses the same, but use not nearly as much CPU; am I missing a trick? I'm sure most programs catch keypresses and you don't see all them using 100%!
Thanks alot.
Upvotes: 4
Views: 7593
Reputation: 9691
Put your infinite loop in a worker thread, and have it sleep for some reasonable interval on each iteration. C++11 makes this pretty easy:
#include <thread>
#include <chrono>
std::chrono::milliseconds THREAD_WAIT = 50;
int keypress = -1;
void GetKeyPress()
{
while (1)
{
for(i = 8; i <= 190; i++)
{
int k = GetAsyncKeyState(i);
if (/*whatever condition needs to be satisfied*/)
keypress = k;
}
if (keypress != -1) break; //Use this only if you have td.join() below
std::this_thread::sleep_for(THREAD_WAIT);
}
}
int main(void)
{
...
std::thread td( GetKeyPress );
td.join(); //If you want to block until the user presses a key, otherwise remove.
//If no join(), do the rest of your program, checking in on keypress when need be
return 0;
}
Upvotes: 3
Reputation: 193
Please check following link that explains Proper use of GetAsyncKeyState() with example code. http://www.mpgh.net/forum/31-c-c-programming/120656-proper-use-getasynckeystate.html
Hope this link might help you to solve your problem
Edited: The GetAsyncKeyState() function is not ideal for what you are trying to do.
All it does is simply check the actual, current-at-this-nanosecond position of a key on the keyboard. Doing that is almost always incorrect.
Instead, read the console input using the proper input functions. Please find below the sample code.
#include <stdio.h>
#include <windows.h>
int main()
{
DWORD mode; /* Preserved console mode */
INPUT_RECORD event; /* Input event */
BOOL done = FALSE; /* Program termination flag */
unsigned int counter = 0; /* The number of times 'Esc' is pressed */
/* Don't use binary for text files, OK? ;-) */
FILE* myfile = fopen( "example.txt", "w" );
/* Get the console input handle */
HANDLE hstdin = GetStdHandle( STD_INPUT_HANDLE );
/* Preserve the original console mode */
GetConsoleMode( hstdin, &mode );
/* Set to no line-buffering, no echo, no special-key-processing */
SetConsoleMode( hstdin, 0 );
/* Give the user instructions */
printf(
"Press Escape as many times as you like.\n"
"Press anything else to quit.\n\n"
);
while (!done)
{
if (WaitForSingleObject( hstdin, 0 ) == WAIT_OBJECT_0) /* if kbhit */
{
DWORD count; /* ignored */
/* Get the input event */
ReadConsoleInput( hstdin, &event, 1, &count );
/* Only respond to key release events */
if ((event.EventType == KEY_EVENT)
&& !event.Event.KeyEvent.bKeyDown)
switch (event.Event.KeyEvent.wVirtualKeyCode)
{
case VK_ESCAPE:
counter++;
fprintf( myfile, "Escape: %d\n", counter );
printf( "Button pressed!\n" );
break;
default:
done = TRUE;
}
}
}
/* All done! */
printf( "You pressed the Escape key %d times\n", counter );
fclose( myfile );
SetConsoleMode( hstdin, mode );
return 0;
}
Upvotes: 1