ich mache solche dinge immer so
Delphi-Quellcode:
procedure TForm1ButtonClick(Sender: TObject);
var
Tick: Cardinal;
begin
if FInAction = 0 then
try
Inc(FInAction);
Button.Caption := 'Abbruch';
Tick := GetTickCount + 100;
while FInAction = 1 do
begin
...
if Tick >= GetTickCount then
begin
Inc(Tick, 100);
Application.ProcessMessages;
end;
end;
finally
FinAction := 0;
Button.Caption := 'Start';
end else
begin
Inc(FInAction); // ist >= 1, wir setzte FInAction auf > 1, bedeutet Abbrechen
Button.Caption := 'beende';
end;
end;
1.) FInAction: Integer wird als Field in deinem TForm deklariert. FInAction kann 3 Staties annehmen
FInAction == 0, bedeutet nichts wird aktuell berechnet und zb. Button hat die Caption == "Start"
FInAction == 1, bedeutet unsere Berechnung läuft, Button.Caption = "Abbrechen"
FinAction >= 2, bedeutet unsere Berechnung soll auf Benutzerwusch hin beendet werden
2.) FInAction macht also die Methode .ButtonClick() vor Rekursionen sicher das diese Methode nicht reentrant sein kann -> weil wir ja Application.ProcessMessages aufrufen
3.) Application.ProcessMessage wird in einem festen Intervall aufgerufen, hier alle 100 Millisekunden. Das macht deine Berechnung weitaus schneller
In deiner TForm1.OnCloseQuery() Methode solltest du nun Abfragen ob FInAction == 0 ist. Wenn ja, dann kannst du das Form schließen lassen, wenn nein dann wird FInAction inkrementiert und OnCloseQuery verhindert das Form zu schließen.
Gruß Hagen
Gruß Hagen