当窗口未最大化时,缺少WM_NCLBUTTONUP消息的奇怪问题 [英] The curious problem of the missing WM_NCLBUTTONUP message when a window isn't maximised

查看:236
本文介绍了当窗口未最大化时,缺少WM_NCLBUTTONUP消息的奇怪问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个窗口,我处理WM_NCLBUTTONUP消息,以处理点击自定义按钮在标题栏。这个工作伟大的窗口是最大化,但是当它不是,WM_NCLBUTTONUP消息从来没有到达!我得到一个WM_NCLBUTTONDOWN消息。奇怪的是WM_NCLBUTTONUP确实到达,如果我点击菜单栏的右边,但在标题栏/窗口框架的任何地方,消息永远不会到达。

I've got a window that I handle WM_NCLBUTTONUP messages, in order to handle clicks on custom buttons in the caption bar. This works great when the window is maximised, but when it's not, the WM_NCLBUTTONUP message never arrives! I do get a WM_NCLBUTTONDOWN message though. Strangely WM_NCLBUTTONUP does arrive if I click on the right of the menu bar, but anywhere along the caption bar / window frame, the message never arrives.

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

After a while of debugging I discovered that if I set a breakpoint on CMainFrame::OnNcLButtonDown(), clicked the caption bar, but keep the mouse button held down, let the debugger break in the function, hit F5 to continue debugging, then release the mouse button - magically WM_NCLBUTTONUP is sent!!

我的问题是双重的,(1)发生了什么事? (2)如何解决这个问题。

My question is two-fold, (1) what the hell is going on? (2) how do I get around this "problem".

我还注意到,互联网上有几个其他人有相同的问题

I also note that there are several other people on the internet who have the same issue (a quick Google reveals lots of other people with the same issue, but no solution).

编辑

感谢前两个回复,我试过在NCLButtonDown调用ReleaseCapture,但它没有效果(实际上,它返回NULL,表示捕获不到位)。我只能假设基类(def window proc)的功能可以设置一个捕获。我会在星期一调查...

Edit
Thanks for the first two replies, I've tried calling ReleaseCapture in NCLButtonDown, but it has no effect (in fact, it returns NULL, indicating a capture is not in place). I can only assume that the base class (def window proc) functionality may set a capture. I shall investigate on Monday...

推荐答案

我有同样的问题。问题的确是,左键单击窗口标题开始拖动,从而阻止WM_NCLBUTTONUP到达鼠标捕获。

I've had this same problem. The issue is indeed that a left button click on the window caption starts a drag, and thus mouse capture, which prevents WM_NCLBUTTONUP from arriving.

解决方案是覆盖WM_NCHITTEST:

The solution is to override 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);
}

按钮不是窗口标题的一部分,而是非客户区(HTBORDER)的非特定部分。

So essentially you inform Windows that the area occupied by your button is not part of the window caption, but a non-specific part of the non-client area (HTBORDER).

脚注:如果您已调用SetCapture()尚未调用ReleaseCapture(),当您期望WM_NCLBUTTONDOWN消息进来时,它将不会到达,即使与上述更改。这可以是刺激性的,因为在与这样的定制按钮交互期间捕获鼠标是正常的,使得如果鼠标离开窗口,可以取消点击/高亮。但是,作为使用捕获的替代方法,您可以考虑使用短(例如,100 ms)间隔的SetTimer()/ KillTimer(),这不会导致WM_NCLBUTTONUP消息消失。

Footnote: If you have called SetCapture() and not yet called ReleaseCapture() when you expect the WM_NCLBUTTONDOWN message to come in, it won't arrive even with the above change. This can be irritating since it's normal to capture the mouse during interaction with such custom buttons so that you can cancel the click/highlight if the mouse leaves the window. However, as an alternative to using capture, you might consider SetTimer()/KillTimer() with a short (eg. 100 ms) interval, which won't cause WM_NCLBUTTONUP messages to vanish.

这篇关于当窗口未最大化时,缺少WM_NCLBUTTONUP消息的奇怪问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆