Reputation: 1188
I have a few simple while loops in my program, such as a Countdown program. I also have a bitmap button for close (Doesn't require any code right?). When The countdown is in progress(while
), everything (All buttons and edits) are ignored/unable to use until the requirements are met with the loop
.
Is there a way to stop the loop before the requirements are met?
Here's my code:
while iCountDown > 0 do
begin
application.ProcessMessages;
dec(iCountDown)
lblOutput.Caption := IntToStr(iCountDown);
sleep(1000);
end;
ShowMessage ('Countdown has finished!');
Thanks.
Upvotes: 0
Views: 745
Reputation: 36654
A different solution could be a thread. Its advantages:
Sleep
Application.ProcessMessages
is not neededWhen used with synchronize
, it also can update the Label caption and other UI elements.
The code for the count-down message ('Countdown has finished!') can be executed in the OnTerminate event handler - without synchronize
as it will executed in the main thread context.
Upvotes: 1
Reputation: 612964
Declare a private field of your form like this:
FCancelLoop: Boolean;
Set the variable to False
before you start your loop. In the OnClick
event handler of your close button, set FCancelLoop
to True
. Check the value of FCancelLoop
inside the loop and break out of the loop if you find it is True
.
FCancelLoop := False;
while iCountDown > 0 do
begin
Application.ProcessMessages;
if FCancelLoop then
exit; // or perhaps break, but you get the idea
dec(iCountDown);
lblOutput.Caption := IntToStr(iCountDown);
Sleep(1000);
end;
However, this code has other problems. It uses the notorious Application.ProcessMessages
which has a tendency to make your life more complicated than you want it to be. Are your event handlers protected against re-entrancy? And the call to Sleep
on your main thread blocks that thread and makes it unresponsive. You really don't want that.
A better solution to your problem is to run your countdown loop with a timer.
Upvotes: 4