Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Stack-Überlauf (https://www.delphipraxis.net/158967-stack-ueberlauf.html)

Array 9. Mär 2011 17:02

Stack-Überlauf
 
Hallo Leute!

Hab folgenden Code:

Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Gespeichert = 'Ja' then begin
   Close;
end else begin
if (MessageDlg('Sie haben nicht gespeichern! Wollen Sie vor dem Beenden speichern?', mtWarning, [mbYes, mbNo], 0) = mrYes) then begin
bt_save.click;
close;
end;
if (MessageDlg('Sie haben nicht gespeichern! Wollen Sie vor dem Beenden speichern?', mtWarning, [mbYes, mbNo], 0) = mrNo) then begin
close;
end;
end;
end;
Immer wenn er aus geführt wird kommt ein Stack-Überlauf!

Worauf ist das zurückzuführen?

Danke im Voraus!

Liebe Grüße

Array :)

BUG 9. Mär 2011 17:16

AW: Stack-Überlauf
 
Wird wohl an den close liegen.
Kommentiere es mal aus und probiere was passiert.

Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if Gespeichert = 'Ja' then
   begin
      //close;
   end else begin
      if (MessageDlg('Sie haben nicht gespeichern! Wollen Sie vor dem Beenden speichern?', mtWarning, [mbYes, mbNo], 0) = mrYes) then
      begin
         bt_save.click;
         //close;
      end;
      if (MessageDlg('Sie haben nicht gespeichern! Wollen Sie vor dem Beenden speichern?', mtWarning, [mbYes, mbNo], 0) = mrNo) then
      begin
         //close;
      end;
   end;
end;

hans ditter 9. Mär 2011 17:23

AW: Stack-Überlauf
 
Mal eine andere Anmerkung... ist da nicht eine MessageDlg zu viel? Wenn die erste nicht Ok gedrückt wird, dann wird doch einfach geschlossen, oder nicht? Ansonsten würde ja auch ein einfacher else-Zweig reichen.
Weil so wird ja zweimal eine MessageDlg aufgerufen... vlt führt das auch zum Überlauf?

LG; hans ditter

Array 9. Mär 2011 17:26

AW: Stack-Überlauf
 
Hans:

Ja, hast Recht - hab vergessen das raus zu tun - hab ein wenig herum probiert um den Stackfehler wegzubekommen...

BUG:

Auch du hast Recht - es lag an den Close - die braucht man gar nicht...

Danke!

Helmi 9. Mär 2011 17:26

AW: Stack-Überlauf
 
Hallo,

ein close im Ereignis OnClose ruft wiederrum OnClose auf. Da da aber ein close drin ist, wiederholt sich das ständig, bis der Stack (über-)voll ist.

Solche Abfragen sollten in OnCloseQuery rein.

Beispiel:
Delphi-Quellcode:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  //Beenden erlauben/verweigern
  CanClose := (Gespeichert = 'Ja') or (MessageDlg('Sie haben nicht gespeichern! Wollen Sie vor dem Beenden speichern?', mtWarning, [mbYes, mbNo], 0) = mrYes);
end;
CanClose = true sagt, dass die Anwendung geschlossen werden kann.

Bei Abfrage auf mrYes wird CanClose true wenn der Bediener auf "Ja" klickt. Klickt er auf "Nein" dann ist CanClose false und es wird nicht geschlossen.

Der Code zum Speichern dann in das OnClose. Dies wird nur aufgerufen, wenn das CanClose in OnCloseQuery auf true gesetzt wurde.

Das würde dann so aussehen:

Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //Button "sichern" anklicken
  bt_save.click;
end;
[Edit]
Die Abfrage auf gespeichert ebenfalls in das OnCloseQuery gelegt. Dadurch kommt keine Meldung wenn
Delphi-Quellcode:
Gespeichert = 'Ja'
ist.

alfold 9. Mär 2011 17:28

AW: Stack-Überlauf
 
Erstens das, und zweitens kommt er aus seiner close nie raus so wie es jetzt da steht!

Besser ist die Abfrage auch im onCloseQuery zu machen und dann CanClose je nach Bedingung zu setzen!

mist zu langsam:wink:

Gruss alfold

Helmi 9. Mär 2011 17:31

AW: Stack-Überlauf
 
Zitat:

Zitat von alfold (Beitrag 1087074)
mist zu langsam:wink:

[OT] HaHa! :-)[/OT]

himitsu 9. Mär 2011 21:47

AW: Stack-Überlauf
 
ich will auch noch :tongue:

Sagen wir es mal anders, oder man schaue mal in die OH.
Delphi-Referenz durchsuchenTForm.OnClose Delphi-Referenz durchsuchenTForm.OnCloseQuery



OnClose wird aufgerufen, wenn die Form endgültig geschlossen wird

OnCloseQuery wird davor aufgerufen, bevor überhaupt feststeht ob wirklich geschlossen werden soll



PS: hat sich mal jemand den Action-Parameter angesehn?
Vorallem das caMinimize (Delphi-Referenz durchsuchenTCloseAction) ... ich glaub da kann shnell mal was passieren, was ihr eigentlich nicht wollt :stupid:

BUG 9. Mär 2011 21:55

AW: Stack-Überlauf
 
Allgemein sollte man bei Stacküberläufen gucken, ob man rekursiver programmiert hat als man vorhatte :lol:

himitsu 9. Mär 2011 22:26

AW: Stack-Überlauf
 
Zitat:

Zitat von BUG (Beitrag 1087166)
Allgemein sollte man bei Stacküberläufen gucken, ob man rekursiver programmiert hat als man vorhatte :lol:

Das ist zwar oftmals wirklich der Grund, aaaaaaaber

Delphi-Quellcode:
procedure TForm5.FormCreate(Sender: TObject);
var
  a: array[0..12345678] of Byte;
begin
  if a[0] = 0 then
    // nix (keine Lust)
end;
Und nun such mal den rekursiven Aufruf :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:30 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz