I wanted to ‘protect’ a certain window from closing. So I wanted to hook WM_CLOSE, WM_DESTOY or WM_QUIT. And this is what I tried to do so:
LRESULT CALLBACK WindowHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
MSG* msg = (MSG*)lParam;
//if (msg->hwnd == GetForegroundWindow())
{
if (msg->message == WM_CLOSE || msg->message == WM_QUIT || msg->message == WM_DESTROY)
{
//MessageBox(0, "TEST", "", 0);
msg->message = 0;
CallNextHookEx(hMsg, nCode, (WPARAM)NULL, (LPARAM)NULL);
return TRUE;
}
}
}
CallNextHookEx(hMsg, nCode, wParam, lParam);
}
I tried:
- Returning TRUE or FALSE
-
Calling CallNextHookEx with NULL as LPARAM or
editing the msg->message to 0
Also what I noticed, if I hook WH_GETMESSAGE it doesn’t ‘block’ the message loop. But it does so with hooking WH_CALLWNDPROC. I discovered this with prompting a messagebox when the msg->message equals to WM_CLOSE.
Thanks in advance,
Regards.
WH_GETMESSAGE installs a hook for messages that are retrieved from the message queue. It does allow you to modify the message. But the problem is that WM_CLOSE is not posted to the message queue with PostMessage(), it is sent with SendMessage(). This hook can’t see it.
WH_CALLWNDPROC installs a hook that runs just before the window procedure is called. Which will allow you to see WM_CLOSE. However, you are not allowed to modify the message or make it disappear.
There is no hook that allows you to do what you want to do. Instead you have to sub-class the window procedure. So that your own custom window procedure is called before the window’s own procedure. Now you can simply filter WM_CLOSE by just not calling the old window procedure.
Beware that you still need the same kind of plumbing that SetWindowsHookEx() provides, you still need to inject a DLL with your window procedure into the process. Best way is to still use SetWindowsHookEx to get that done with a dummy hook that doesn’t otherwise do anything.