I'm using this code to show a for开发者_如何学Pythonm with a messenger-like popup:
TimeSleep := 5;
for i := 1 to FormHeight do
begin
Form.Top := Form.Top - 1;
Sleep(TimeSleep);
end
It's working smoothly but only from the second time. I mean I have a button on my form that invokes the loop and the first time I click the form shows suddenly without the sliding effect. If I click again, the effect works.
How can I have it working from the first time?
Thanks.
You are not posting enough code to be sure about it, but I assume that your form isn't visible or doesn't even have a window handle before you click the button the first time, so the moving of the form isn't visible. If you insert
Form.Show;
Form.Update;
before the loop things should work the first time too. Note the call to Update()
, it is needed to really show the form that has been made visible in the previous line.
Similarly you should insert a call to Update()
after the change to the Top
property inside your loop - it does what the call to Application.ProcessMessages()
does too, without being such a sledgehammer. Try to make do without Application.ProcessMessages()
whenever there is a better way, search Stack Overflow for discussions regarding this.
Two more pieces of advice regarding your loop:
Movement will not be smooth if anything causes your
Sleep()
to be longer than the 5 milliseconds you request - it's much better to calculate the amount to decrement the top coordinate of the form from the elapsed time since the last movement.There is no way anybody will see your form move in 1 pixel increments - the human eye and brain aren't fast enough to gather and process information at that speed, and even cats and insects in your room will only see the 60 or so updates your monitor does in each second. So a parameter to
Sleep()
of 20 or even 50 is much more sensible than 5. Adjust the form movement accordingly.
Edit:
Here is some sample code that creates constant movement of the form even with differing delays:
uses
MMSystem;
procedure TForm1.Button1Click(Sender: TObject);
var
Frm: TForm;
TicksStart, TicksNow: Longword;
Progress: Single;
begin
Frm := TForm.CreateNew(Self);
try
// slide a form of 600 by 500 pixel into view over a period of 100 millis
Frm.SetBounds((Screen.Width - 600) div 2, -500, 600, 500);
Frm.Show;
TicksStart := timeGetTime;
while True do begin
Sleep(15);
TicksNow := timeGetTime;
if TicksNow - TicksStart >= 1000 then
break;
Progress := (TicksNow - TicksStart) / 1000;
Frm.Top := - Round((1.0 - Progress) * 500);
end;
Frm.Top := 0;
Sleep(500);
finally
Frm.Free;
end;
end;
Try adding "Application.ProcessMessages;" before sleep.
精彩评论