The curious problem of missing WM_NCLBUTTONUP message when the window is not maximized

I have a window in which I process WM_NCLBUTTONUP messages to handle clicks on custom buttons in the title bar. This works fine when the window is maximized, but when it is not, the WM_NCLBUTTONUP message never arrives! However, I get a WM_NCLBUTTONDOWN message. Strange WM_NCLBUTTONUP arrives if I click to the right of the menu bar, but anywhere along the title bar / window, the message never arrives.

After some debugging time, I found that if I set a breakpoint on CMainFrame :: OnNcLButtonDown (), clicked the title bar, but while holding the mouse button down, let the debugger break the function, press F5 to continue debugging, then release the mouse button - it magically goes WM_NCLBUTTONUP!

My question is twofold, (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 problem (fast Google shows many other people with the same problem, but without a solution).

Edit
Thanks for the first two answers, I tried calling ReleaseCapture on NCLButtonDown, but it has no effect (it actually returns NULL, indicating that there is no capture). I can only assume that the functionality of the base class (def window proc) can set the capture. I will explore on Monday ...

+5
source share
4 answers

I had the same problem. The problem is that left-clicking on the window title causes a drag and drop, and thus mouse capture, which prevents the arrival of WM_NCLBUTTONUP.

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);
}

, , , Windows, , , , (HTBORDER).

: SetCapture() ReleaseCapture(), , WM_NCLBUTTONDOWN , . , , /, . SetTimer()/KillTimer() (, 100 ), WM_NCLBUTTONUP.

+4

- , , , . , - .

Spy ++ , , .

, - , . , , .

+2

To add Franci Penov to the answer , clicking on the title bar is interpreted as the start of a drag and drop to move the window. A window grabs the mouse to perform a drag and drop. Since the maximum window cannot be dragged, the capture is skipped and the message usually goes.

+1
source

enable ReleaseCapture () in WM_NCLBUTTONDOWN {code block}

+1
source

All Articles