Как правильно использовать SetWindowsHookEx & amp; CallNextHookEx
Вопрос
Я могу правильно настроить хук Windows, но меня смущает строка в MSDN, в которой говорится "Вызов функции CallNextHookEx для цепочки следующей процедуры хука необязателен, но это настоятельно рекомендуется; в противном случае другие приложения, в которых установлены хуки, не будут получать уведомления о хуках и в результате могут работать некорректно. Вы должны вызывать CallNextHookEx, если вам абсолютно не нужно предотвращать просмотр уведомления другими приложениями. & Quot;.
Я хочу быть хорошим гражданином в программировании и назвать следующий хук. Но моя процедура подключения выглядит так:
LRESULT CALLBACK CBTProc(int code, WPARAM wp, LPARAM lp)
{
if (code != HCBT_CREATEWND)
{
// What do I do here? It's not the event I requested so how do I pass it on?
return 0;
}
// It's the code we want (create window)
CallNextHookEx(...);
...
}
Итак, что происходит в процедуре подключения, если код не тот, который меня интересует? Как мне вызвать следующий хук?
Правка . Основная проблема заключается в том, что HHOOK возвращается из SetWindowsHookEx, и его необходимо передать в функцию CallNextHookEx.
Обновление . Кажется, что параметр hook игнорируется на платформах NT:
http://msdn.microsoft.com/en-us/library/ms644974.aspx
http://www.klenotic.com/pl/null_hhook/
Решение
Согласно документам, правильная вещь - это передать полученные аргументы непосредственно CallNextHookEx в точности так, как вы их получили. Вам также следует вызывать CallNextHookEx независимо от того, решили ли вы обработать сообщение о перехвате.
Согласно MSDN , первый параметр CallNextHookEx
игнорируется в NT / XP / 2003, а для более старых операционных систем на основе Win95 это должен быть HHOOK
, который вы получили, когда зарегистрировали свой хук в SetWindowsHookEx
, В документах не указывается значение для Windows 2000, но, поскольку оно является частью семейства NT, разумно предположить, что оно там тоже игнорируется. Р>
Учитывая все это, хороший способ кодирования метода для операционных систем семейства NT может быть следующим:
LRESULT CALLBACK CBTProc( int code, WPARAM wp, LPARAM lp )
{
if( code == HCBT_CREATEWND )
ProcessCreateWnd( wp, lp );
return CallNextHookEx( 0, code, wp, lp );
}
void ProcessCreateWnd( WPARAM wp, LPARAM lp )
{
// my code here
}
Это гарантирует, что вы всегда вызываете ловушку в конце вашей обработки, и затрудняет случайное добавление return
, которое будет обходить CallNextHookEx
.