双缓冲winAPI

Ale*_*rty 5 c++ winapi double-buffering

好的,所以在我的应用程序中,有一堆winAPI和一些自定义控件.好极了...

现在,通常情况下,他们会悄悄地重新绘制自己的动画,状态改变等等......一切正常.

但我有一个类Window的方法,名为fix().只要整个窗口需要更新,就会调用此方法.它调整控件的大小并使窗口无效.

当发生这种情况时,绘制背景,然后绘制标签控件,然后绘制所有其他顶部.这会导致非常恼人的闪烁,特别是在调整窗口大小时(因为不断调用fix()).

我尝试过的:

  • WS_EX_COMPOSITED.这只会对各个控件进行双重缓冲.它是一种改进,但闪烁不可避免地仍然存在.
  • 关闭背景图.几乎没有解决问题,实际上使事情变得更糟.

所以:我需要一个技术/方法/任何允许我完全双重缓冲窗口.我认为自己处理WM_PAINT消息可能是一个解决方案,但我不知道从哪里开始.我有一种可怕的感觉,这甚至都不可能......

请帮忙,这是一个关键问题.当这个愚蠢的小问题得到解决时,我会非常放心.

Chr*_*cke 5

正是在这个时候,人们意识到了微软对本地开发人员的无视。实际上,人们可能会开始幻想到,微软故意破坏了本地绘画,以迫使本地开发人员转向WPF。

首先,考虑WS_EX_COMPOSITEDWS_EX_COMPOSITED似乎是芥末酱:-它说它强制执行一个botton以便为子控件添加最高绘画顺序,并且基本上是批量处理WM_PAINT消息。它说它是在Windows 2000(5.0)中添加的,并且只有几行,它在启用桌面合成的情况下不起作用。即从Windows Vista(6.0)开始,它将停止工作,除非关闭了航空玻璃,然后由谁来做?

然后,有两种可能的“ hacks”尝试使无闪烁的绘画起作用:

  • 首先,您需要最小化过量绘画的数量。WS_EX_CLIPCHILDREN | WS_EX_CLIPSIBLINGS必须确保窗口​​的任何特定区域只绘制一次。BeginDeferWindowPos还需要批处理调整大小的操作,以确保不会发生瞬态-在一个窗口与另一个窗口重叠的情况下(即,当窗口A调整大小而窗口B没有调整大小)。

当然,当您尝试绘制带皮肤的对话框或使用“组”框,选项卡控件或任何其他限制时,这WS_EX_CLIPSIBLINGS是不合适的。

  • WM_SETREDRAW是一条神奇的讯息。没有API可以访问此功能:WM_SETREDRAWDefWindowProc直接对其进行处理,以在实质上将窗口标记为隐藏。后WM_SETREDRAW, FALSE发送,使用父窗口的句柄(及其所有子)将返回一个DC,将不会在屏幕上绘制到的GetDC / GetDCEx / GetWindowDC等电话。发送完成后,您就可以对子窗口执行各种操作WM_SETREDRAW,TRUE,(然后手动重新绘制窗口)。当然,所有子窗口都将在自己的时间内绘制,并且在父窗口完成其擦除背景后,因此WM_SETREDRAW并不是万灵药。

断开后WS_EX_COMPOSITED,在.NET的WinForms和WPF中,从头开始重新编写控件,以不使用本机控件,因此它们可以在其中烘焙缓冲绘画。还有Alpha支持。