windows 使非客户区无效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2819937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:27:06  来源:igfitidea点击:

Invalidating non-client areas

c++windowsgdi

提问by Ismael

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.

我有一个具有自定义边框/标题的窗口,为了做到这一点,我处理 WM_NCPAINT 消息。我的标题有两种背景,一种较亮的用于活动窗口,一种较暗的用于背景窗口。

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?

到目前为止,我已经处理了 WM_NCACTIVATE,并发送了一个 RedrawWindow(hwnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE),但这会导致整个窗口重新绘制。你对此有什么建议吗?

采纳答案by Adrian McCarthy

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

覆盖非客户区总是充满危险。窗口管理器似乎对优化做了很多假设。显然可以做到,请参阅 Office,但可能需要进行大量实验。

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

只是一个想法。调用 RedrawWindow 两次,一次使非客户区无效,然后再次使客户区无效。

RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
RedrawWidnow(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.

另一个想法是在第二个或第三个参数中指定一个空的 RECT 或 HREGION。它可能不会以这种方式使客户区无效。

回答by thims

Actually, this does the trick:

实际上,这可以解决问题:

SetWindowPos(hwnd, 0, 0, 0, 0, 0,
    SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER);