我想'保护'某个窗口关闭。所以我想挂钩WM_CLOSE,WM_DESTOY或WM_QUIT。这就是我试图这样做的:
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);
}
我试过了:
同样我注意到,如果我挂钩WH_GETMESSAGE它不会“阻止”消息循环。但它是通过挂钩WH_CALLWNDPROC来实现的。我发现这是在msg->消息等于WM_CLOSE时提示消息框。
提前致谢, 问候。
答案 0 :(得分:1)
而不是尝试安装一个钩子,只需将窗口子类化,让你的子类WndProc在转发所有其他消息时忽略WM_CLOSE
。
您不能也不应该尝试停止WM_QUIT
。正如罗德里戈指出的那样,你无法对WM_DESTROY
做任何事情。此时,DestroyWindow
已被调用,无论您是否愿意,您的窗口都会消失。
答案 1 :(得分:1)
WH_GETMESSAGE为从消息队列中检索的消息安装挂钩。它允许您修改消息。但问题是WM_CLOSE没有发布到PostMessage()的消息队列中,它与SendMessage()一起发送。这个钩子看不到它。
WH_CALLWNDPROC安装一个在调用窗口过程之前运行的钩子。这将允许您查看WM_CLOSE。但是,您不能修改消息或使消失。
没有钩子可以让你做你想做的事。相反,你必须子类窗口过程。这样就可以在窗口自己的过程之前调用自己的自定义窗口过程。现在你可以通过不调用旧窗口过程简单地过滤WM_CLOSE。
请注意,您仍然需要与SetWindowsHookEx()提供的相同类型的管道,您仍需要将带有窗口过程的DLL注入到该过程中。最好的方法是仍然使用SetWindowsHookEx来完成一个虚拟钩子,否则什么都不做。