钩窗口消息循环WM_CLOSE

时间:2012-12-17 13:43:47

标签: c

我想'保护'某个窗口关闭。所以我想挂钩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);
}

我试过了:

  • 返回TRUE或FALSE
  • 使用NULL作为LPARAM或调用CallNextHookEx 将msg->消息编辑为0

同样我注意到,如果我挂钩WH_GETMESSAGE它不会“阻止”消息循环。但它是通过挂钩WH_CALLWNDPROC来实现的。我发现这是在msg->消息等于WM_CLOSE时提示消息框。

提前致谢, 问候。

2 个答案:

答案 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来完成一个虚拟钩子,否则什么都不做。