2009-12-23 150 views
7

我有一个用borland pascal和Delphi编写的旧程序,如果我使用Form1.Canvas.LineTo和MoveTo函数,我会得到一个闪烁的效果。任何人都可以告诉我如何摆脱闪烁?停止闪烁

感谢

回答

13

在动画图形操作减少闪烁的一般技术被称为double buffering。我们的想法是,您将全部绘制到离屏位图上,然后当完成渲染整个场景时,将整个位图复制到可见的显示。

该术语还涉及硬件支持的技术,例如将视频显示缓冲区与备用视频显示缓冲区进行交换的能力,该缓冲区用于控制台视频游戏等专用系统。

20

尝试在Form.OnCreate中将DoubleBuffered设置为true。

+12

当我还是一个年轻的小伙子,我们不得不实施双缓冲自己。双方都在雪地上! – 2009-12-23 18:32:53

+0

@Greg:OTOH这已得到Delphi VCL超过10年的支持,所以实际上没有什么动力去实现它。 +1这个答案,这是Delphi做双缓冲的方式。 – mghie 2009-12-23 19:42:18

+5

@Greg:赤脚? – HMcG 2009-12-23 22:28:06

3

虽然使用双缓冲通常是最好的解决方案,但它并不总是正确的解决方案,绝对不是最节省内存的解决方案。但是,如果您只绘制了图像的一部分,我还是会使用该解决方案,并将DoubleBuffered设置为true,如其他评论中所述。

但是,如果您在每次绘制时填充整个组件区域,则可能需要选择其他方法。如果将ControlStyle设置为csOpaque,则可以避免让组件擦除背景,从而消除闪烁源,而不必使用双缓冲区。这当然要求您在整个组件区域进行绘图,所以如果您这样做,解决方案才真正适合。

一般来说,如果内存消耗并不重要,我也会选择双缓冲,我只是想为您提供一种替代方案。 :)

4

双缓冲简单的代码示例。

创建缓冲区(TBitmap)

在缓冲区画布上绘制。

在画布上绘制位图。例如,Form1.Canvas

Buffer := TBitmap.Create; 
try 
    Buffer.Width:=Form1.Width; 
    Buffer.Height:=Form1.Height; 
    //clearBuffer 
    Buffer.Canvas.FillRect(Buffer.Canvas.ClipRect); 
    //draw Something 
    Buffer.Canvas.TextOut(0,0,'Hello World'); 
    Buffer.Canvas.Rectangle(0,1,2,3); 
    //drawBuffer on canvas 
    Form1.Canvas.Draw(0,0,Buffer); 
finally 
    Buffer.free 
end;