Is it possible to show the countdown of a TTimer in a Label ? Like instantly putting the variable in the Label Caption. I was thinking about how I could do, I'm trying to do a visible countdown in the Form.
Asked
Active
Viewed 1,766 times
-2
-
1A `TTimer` doesn't have a *countdown*. It has an interval, which is managed by Windows. (When the interval passes, Windows sends a `WM_TIMER` message.) If you want to implement a countdown, you'll have to track it yourself; use a small interval for the timer, decrement your counter when you receive the message, and update the label as needed. When your countdown expires, either disable the timer or reset the countdown and start over. – Ken White Nov 26 '15 at 22:24
-
1Yes it is possible to show a countdown – David Heffernan Nov 26 '15 at 22:24
2 Answers
3
As Ken White said, a TTimer doesn't have a 'countdown'. However, of course it is possible to implement a 'countdown' in your application. The following is an example of one way of doing this.
Create a new VCL application.
Add a private integer variable named
FCountto your form class.Use the following code as your form's
OnCreateevent handler:
procedure TForm1.FormCreate(Sender: TObject);
begin
FCount := 10;
Randomize;
end;
- Use the following code as your
OnPaintevent handler:
procedure TForm1.FormPaint(Sender: TObject);
var
R: TRect;
S: string;
begin
Canvas.Brush.Color := RGB(Random(127), Random(127), Random(127));
Canvas.FillRect(ClientRect);
R := ClientRect;
S := IntToStr(FCount);
Canvas.Font.Height := ClientHeight div 2;
Canvas.Font.Name := 'Segoe UI';
Canvas.Font.Color := clWhite;
Canvas.TextRect(R, S, [tfCenter, tfSingleLine, tfVerticalCenter]);
end;
- Add a
TTimerto your form, and use the following code as itsOnTimerhandler:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if FCount = 0 then
begin
Timer1.Enabled := false;
MessageBox(Handle, 'Countdown complete.', 'Countdown', MB_ICONINFORMATION);
Close;
end
else
begin
Invalidate;
dec(FCount);
end;
end;
Call the
Invalidatemethod in the form'sOnResizehandler.Run the application.
Andreas Rejbrand
- 105,602
- 8
- 282
- 384
1
Let's grab the FCount variable and keep the things simple.
Here the timer stops itself when the count reaches 0.
procedure TForm1.FormCreate(Sender: TObject);
begin
FCount := 10;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
label1.Caption := IntToStr(FCount);
Dec(FCount);
if FCount < 0 then begin
FCount := 10;
Timer2.Enabled := False;
end;
end;
The following uses an approach based on the TThread class which avoids to grab the FCount variable from the Andreas Rejbrand's answer
procedure TForm1.Button1Click(Sender: TObject);
begin
TThread.CreateAnonymousThread(procedure
var
countFrom, countTo: Integer;
evt: TEvent;
begin
countFrom := 10;
countTo := 0;
evt := TEvent.Create(nil, False, False, '');
try
while countTo <= countFrom do begin
TThread.Synchronize(procedure
begin
label1.Caption := IntToStr(countFrom);
end);
evt.WaitFor(1000);
Dec(countFrom);
end;
finally
evt.Free;
end;
end).Start;
end;
Community
- 1
- 1
fantaghirocco
- 4,761
- 6
- 38
- 48
-
1In the thread solution, there is a need to synch with the VCL thread when updating the label. – Christian Holm Jørgensen Nov 27 '15 at 17:15
-
@ChristianHolmJørgensen Thank you, I forgot about that. You're absolutely right – fantaghirocco Nov 27 '15 at 18:03