для цикла — перехват нажатий клавиш Переполнение стека

Я использую простой цикл для перехвата пользовательских нажатий клавиш;

while (1)
{
for(i = 8; i <= 190; i++)
{
if (GetAsyncKeyState(i) == -32767){
//Do stuff
}
}
}

Который будет «делать что-то», когда пользователь нажимает определенную клавишу, однако очевидно, что он зацикливается бесконечно, и, поскольку я новичок в C ++, он потребляет 100% ЦП, что не годится для простого ввода.

Что я делаю неправильно? Я пробовал функцию Sleep () (если я помещаю его в цикл for, он пропускает нажатия клавиш, а если я помещаю его в цикл while, он вообще не понижает ЦП)

Как я могу сделать так, чтобы он улавливал нажатие клавиш одинаково, но использовал не столько процессор; я пропускаю трюк? Я уверен, что большинство программ перехватывают нажатия клавиш, и вы не видите их все, используя 100%!

Большое спасибо.

1

Решение

Пожалуйста, проверьте следующую ссылку, которая объясняет правильное использование GetAsyncKeyState () с примером кода.
http://www.mpgh.net/forum/31-c-c-programming/120656-proper-use-getasynckeystate.html

Надеюсь, что эта ссылка может помочь вам решить вашу проблему

Отредактировано:
Функция GetAsyncKeyState () не идеальна для того, что вы пытаетесь сделать.

Все, что он делает, это просто проверяет фактическое положение клавиши на клавиатуре «текущее при этой наносекунде». Делать это почти всегда неправильно.

Вместо этого читайте ввод с консоли, используя соответствующие функции ввода. Пожалуйста, найдите ниже пример кода.

#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;
}
2

Другие решения

Поместите свой бесконечный цикл в рабочий поток и оставьте его спать в течение некоторого разумного интервала на каждой итерации. C ++ 11 делает это довольно легко:

#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;
}
2

Вы могли бы использовать

while (!kbhit());

Это может помочь.

0
По вопросам рекламы [email protected]