Win32 - как управлять моей цепочкой мыши - PullRequest
2 голосов
/ 11 июля 2010

Я успешно применил мой низкоуровневый код мыши, но я наблюдаю некоторые варианты поведения, которые я не совсем понимаю. Все работает нормально, если я создаю поток, который устанавливает ловушку мыши. Когда он мне больше не нужен, я позволяю потоку автоматически уничтожаться при выходе из программы, и я думаю, что могу легко прекратить поток явно. Однако это делает меня неловким, потому что я не буду звонить UnhookWindowsHookEx, чтобы освободить ресурсы ловушки мыши.

Итак, я попытался изменить логику в моей тестовой программе. Я пытаюсь порождать поток, который немного спит, а затем записывает в глобальную переменную. Затем я вызываю процедуру установки хука из основного потока. Здесь есть цикл, который проверяет глобальную переменную и выходит из цикла при необходимости. Тогда он сможет убирать за собой. Вот соответствующий код:

static int willQuit = 0;
unsigned WINAPI MouseProcessingProc (void *param) {
 try { // will catch exceptions and not propagate them
  HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc,
    NULL, 0);
  if (mousehook == NULL) printf("Mousehook error %u\n",GetLastError());

  while(true) {
   MSG msg;
   if (GetMessage(&msg,0,0,0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
   }
   if (willQuit) { printf("willQuit no longer 0!\n"); break; }
   printf("Looped\n");
  }
  willQuit = 0;
  UnhookWindowsHookEx(mousehook);

  printf("Procedure completed without exceptional events.\n");
 } catch (const std::string& s) {
  printf("String exception: %s\n", s.c_str());
 } catch (int i) {
  printf("Int exception: %d\n", i);
 } catch (...) {
  printf("Unknown default exception!\n");
 }
 printf("Exiting thread execution.\n");
 return 0;
}

void spawn() {
 printf("Spawning Mouse thread\n");
 _beginthreadex(NULL,0,MouseProcessingThreadProc,NULL,0,0);
}

void run() {
 printf("Running Mouse routine\n");
 MouseProcessingThreadProc(0);
}

void stop() {
 printf("Stopping Mouse routine\n");
 willQuit = 1;
}

unsigned WINAPI threadproc(void *param) {
    Sleep(500);
    printf("Spawned thread says 3");
    Sleep(500);
    printf("2");
    Sleep(500);
    printf("1\n");
    Sleep(500);
    printf("Spawned thread calls stop now -->\n");
    stop();
}

int main() {
    _beginthreadex(NULL,0,threadproc,NULL,0,0); // waiter and stopper thread
    run(); // become the mousehook thread
    printf("Completed\n");
    return 0;
}

Теперь происходит то, что мой маленький цикл опроса сообщений (цикл while) никогда не возвращается из вызова GetMessage, поэтому он никогда не достигнет точки, где он проверяет willQuit. Я проверил это с этими printf и gdb. Почему GetMessage не возвращается? Есть ли лучший способ настроить мою нить крюка мыши? Или я пытаюсь сделать что-то, чего не должен делать?

спасибо за чтение.

1 Ответ

1 голос
/ 11 июля 2010

В вашей подпрограмме stop () после установки переменной willQuit вам также потребуется POST-сообщение для потока, выполняющего MouseProcessingProc, поэтому GetMessage вернется. См. PostThreadMessage API.

РЕДАКТИРОВАТЬ: Вы также можете использовать событие или другой объект синхронизации, вместо использования сообщений Windows и насос сообщений. Таким образом, обработчик сообщений получит замену на что-то вроде WaitForSingleObject, некоторый объект ядра, который вы можете сообщить, например, событие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...