Below is part of the code for a 'progress' form.
Apart from ProgressBars (removed from code) it has a TLabel (LblDots) of which I want to change the caption (number of dots increasing).
In the FormShow/FormClose the TDotterThread gets created and destroyed.
Problem:
I see the Synchronize(DoUpdate) procedure that updates the label only being called when the program is not doing heavy work.
This is the progress form:
unit FrmBusy;
interface
uses
System.SyncObjs, Windows, Messages, SysUtils, System.Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TUpdateEvent = procedure of object; // 'of object' to prevent 'Incompatible types: regular procedure and method pointer'
type
TDotterThread = class(TThread) // Thread to update LblDots
private
FTick: TEvent;
FUpdater: TUpdateEvent;
protected
procedure Execute; override;
procedure DoUpdate;
public
constructor Create;
destructor Destroy; override;
property Updater: TUpdateEvent read FUpdater write FUpdater;
procedure Stop;
end;
type
TFormBusy = class(TForm)
LblDots: TLabel;
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
FShowDots: Boolean;
FDotterThread: TDotterThread;
procedure UpdateDots;
public
property ShowDots: Boolean write FShowDots;
end;
implementation
{$R *.DFM}
procedure TFormBusy.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if FShowDots then FDotterThread.Stop; // Calls Terminate and is FreeOnTerminate
end;
procedure TFormBezig.UpdateDots;
var s: String;
begin
s := LblDots.Caption;
if Length(s) = 50 then s := '' else s := s + '.';
LblDots.Caption := s;
Application.ProcessMessages;
end;
procedure TFormBusy.FormShow(Sender: TObject);
begin
LblDots.Caption := '';
if FShowDots then
begin
FDotterThread := TDotterThread.Create;
FDotterThread.Updater := Self.UpdateDots;
FDotterThread.Start;
end;
BringWindowToTop(Self.Handle);
end;
{ TDotterThread }
constructor TDotterThread.Create;
begin
FTick := TEvent.Create(nil, True, False, '');
FreeOnTerminate := true;
inherited Create(true); // Suspended
end;
destructor TDotterThread.Destroy;
begin
FTick.Free;
inherited;
end;
procedure TDotterThread.DoUpdate;
begin
if Assigned(FUpdater) then FUpdater;
end;
procedure TDotterThread.Execute;
begin
while not Terminated do
begin
FTick.WaitFor(1000);
Synchronize(DoUpdate);
end;
end;
procedure TDotterThread.Stop;
begin
Terminate;
FTick.SetEvent;
end;
end.
The form is called and created like:
procedure TFrmTest.FormCreate(Sender: TObject);
begin
FFormBusy := TFormBusy.Create(nil);
end;
procedure TFrmTest.FormDestroy(Sender: TObject);
begin
FFormBusy.Free;
end;
procedure TFrmTest.BtnCompareClick(Sender: TObject);
begin
FrmTest.FFormBusy.ShowDots := true;
FrmTest.FFormBusy.Show;
FrmTest.FFormBusy.Update label/progress bar
DoHeavyWork1();
FrmTest.FFormBusy.Update label/progress bar
DoHeavyWork2();
etc.
end;
What am I doing wrong?
TIA