Я пытаюсь реализовать следующий сценарий: Требование Напишите программу на C ++ для захвата всех вводов с клавиатуры в ОС Windows. Программа должна начать фиксировать нажатия клавиш и примерно через 3 ...

1
George Gkasdrogkas 10 Апр 2021 в 01:10

1 ответ

Лучший ответ

Я думаю, что это ваша проблема

  while (WaitForSingleObject(ghStopEvent, 1) == WAIT_TIMEOUT)
  {
    // Retrieve the current messaged from message queue.
    GetMessage(&msg, NULL, 0, 0);
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

Причина в том, что в настоящее время ваш цикл может застрять на шаге GetMessage() навсегда и никогда больше не будет смотреть на событие ручного сброса.

Чтобы исправить это, просто замените комбинацию WaitForSingleObject + GetMessage на MsgWaitForMultipleObjects + PeekMessage.

Причина, по которой вы допустили эту ошибку, заключается в том, что вы не знали, что GetMessage возвращает в цикл сообщений только опубликованные сообщения. Если он находит отправленное сообщение, он вызывает обработчик изнутри GetMessage и продолжает поиск отправленного сообщения. Поскольку вы не создали ни одного окна, которое может принимать сообщения, и не вызываете PostThreadMessage 1 , GetMessage никогда не возвращается.

while (MsgWaitForMultipleObjects(1, &ghStopEvent, FALSE, INFINITE, QS_ALLINPUT) > WAIT_OBJECT_0) {
   // check if there's a posted message
   // sent messages will be processed internally by PeekMessage and return false
   if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
}

1 У вас есть логика для публикации WM_QUIT, но она обусловлена ​​получением WM_DESTROY с помощью низкоуровневого обработчика клавиатуры, а WM_DESTROY не является сообщением с клавиатуры. . Некоторые типы ловушек могут видеть WM_DESTROY, а WH_KEYBOARD_LL - нет.

2
Ben Voigt 9 Апр 2021 в 22:30