每当我移动窗口并同时调整大小时,我的窗口似乎都会闪烁。这通常发生在从窗口左侧进行尺寸调整时。
为什么会发生这种闪烁?换句话说,当您重新定位窗口时,操作系统在做什么?
注意:从右侧调整大小时不会出现闪烁,这意味着窗口不一定会移动其原点X和Y.
答案 0 :(得分:5)
在Windows下调整窗口大小涉及在OS和窗口处理程序之间发送的几条消息(用于WNDCLASSEX窗口类的register结构的lpfnWndProc成员)。您可以使用一些消息监视工具自己发现它们。 Visual Studio附带的Spy++就是这样一个工具。
一个有趣的消息是WM_NCCALCSIZE:在窗口大小调整期间调用此消息可以生成两个矩形(当设置了WVR_VALIDRECTS标志时):source和target指定旧窗口的客户区域的哪些内容可以“重用”在新窗口的位置。默认情况下,假设左上角是一个轴:
此默认复制可能会导致闪烁,如果它与重绘期间放置视觉效果的方式不对应。例如,从左边框或上边框调整大小后,相对于右边框或下边框显示的所有内容都会放错位置:这些对象会在调整大小后不必要地移动,留下奇怪的新旧内容,因为只有非复制的像素将被重新粉刷。如果你试着用InvalidateRect来治疗这个混乱,比如WM_SIZE,你就会得到闪烁(事情错位的时间间隔非常短但仍然存在)。
禁用此行为的最简单方法是为您的窗口设置CS_HREDRAW和CS_VREDRAW Class Styles。
答案 1 :(得分:0)
2018年更新。
WM_NCCALCSIZE
WVR_VALIDRECTS
技巧仍然是防止Windows XP / Vista / 7 SetWindowPos
做不必要的BitBlt
导致闪烁的好方法。
但是,Microsoft又做了一次,并且在Windows 8/10上,DWM窗口管理器在旧版BitBlt
SetWindowPos
的顶部添加了BitBlt
的另一层,这可能导致相同的问题并且更难解决。
有关不想要的BitBlt
导致闪烁的原因的解释,以及WM_NCCALCSIZE
WVR_VALIDRECTS
技巧的示例代码以及一些有关如何防止Windows 8/10 Aero出现的代码提示这样做,请参阅: