停止闪烁

时间:2009-12-23 18:24:46

标签: delphi

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

5 个答案:

答案 0 :(得分:21)

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

答案 1 :(得分:14)

减少动画图形操作中闪烁的一般技术称为double buffering。这个想法是你完成所有绘图到屏幕外的位图,然后当你完成渲染整个场景时,将整个位图复制到可见的显示。

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

答案 2 :(得分:5)

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

但是,如果您每次绘制时都填充整个组件区域,则可能需要选择其他方法。如果将ControlStyle设置为csOpaque,则可以避免让组件擦除背景,从而消除闪烁的来源,而无需双倍缓冲。这当然要求您在整个组件区域上绘图,因此解决方案只适用于您。

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

答案 3 :(得分:4)

双缓冲上的简单代码示例。

创建缓冲区(TBitmap)

在Buffer画布上绘制。

在画布上绘制位图。例如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;

答案 4 :(得分:0)

就我而言,上述解决方案均无效。我有两个图形彼此重叠。更改DoubleBuffered属性可以解决闪烁问题,但是背景图形无法正确呈现。

经过一番细致的研究,我发现了第https://delphi-bar.blogspot.com/2012/11/prevent-screen-refresh-and-flickering.html页上描述的两个替代修复程序。

LockWindowUpdate(Handle);
try
  // Code goes here
finally
  LockWindowUpdate(0);
end;

如示例here所述,它并不总是推荐的方法。就我而言,第二个选项几乎完全解决了闪烁问题:

SendMessage(Handle, WM_SETREDRAW, WPARAM(False), 0);
try
  // Code goes here
finally
  SendMessage(Handle, WM_SETREDRAW, WPARAM(True), 0);
  RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
end;