Search code examples
c++windowsgdi

Invalidating non-client areas


I've a window which has custom border/caption, in order to do that I handle WM_NCPAINT message. My caption has two backgrounds a brighter one for the active window, and a darker one for the background window.

But under some circumstances, for example when the window loses/gain focus, my caption is not updated so I end with the wrong background.

Until now I've handled WM_NCACTIVATE, and send a RedrawWindow(hwnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE), but this causes the whole window to repaint. Do you have any advice about this?


Solution

  • Overriding non-client area is always fraught with peril. It seems the Window manager makes a lot of assumptions for optimization. Clearly it can be done, see Office, but it might take a lot of experimentation.

    Just an idea. Call RedrawWindow twice, once to invalidate the non-client area then again to validate the client area.

    RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
    RedrawWindow(hwnd, NULL, NULL, RDW_NOFRAME | RDW_VALIDATE);
    

    Another idea is to try to paint just the frame immediately, without invalidating anything:

    RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_UPDATENOW | RDW_NOCHILDREN);
    

    Yet another idea is to specify an empty RECT or HREGION in the 2nd or 3rd parameters. It might not invalidate the client area that way.