我有一个用borland pascal和Delphi编写的旧程序,如果我使用Form1.Canvas.LineTo和MoveTo函数,我会得到一个闪烁的效果。谁能告诉我如何摆脱闪烁?
答案 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;