Проблема при перехвате сообщений клавиатуры с помощью SetWindowsHookEx - PullRequest
0 голосов
/ 23 июля 2011

Я пытаюсь подключить сообщения клавиатуры безуспешно.

Я создаю тестовое консольное приложение win32:

int _tmain(int argc, _TCHAR* argv[])
{
HOOKPROC hHookProc;
HINSTANCE hinstDLL; 
HHOOK hHook; 

hinstDLL = LoadLibrary(TEXT("pathtodll\\KeyHook.dll")); 
hHookProc= (HOOKPROC)GetProcAddress(hinstDLL, "HookProc"); 

hHook = SetWindowsHookEx( 
    WH_KEYBOARD,
    hHookProc,
    hinstDLL,
    0);

    while (1) {}

return 0;
}

Я также создал тестовую win32 dll сФункция HookProc:

extern __declspec(dllexport) LRESULT CALLBACK HookProc(
  int nCode, 
  WPARAM wParam, 
  LPARAM lParam
)
{
   // process event
   //...
     MessageBox( NULL,
                TEXT("OK"),
                TEXT("OK"),
                MB_OK);

   return CallNextHookEx(NULL, nCode, wParam, lParam);
}

Все компилируется нормально, но когда я пытаюсь отладить, кажется, что HookProc никогда не вызывается.На самом деле в Win 7 приложение зависает при нажатии любой клавиши, в то время как в Win Xp HookProc не вызывается.Я получаю не NULL hinstDLL, hHookProc, hHook.

Что я пропускаю?

Ответы [ 2 ]

1 голос
/ 24 июля 2011

Вместо выполнения пустого цикла while после вызова SetWindowsHookEx(), попробуйте вместо этого цикл перекачивать очередь сообщений вызывающего потока вместо Peek/GetMessage().Некоторые перехватчики выполняются в контексте потока, который их устанавливает, поэтому ОС должна иметь возможность переключаться на этот поток при необходимости.

0 голосов
/ 28 июля 2011

Пара вопросов здесь:

while (1) {}

Не делайте этого: ваш код теперь имеет занятый (бесконечный) цикл, который фактически сделает приложение не отвечающим (и, вероятно, заставит весь рабочий стол казаться вялым). Причина, по которой здесь работает GetMessage, заключается просто в том, что он возвращает управление операционной системе, которая переводит поток в спящий режим вместо его активной работы. Вы, вероятно, получите тот же эффект, просто вызвав Sleep (...), который также вернет управление обратно в ОС, но без перекачки сообщений. Для тестового кода что-то вроде getchar () может хорошо работать здесь, оно будет корректно блокироваться, пока вы не нажмете Enter в окне консоли. MessageBox () также может работать здесь.

extern __declspec(dllexport) LRESULT CALLBACK HookProc(
{
  MessageBox( NULL,
            TEXT("OK"),
            TEXT("OK"),
            MB_OK);

Другая проблема: вы обычно никогда не хотите делать что-либо «сложное» в перехвате перехвата - просто сделайте минимум для обработки сообщения и верните как можно скорее. Вы, конечно, никогда не хотите блокировать, что делает MessageBox. В целях отладки лучше всего использовать OutputDebugString () или какой-либо другой ориентированный на отладку API, который не блокируется.

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