【问题标题】:The curious problem of the missing WM_NCLBUTTONUP message when a window isn't maximised窗口未最大化时缺少 WM_NCLBUTTONUP 消息的奇怪问题
【发布时间】:2009-02-06 17:02:42
【问题描述】:

我有一个处理 WM_NCLBUTTONUP 消息的窗口,以便处理对标题栏中自定义按钮的点击。当窗口最大化时这很有效,但是当它不是时,WM_NCLBUTTONUP 消息永远不会到达!我确实收到了 WM_NCLBUTTONDOWN 消息。奇怪的是,如果我单击菜单栏的右侧,WM_NCLBUTTONUP 确实会到达,但是沿着标题栏/窗口框架的任何地方,消息永远不会到达。

调试一段时间后发现如果我在CMainFrame::OnNcLButtonDown()上设置断点,点击标题栏,但一直按住鼠标,让调试器在函数中中断,按F5继续调试,然后释放鼠标按钮 - 神奇地发送 WM_NCLBUTTONUP!!

我的问题有两个,(1)到底发生了什么? (2) 如何解决这个“问题”。

我还注意到互联网上还有其他几个人有同样的问题(快速的谷歌显示很多其他人有同样的问题,但没有解决方案)。

编辑
感谢前两位的回复,我试过在NCLButtonDown中调用ReleaseCapture,但是没有效果(其实返回NULL,说明没有抓到)。我只能假设基类(def window proc)功能可以设置捕获。我会在星期一调查...

【问题讨论】:

    标签: c++ winapi mfc


    【解决方案1】:

    我也遇到过同样的问题。问题确实是左键单击窗口标题开始拖动,因此鼠标捕获,这会阻止 WM_NCLBUTTONUP 到达。

    解决方案是覆盖 WM_NCHITTEST:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (nMsg)
        {
            ...
            case WM_NCHITTEST:
                Point p(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam);
                ScreenToClient(p);
                if (myButtonRect.Contains(p))
                {
                    return HTBORDER;
                }
                break;
        }
        return DefWindowProc(hWnd, nMsg, wParam, lParam);
    }
    

    所以基本上你告诉 Windows 你的按钮占用的区域不是窗口标题的一部分,而是非客户区 (HTBORDER) 的非特定部分。

    脚注:如果您在预期 WM_NCLBUTTONDOWN 消息进入时调用了 SetCapture() 并且尚未调用 ReleaseCapture(),则即使进行上述更改,它也不会到达。这可能很烦人,因为在与此类自定义按钮交互期间捕获鼠标是正常的,因此如果鼠标离开窗口,您可以取消单击/突出显示。但是,作为使用捕获的替代方法,您可以考虑使用较短(例如 100 毫秒)间隔的 SetTimer()/KillTimer(),这不会导致 WM_NCLBUTTONUP 消息消失。

    【讨论】:

      【解决方案2】:

      一个疯狂的猜测 - 一些代码正在捕捉鼠标,可能是为了在你抓住标题时促进窗口移动。这也可以解释为什么在调试器中中断会导致消息显示 - 调试器交互正在清除鼠标捕获。

      我建议你在那个窗口和它的子窗口上运行 Spy++,并尝试找出谁得到了按钮向上的消息。

      至于如何修复它 - 如果不查看实际代码就无法帮助您。您必须找出罪魁祸首并查看他们的代码。

      【讨论】:

        【解决方案3】:

        要添加到Franci Penov's answer,单击标题栏将被解释为开始拖动以重新定位窗口。该窗口正在捕获鼠标,因此它可以执行拖动。由于无法拖动最大化的窗口,因此跳过捕获并正常发送消息。

        【讨论】:

          【解决方案4】:

          在 WM_NCLBUTTONDOWN {代码块}中包含 ReleaseCapture()

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-06-08
            • 1970-01-01
            • 2012-06-01
            • 1970-01-01
            • 2020-07-14
            • 1970-01-01
            • 1970-01-01
            • 2018-06-13
            相关资源
            最近更新 更多