2

当绘制包含具有每像素 Alpha 通道的位图的子控件时,每当需要重绘它们时,我们就会得到相当多的闪烁。实际的混合工作正常。我找到了很多关于减少闪烁的信息(例如这个问题这个网站),但我似乎找不到任何特别适用于这种情况的信息。

例如,我有一个带有几个不同位图的按钮,这些位图根据按钮的状态进行了 alpha 混合和 blitted 到窗口。当它们的状态发生变化并且我需要绘制不同的位图时,我需要先重新绘制背景,否则它会与前一个状态位图留下的像素混合。这是我得到一些闪烁的地方,我偶尔会得到一些背景撕裂。

让顶级父窗口绘制位图背景而不是纯色,以及让子控件重叠的可能性使问题变得更加复杂;只是将基础颜色乘以孩子的位图是不可能的,就像使用WS_CLIPCHILDREN.

由于窗口有位图背景,我将返回trueWM_ERASEBKGND以避免绘制将被覆盖的颜色。

当然,双缓冲似乎可以解决所有这些问题,但我无法让它正常工作。我已经WS_COMPOSITED为顶级窗口和WS_TRANSPARENT子窗口设置了。当需要使用新位图重绘子窗口时,我遇到了一些问题(很可能是我不理解在这种情况下绘制顺序是如何工作的):

  • 如果我调用InvalidateRect()并传递子句柄,子窗口确实被重绘,但背景没有被重绘,因此像素相互叠加,混合在一起。
  • 如果我调用InvalidateRect()并传入句柄,矩形由子窗口的尺寸组成,则背景会被重绘,但子窗口不会。
  • 如果我同时执行上述两项操作,那么背景和子窗口都会被重绘,它看起来完全符合我的要求——除了这样做,我设法让它再次闪烁(这不是这并不令人惊讶,因为这样调用两次似乎非常骇人听闻InvalidateRect(),因为我猜每次调用都可能导致缓冲区翻转,这违背了目的)。

我得出的结论是,我真的不明白我需要如何修改我的程序来处理双缓冲,或者双缓冲是否有助于解决这种情况。我觉得它肯定会,但我不太明白我需要如何修改东西才能让所有东西再次正常播放。

4

2 回答 2

2

你在使用 分层窗口吗?如果没有,也许试试看。

同样对于双缓冲考虑这种技术

于 2009-05-14T22:13:56.277 回答
1

这可能完全不合时宜——我的 gui 时代是很久很久以前的事了......

但是你不能为你的不同状态预先计算混合吗?我假设您的按钮可以启用/禁用和向上/向下,所以只有 4 种组合。为什么不预先计算组合位图?

或者问题是已经组合的位图与现有状态的交互?

于 2009-05-14T22:04:00.807 回答