我在一个表单上有一些自定义进度条,每秒更新/刷新两次,但它们会闪烁。
TMyProgressBar = class(TCustomControl)
我从 TCustomControl
继承了控件,因为我需要 Handle
和一些 TWinControl
事件。这些控件(最多 64 个)是动态创建的,并放置在一个 ScrollBox 上。当进度更新时,我首先调用 InvalidateRect
。
所有绘画工作(一组矩形、DrawText
等——灵感来自于这里)都在内存 DC 中执行,然后通过 BitBlt
复制到控件的 DC 上。尽管如此,它仍然会闪烁,好像组件消失又重新出现。我认为这是由于背景擦除引起的。
在这份无闪烁绘图建议中,写道要按照以下方式处理 WM_ERASEBKGND
:
type
TMyProgressBar = class(TCustomControl)
procedure WMEraseBkGnd(var Message:TMessage); message WM_ERASEBKGND;
procedure TMyProgressBar.WMEraseBkGnd(var Message: TMessage);
begin
Message.Result := 1;
end;
但是在另一个组件中,由TMS (
TAdvProgressBar
),相同的消息Result
被设置为0
。现在,Windows文档指出:
如果应用程序擦除背景,则应返回非零;否则,应返回零。
我测试了两个变体(Result = 0、1),令人惊讶的是,两者都避免了闪烁问题。
那么,现在我该在Delphi代码中放置什么?什么是正确的方法?
WM_ERASEBACKGROUND
中可能需要真正完成的工作。如果您什么都不绘制,那么就不会有闪烁。 - David HeffernanTScrollBox
的示例,可以调整以解决闪烁问题:https://dev59.com/f3LYa4cB1Zd3GeqPTyLD#16569324 - J...