Remus Rigo
Remus Rigo

Reputation: 1464

stop flickering

I have an old program written in borland pascal and in Delphi if I use the Form1.Canvas.LineTo and MoveTo functions I get a flickering effect. Can anyone tell me how to get rid of the flickering?

Upvotes: 11

Views: 15048

Answers (6)

Max Kleiner
Max Kleiner

Reputation: 1612

Double Buffering is one way but not always sufficient. Imagine you paint a shape at runtime, it depends on your repaint method. Forces the control to repaint its image on the screen could be crucial.

Call Repaint to force the control to repaint its image immediately. If the ControlStyle property includes csOpaque, the control paints itself directly. So double buffering plus invalidate and [csOpaque] as controlstyle could be an improvement:

var Compass: TPaintBox;
procedure TForm1ForceRepaint(Sender: TObject);
{Called when display type or compass angle changes}
begin
  compass.controlstyle:= [csOpaque];
  while heading.value<0 do heading.Value:=heading.Value+360;
  while heading.value>360 do heading.Value:=heading.Value-360;
  compass.Invalidate;
end;

double buffering with opaque

Upvotes: 1

Jacek Krawczyk
Jacek Krawczyk

Reputation: 2184

In my case, none of the above-mentioned solutions really worked. I have two graphics which are overlaying one on another. The change of the DoubleBuffered property has solved the flickering problem, but the background graphics was not correctly rendered.

After a small research, I have found two alternative fixes described on page https://delphi-bar.blogspot.com/2012/11/prevent-screen-refresh-and-flickering.html.

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

As discussed for example here, it is not always a recommended way. The second option, in my case, has fixed almost completely the flicker problem:

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;

Upvotes: 0

Matthias
Matthias

Reputation: 12259

Try to set DoubleBuffered to true in Form.OnCreate.

Upvotes: 21

r_j
r_j

Reputation: 1368

Easy code sample on the double buffering.

Create Buffer ( TBitmap )

Draw on the Buffer canvas.

Draw the bitmap on the canvas. Form1.Canvas for example.

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;

Upvotes: 5

Tommy Andersen
Tommy Andersen

Reputation: 7220

Although using double buffering is usually the best solution, it is not always the right solution, and definitely not the most memory saving solution. However if you only draw a part of the image, I'd go with that solution as well setting DoubleBuffered to true as mentioned in the other comments.

However if you fill the entire components area every time you draw anyway, you might want to choose a different approach. If you set the ControlStyle to csOpaque you'll avoid having the component erase the background, and thereby removing a source of the flickering, without having to double buffer. This of course requires you to draw on the entire component area, so the solution is only really suitable if you do.

In general however if memory consumption is of no importance, I'd go for the double buffering as well, I just wanted to supply you with an alternative. :)

Upvotes: 6

Greg Hewgill
Greg Hewgill

Reputation: 993035

A general technique for reducing flicker in animated graphics operations is called double buffering. The idea is that you do all drawing to an offscreen bitmap, then when you've finished rendering the whole scene, copy the entire bitmap to the visible display.

The term also relates to hardware-supported techniques such as the ability to exchange the whole video display buffer with an alternate one, which is used in dedicated systems like console video games.

Upvotes: 16

Related Questions