Я устанавливаю крючок в своем графическом приложении. Я хочу поймать сообщение WM_DESTROY с крюком WH_CBT, но это не похоже на работу.
...
HWND ghWnd = NULL;
HHOOK ghHook = NULL;
...
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
...
SetHook();
....
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
...
}
...
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
case WM_DESTROY:
UnHook();
PostQuitMessage(0);
break;
...
}
LRESULT WINAPI HookProc(int Id, DWORD wParam, DWORD lParam)
{
if ( Id == WM_DESTROY )
{
MessageBoxA(NULL, "I got it", NULL, 0);
}
return CallNextHookEx(ghHook, Id, wParam, lParam);
}
void SetHook()
{
ghHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)HookProc, hInst, GetCurrentThreadId());
if ( ghHook != NULL )
MessageBox(ghWnd, L"Hooked", L"Hook!", 0 );
else
MessageBox(ghWnd, L"Unable to hook", L"Hook!", 0 );
}
void UnHook()
{
if ( ghHook != NULL )
{
UnhookWindowsHookEx(ghHook);
MessageBoxA(ghWnd, "Unhooked", NULL, 0);
}
}
Когда я запускаю приложение, я вижу сообщение "Hooked" и "UnHooked", когда я нажимаю кнопку X (символ X в правом верхнем углу окна).
Но я пропустил сообщение в функции HookProc.
Может ли кто-нибудь объяснить мне почему?
Прочтите документацию. Id
в WH_CBT
никогда не будет WM_DESTROY
. Когда окно будет уничтожено, вместо этого Id
будет HCBT_DESTROYWND
.
Если вы хотите поймать фактическое сообщение WM_DESTROY
, вместо этого используйте вместо этого WH_CALLWNDPROC
.
MessageBox()
использует HWND, как и любой другой пользовательский интерфейс. Когда вы закрываете диалоговое окно, эти HWND уничтожаются, вызывая уведомления HCBT_DESTROYWND
. Поэтому не вызывайте MessageBox()
в своем хуке, используйте другой подход к отладке, например OutputDebugString()
.