Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi FormClose erzeugt Exception - Washalb? (https://www.delphipraxis.net/144167-formclose-erzeugt-exception-washalb.html)

Jazzman_Marburg 1. Dez 2009 18:51


FormClose erzeugt Exception - Washalb?
 
Moin, Moin,

bin gerade auf folgendes (mir unverständliches) Phänomen gestoßen:
Auf der Main-Form wird mittels CheckBox eine neue Form geöffnet bzw. geschlossen:

Delphi-Quellcode:
  IF CheckBox1.Checked    THEN Trace_Frm.Show;
  IF NOT CheckBox1.Checked THEN Trace_Frm.Close;
In dieser Trace_Frm wird auf das Ereignis Close eine Liste freigegeben (die zuvor erzeugt wurde):

Delphi-Quellcode:
procedure TTrace_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Trace_List.Free;
end;
Das Öffnen/Schliessen der Form funktioniert genau zweimal -- beim zweiten "unchecken" der CheckBox und dem Versuch die From zu schliessen wird eine Exception gefeuert: EInvalidPointer 'Ungültige Zeigeroperation'

Was stimmt mit meinem Öffnen/Schliessen Mechanismus nicht? Jemand eine Idee?

Dankeschön

Gruß
Jazzman

Medium 1. Dez 2009 19:02

Re: FormClose erzeugt Exception - Washalb?
 
Es gehört zusammen: Show/Hide und Create/Close. Show löst kein OnCreate aus, OnClose gibt aber deine Listen frei. (Eigentlich gehört Create zu Free bzw. Destroy (welches man nicht selbst aufrufen sollte), aber Close löst eben OnClose aus. Ich würde das Freigeben einfach aus dem OnClose ins OnDestroy schieben, und du kannst so weiter machen :))

Jazzman_Marburg 1. Dez 2009 19:06

Re: FormClose erzeugt Exception - Washalb?
 
Merci!

Gruß
Jazzman

thkerkmann 1. Dez 2009 20:27

Re: FormClose erzeugt Exception - Washalb?
 
Menno....

Zitat:

Delphi-Quellcode:
  IF CheckBox1.Checked    THEN Trace_Frm.Show;
  IF NOT CheckBox1.Checked THEN Trace_Frm.Close;

Es gibt doch auch noch else :wall:

Delphi-Quellcode:
IF CheckBox1.Checked THEN
   Trace_Frm.Show
ELSE
  Trace_Frm.Close;

SirThornberry 1. Dez 2009 21:04

Re: FormClose erzeugt Exception - Washalb?
 
oder gleich:
Delphi-Quellcode:
Trace_Frm.visible := Checkbox1.checked;
was in vorliegendem Fall wohl genau den gleichen Effekt haben sollte wie die bisherige Variante.
Aber das fehlende "else" hat mich auch sofort angesprungen.

sx2008 1. Dez 2009 23:30

Re: FormClose erzeugt Exception - Washalb?
 
Das hier ist dein "Todesurteil":
Delphi-Quellcode:
procedure TTrace_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Trace_List.Free;
end;
Das Objekt wird freigeben, obwohl nach .Free noch weitere Methoden aufgerufen werden (unsichtbar von der VCL).
Es hängt vom Zufall bzw. vom Stack ab, wann und wo es knallt.
Deshalb gibt es die Methode Release.
Delphi-Quellcode:
procedure TTrace_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Release; // kann gefahrlos aufgerufen werden
end;
Release wartet bis alle Windows-Botschaften verarbeitet wurden und gibt dann erst (verzögert) das Formular frei.

Medium 1. Dez 2009 23:50

Re: FormClose erzeugt Exception - Washalb?
 
Noch ein Grund es ins OnDestroy zu packen :)

Das mit dem else stach mir auch direkt ins Auge, war für das Problem jetzt aber nicht wirklich von Belang - es ist streng genommen nichtmal falsch, nur ausgesprochen unglücklich und in den eher unteren Stil-Rängen anzusiedeln.

Sir Rufo 2. Dez 2009 00:06

Re: FormClose erzeugt Exception - Washalb?
 
Zitat:

Zitat von sx2008
Das hier ist dein "Todesurteil":
Delphi-Quellcode:
procedure TTrace_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Trace_List.Free;
end;
Das Objekt wird freigeben, obwohl nach .Free noch weitere Methoden aufgerufen werden (unsichtbar von der VCL).

:wiejetzt: Wieso sollten da noch Methoden aufgerufen werden? ... von der VCL?
Trace_List ist nicht das Formular, ansonsten hättest du da recht :mrgreen:

Der Fehler ist, dass das Object Trace_List in OnCreate erzeugt wird um im OnClose geschmissen wird.

Und beim nächsten Anzeigen des Formulars ist das Object Trace_List halt nicht da ...

Ob das Free wirklich in OnDestroy gehört hängt ja von der Logik ab ... allerdings rein logisch betrachtet gehört es da hin :mrgreen:
Ist also von daher ein Design-Fehler, das so aufzubauen.

Um ganz sicher zu gehen, kann man das Formular auch immer zur Laufzeit erzeugen, dann ist das immer ganz frisch.
Solange man mit dem Ein- Ausblenden des Formulars keine Lauflicht bauen will, ist der Performance-Verlust auch vernachlässigbar.

Zudem aast man nicht so mit dem RAM rum.

cu

Oliver

sx2008 2. Dez 2009 00:39

Re: FormClose erzeugt Exception - Washalb?
 
Zitat:

Zitat von Sir Rufo
:wiejetzt: Wieso sollten da noch Methoden aufgerufen werden? ... von der VCL?

Ja, die VCL ist noch nicht fertig mit dem Formular.
Delphi-Quellcode:
procedure TCustomForm.Close; // aus der VCL
var
  CloseAction: TCloseAction;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
    if CloseQuery then
    begin
      if FormStyle = fsMDIChild then
        if biMinimize in BorderIcons then
          CloseAction := caMinimize else
          CloseAction := caNone
      else
        CloseAction := caHide;
      DoClose(CloseAction); // hier wird das Event OnClose aufgerufen
      if CloseAction <> caNone then
        if Application.MainForm = Self then Application.Terminate // ???
        else if CloseAction = caHide then Hide // ***
        else if CloseAction = caMinimize then WindowState := wsMinimized // ***
        else Release; // ***
    end;
end;
Jede Zeile, die mit *** markiert ist greift auf das Formular Objekt zu.
Aber das Objekt ist ja schon freigeben und deshalb kann es in jeder dieser Zeilen zu einer Zugriffsverletzung kommen.
Bei der Zeile markiert mit ??? bin ich mir selbst nicht sicher, aber auch hier besteht potentiell die Gefahr,
dass über verschlungene Wege auf das (freigebene) Formular Objekt zugegriffen wird.

Stevie 2. Dez 2009 06:32

Re: FormClose erzeugt Exception - Washalb?
 
Zitat:

Zitat von Sir Rufo
Trace_List ist nicht das Formular, ansonsten hättest du da recht :mrgreen:

Ums nochmal zu betonen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:52 Uhr.
Seite 1 von 2  1 2      

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