It's still not perfect... How about this?
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TMyThread }
TMyThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: boolean);
destructor Destroy; override;
end;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
private
{ private declarations }
T: TMyThread;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
T := TMyThread.Create(False); // If you don't start it suspended, no need to call Start
//T.Start;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
FreeAndNil(T); // This is good because of no FreeOnTerminate
// But it could be moved to onDestroy rather, or right after T.WaitFor; for clarity
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean);
begin
if t <> nil then begin
T.Terminate;
T.WaitFor; // Wait for thread to close
end;
//CanClose:=True; // Actually this is true by default already...
end;
{$R *.lfm}
{ TMyThread }
procedure TMyThread.Execute;
begin
repeat
Sleep(60);
until Terminated;
end;
constructor TMyThread.Create(CreateSuspended: boolean);
begin
FreeOnTerminate := False; // <-- Not always a good idea to have this True
// .. because you have a case where thread could be running while app tries to exit.
inherited Create(CreateSuspended);
end;
destructor TMyThread.Destroy;
begin
inherited Destroy;
end;
end.