Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Flicker-free refresh 2

Status
Not open for further replies.

fatlardo

Programmer
May 7, 2007
41
GB
I'm trying to animate a part of my program, just a simple sliding effect.

My main form consists of 4 frames. I am trying to hide one by moving it (changing the left property) and using F_Main.Repaint after each step.

The only problem is, with each step all the frames flicker!

Is there any way to prevent this flicker as the form refreshes?

The code I am using is:

Code:
  //Do while pane is not fully shown / hidden
  for i :=  0 to 150 do
  begin
	  //InfoPane.Top (+/-)= 1
    F_Main.Frame_Info.Top := F_Main.Frame_Info.Top + 1;
  	//MediaLibrary.Height (+/-)= 1
    F_Main.Frame_Library.Height := F_Main.Frame_Library.Height + 1;
  	//Form.Repaint (so that the change is shown)
    F_Main.Frame_Player.BringToFront;
    F_Main.Repaint;
  //Loop
  end;
 
This is an old problem even in the DOS days. Solution: Frame flipping. You maintain a panel in memory in addition to the panel you draw on. You do all your drawing on the panel in memory and then flip it to the active frame. The flickering happens because it's actively drawing to screen and showing it for each step you do.
 
I want the effect of it doing each operation separately, thats why I have the repaint function in the first place. The code is meant to show it 'sliding' off screen.

I've done a few more tests and the problem seems to be that when the pane is moved each time, the pane turns a green colour. Possibly because it cannot redraw it immediately after it has moved the frame. When the repaint is called, it shows it as it should be. This happening 150 times seems to be what causes the flicker.

As hopeless as this is seeming to me, anyone know how to get rid of it?
 
Might be an obvious one that you've already tried, but have you set the DoubleBuffered property of the form/container to true?

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
It's worked on three out of the four frames. But they are the three that have an image and a label and thats it!!!!

The last frame has about 20 images buttons and it still flickers, even when it's not being moved!!!!!
 
Ok so I've solved my own problem in part at least!!

I was refreshing the whole form. So even if the player frame (the one with lots of buttons on it!) wasn't being moved, it was being refreshed.

I still have a problem with the flickering when I move the player however. And I'm worried that when I start to add components to my other frames, the same thing will start to happen to them.

Any ideas??

Gary
 
Alright, maybe I'm not understanding what's going on. The appearance of this issue is still what I was thinking originally. The system (video/OS/whatever) needs time to catch up with the CPU for multiple draws. So I'm guessing for the issue a simple way to duplicate it is something like this tied to two buttons?

Code:
var
  i: integer;
  FCaption: String;
begin
  randomize;
  FCaption := Form1.Caption;
  for i := 1 to 20 do
    begin
      Form1.Caption := fCaption + ' - ' + IntToStr(i);
      Button1.Top := random(Form1.Height - Button1.Height - 35) + 1;
      Button1.Left := random(Form1.Width - Button1.Width - 35) + 1;
      sleep(200);
    end;
  Form1.Caption := FCaption;
end;

Button2 moves around Button1 on the screen repeatedly. Now if I remove the sleep command (I put it there to see what was happening), the screen flickers until it finishes, and after a while, the button itself disappears. The code runs faster than how it can redraw.

The frame flipping thing was how to solve the problem in DOS. Do your drawing work, show the frame, wait.

Perhaps, waiting is the issue. I add Application.ProcessMessages; to the loop, the button now shows up each and every iteration (as far as my eye can see when I run it). For animation, you want to slow it up to make sure the end-user sees whatever the effect you are wanting to do. Therefore, the sleep function with a low MS value might be preferable for what you are doing.

Hope that helps out.
 
Success!! Thank you very much.

I think you were right, it was running too fast to keep up with and while redraw slowed it down enough to see, the fact that it had to redraw so much made it flicker.

Thanks a lot

Gary
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top