A few notes.
Don't use TThread.Start and TThread.Resume. They are deprecated.
The effect of this method is currently the same as calling TThread.Resume after creating a thread in a suspended state. This method was added for Delphi-compatibility, where it was introduced after TThread.Suspend and TThread.Resume were deprecated.
https://www.freepascal.org/docs-html/rtl/classes/tthread.start.htmlhttps://www.freepascal.org/docs-html/rtl/classes/tthread.resume.htmlYou are using Resume for the StartAgain. That's not going to work. Even if Resume works... you didn't suspend the thread. When pressing Stop, the thread is ended... period. The Execute is exited. So there is no way to resume it.
Why are you using a global variable MyThreadAbort to abort the thread. Don't do that. Use Terminate. In that case the variable TThread.Terminated is set and the while loop will end. You can also check TThread.Terminated yourself so you also don't need that fAbortConfirmed. So remove fAbort and fAbortConfirmed from the thread entirely. You can probably remove that fActive too.
Why did you comment out the MyThread.free line in btnStopClick?
If you stop the thread you should use MyThread.WaitFor; followed by MyThread.Free; to completely free the MyThread. You can then create the thread again in btnStartAgainClick.
I would even FreeAndNil the thread so you can use Assigned() to check that you don't press that button twice.
So you only need btnStartClick() and btnStopClick().
procedure TForm1.btnStartClick(Sender: TObject);
begin
if Assigned(MyThread) then
begin
ShowMessage('Thread is already running');
exit;
end;
MyThread := TMyThread.Create(True);
MyThread.OnShowStatus := @ShowStatus;
MyThread.OnCheckActiv := @CheckActiv; //wichtig... aktiviert diesen Event
MyThread.OnCheckAbortConfirmed := @CheckAbortConfirmed;
//wichtig... aktiviert diesen Event
MyThread.Start;
end;
procedure TForm1.btnStopClick(Sender: TObject);
begin
if not Assigned(MyThread) then
begin
ShowMessage('Thread was NOT running');
exit;
end;
MyThread.Terminate;
MyThread.WaitFor;
MyThread.Free;
MyThread := nil;
end;
procedure TForm1.btnDestroyClick(Sender: TObject);
begin
if Assigned(MyThread) then
begin
MyThread.Terminate;
MyThread.WaitFor;
MyThread.Free;
MyThread := nil;
end;
end;
And instead, you might want to put the code from btnDestroyClick in TForm1.Destroy in case the application is closed without stopping the thread.