C++ 从左侧调整大小时窗口闪烁
每当我同时移动窗口和调整大小时,我的窗口似乎都在闪烁。这通常发生在从窗口左侧调整大小时 为什么会发生这种闪烁?换句话说,当您重新定位窗口时,操作系统在做什么C++ 从左侧调整大小时窗口闪烁,c++,c,winapi,C++,C,Winapi,每当我同时移动窗口和调整大小时,我的窗口似乎都在闪烁。这通常发生在从窗口左侧调整大小时 为什么会发生这种闪烁?换句话说,当您重新定位窗口时,操作系统在做什么 注意:从右侧调整大小时,我没有体验到闪烁,这意味着窗口不一定会移动其原点X和Y。在Windows下调整窗口的大小涉及操作系统和窗口处理程序(用于窗口类的结构的lpfnWndProc成员)之间发送的多条消息。您可以使用一些消息监视工具自己发现它们。VisualStudio附带的就是这样一个工具 一条有趣的消息是:在调整窗口大小期间调用此消息,
注意:从右侧调整大小时,我没有体验到闪烁,这意味着窗口不一定会移动其原点X和Y。在Windows下调整窗口的大小涉及操作系统和窗口处理程序(用于窗口类的结构的lpfnWndProc成员)之间发送的多条消息。您可以使用一些消息监视工具自己发现它们。VisualStudio附带的就是这样一个工具 一条有趣的消息是:在调整窗口大小期间调用此消息,它可以生成两个矩形(当设置WVR_VALIDRECTS标志时):源和目标,指定在新窗口位置可以“重用”旧窗口客户端区域的哪些内容。默认情况下,假定左上角是轴:
- 调整左边框或上边框的大小会导致复制旧窗口的内容以保留轴李>
- 调整右下边框的大小不会复制任何内容,因为窗口的左上角没有移动
WM\u NCCALCSIZE
WVR\u VALIDRECTS技巧仍然是防止Windows XP/Vista/7SetWindowPos
执行不必要的导致闪烁的BitBlt
的好方法
然而,微软再次这样做,在Windows 8/10上,DWM窗口管理器在传统的SetWindowPos
BitBlt
上添加了另一层BitBlt
,这可能会导致同样的问题,并且更难解决
有关不需要的BitBlt
导致闪烁的原因的解释,以及WM\u NCCALCSIZE
WVR\u VALIDRECTS
技巧的示例代码以及如何防止Windows 8/10 Aero执行相同操作的一些代码想法,请参阅:
原因是您正在移动整个窗口。Windows现在将在该特定位置重新绘制所有内容。从右侧收缩只会使其重新绘制边界。客户端区域不需要重新绘制,因为它刚刚被裁剪过。从右侧拉伸要求现在绘制未绘制的控件以及客户端区域。移动窗口需要重新绘制每个组件和客户端区域及其边界。@CantChooseServerNames我正在尝试将您所说的连接到此
SWP\u NOCOPYBITS
。但我认为它只是复制了一些信息。你用的是什么操作系统?启用主题的Windows XP(即默认情况下)不可避免地会闪烁。除Vista外,所有其他版本的Windows都正常。我还没试过Vista。回答得很好!接下来,当操作系统在从上到左调整大小时试图保留轴心时,是否会拉伸旧版本的内容?此外,操作系统似乎也在先移动,然后调整大小。你能证实吗?此外,我已经禁用了CS_HREDRAW和CS_VREDRAW,但仍然会出现闪烁。我们如何停止setPosWindow调用WM_PAINT?操作系统不会拉伸:它使用源和目标客户端区域宽度/高度中较短的一个进行复制。闪烁的另一个原因可能是由于将WNDCLASSEX::hbrBackground
初始化为有效笔刷:在您有机会在WM_PAINT中重新绘制之前,使用它清除剩余区域。具有标志SWP_NOREDRAW
,该标志应防止生成WM_PAINT和相关重绘消息。然后需要通过调用invalidate
或直接绘制到窗口(带有或类似)来确保视图的一致性。