procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin CanClose := LHowManyThreadRunning = 0; end;
procedure TMainForm.FormDestroy(Sender: TObject); begin MyDestroyForms; end;
procedure TMainForm.Btn_Try_Close_All_Form_ShowingClick(Sender: TObject); begin for var F in LArrForms do if (F <> nil) then F.Close; // LTop := 0; LLeft := 0; end;
initialization
ReportMemoryLeaksOnShutdown := true;
end.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
type TFormWithThread = class(TForm) Btn_RunThread: TButton; MyAnimation: TActivityIndicator; Memo1: TMemo; Label1: TLabel; procedure Btn_RunThreadClick(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); private LArrThreads: TArray<TMyThread>; // procedure MyUpdateButtonCaption(const AValue: string); function MyCanClose: Boolean; public { Public declarations } end;
var FormWithThread: TFormWithThread;
implementation
{$R *.dfm}
uses uFormMain;
function TFormWithThread.MyCanClose: Boolean; begin result := false; // try while (Length(LArrThreads) > 0) do begin // trying kill the thread... LArrThreads[0].Terminate; LArrThreads[0].WaitFor; LArrThreads[0].Free; // // if ok, remove it from list delete(LArrThreads, 0, 1); end; except on E: Exception do Memo1.Lines.Add('ERROR: ' + E.Message); end; // LHowManyThreadRunning := Length(LArrThreads); result := LHowManyThreadRunning = 0; end;
procedure TFormWithThread.Btn_RunThreadClick(Sender: TObject); var i: integer; begin i := Length(LArrThreads); LArrThreads := LArrThreads + [TMyThread.Create(MyUpdateButtonCaption)]; // Memo1.Lines.Add(TimeToStr(now) + ' CurrentThread: ' + TThread.CurrentThread.ThreadID.ToString + ' ... App'); // LArrThreads[i].Start; // LHowManyThreadRunning := i + 1; Label1.Caption := (i + 1).ToString; // MyAnimation.StartAnimation; end;
procedure TFormWithThread.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin LHowManyThreadRunning := Length(LArrThreads); CanClose := LHowManyThreadRunning = 0; // if not CanClose then CanClose := MyCanClose; end;
procedure TMyThread.DoTerminate; begin FLThreadID := ThreadID.ToString; // if Assigned(FProc) then TThread.Queue(nil, procedure begin FProc('This is the end! FLThreadID: ' + FLThreadID + ' LCounter: ' + FLCounter.ToString); end); end;
procedure TMyThread.Execute; begin while not Terminated do begin FLThreadID := ThreadID.ToString; // if (FLCounter = 100) then break; // if Assigned(FProc) then TThread.Queue(nil, procedure begin FProc('FLThreadID: ' + FLThreadID + ' LCounter: ' + FLCounter.ToString); end); // // simulating a process... "LCounter just for test n process" FLCounter := FLCounter + 1; sleep(500); end; end;
end.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
... LHowManyThreadRunning := Length(LArrThreads); <--- not safe!!!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3