当绘制包含具有每像素 Alpha 通道的位图的子控件时,每当需要重绘它们时,我们就会得到相当多的闪烁。实际的混合工作正常。我找到了很多关于减少闪烁的信息(例如这个问题或这个网站),但我似乎找不到任何特别适用于这种情况的信息。
例如,我有一个带有几个不同位图的按钮,这些位图根据按钮的状态进行了 alpha 混合和 blitted 到窗口。当它们的状态发生变化并且我需要绘制不同的位图时,我需要先重新绘制背景,否则它会与前一个状态位图留下的像素混合。这是我得到一些闪烁的地方,我偶尔会得到一些背景撕裂。
让顶级父窗口绘制位图背景而不是纯色,以及让子控件重叠的可能性使问题变得更加复杂;只是将基础颜色乘以孩子的位图是不可能的,就像使用WS_CLIPCHILDREN
.
由于窗口有位图背景,我将返回true
,WM_ERASEBKGND
以避免绘制将被覆盖的颜色。
当然,双缓冲似乎可以解决所有这些问题,但我无法让它正常工作。我已经WS_COMPOSITED
为顶级窗口和WS_TRANSPARENT
子窗口设置了。当需要使用新位图重绘子窗口时,我遇到了一些问题(很可能是我不理解在这种情况下绘制顺序是如何工作的):
- 如果我调用
InvalidateRect()
并传递子句柄,子窗口确实被重绘,但背景没有被重绘,因此像素相互叠加,混合在一起。 - 如果我调用
InvalidateRect()
并传入父句柄,矩形由子窗口的尺寸组成,则背景会被重绘,但子窗口不会。 - 如果我同时执行上述两项操作,那么背景和子窗口都会被重绘,它看起来完全符合我的要求——除了这样做,我设法让它再次闪烁(这不是这并不令人惊讶,因为这样调用两次似乎非常骇人听闻
InvalidateRect()
,因为我猜每次调用都可能导致缓冲区翻转,这违背了目的)。
我得出的结论是,我真的不明白我需要如何修改我的程序来处理双缓冲,或者双缓冲是否有助于解决这种情况。我觉得它肯定会,但我不太明白我需要如何修改东西才能让所有东西再次正常播放。