Form schliessen und zerstören

Rund um die LCL und andere Komponenten
Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2256
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.8, FPC 3.0.4)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Form schliessen und zerstören

Beitrag von m.fuchs »

Genau, falls man mehrere Forms auf diese Weise behandeln lässt, ist das ein guter Anfang. Man würde dann natürlich eine Liste mit den Subforms haben und diese durch-iterieren um das richtige zu finden.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 4856
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form schliessen und zerstören

Beitrag von Mathias »

Momentan stehe ich vor dem nächsten Problem.
Innerhalb einer FormClasse funktioniert dies super.
Nur wie bewerkstellige die in einer normalen Procedure ?

Code: Alles auswählen

procedure RegisterSerialMonitor(Sender: TObject);
begin
  if not Assigned(Serial_Monitor_Form) then begin
    Serial_Monitor_Form := TSerial_Monitor_Form.Create(nil);
    Serial_Monitor_Form.OnClose:=;  // Was kommt hier ?
  end;

  Serial_Monitor_Form.Show;
end;  
Die Register Procedure in der Package:

Code: Alles auswählen

procedure Register;
begin
....
  RegisterIdeMenuCommand(mnuProject, 'Serial-Monitor', 'Serial-Monitor...', nil, @RegisterSerialMonitor);
end; 
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2256
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.8, FPC 3.0.4)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Form schliessen und zerstören

Beitrag von m.fuchs »

Das geht so nicht, die FormClose-Procedure muss immer eine Methode einer Klasse sein. Du kannst ja die "normale" Prozedur objektorientiert umbauen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 4856
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form schliessen und zerstören

Beitrag von Mathias »

Habe ich schon probiert, dann will aber "RegisterIdeMenuCommand" nicht mitmachen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 3252
Registriert: Fr 8. Apr 2011, 09:01

Re: Form schliessen und zerstören

Beitrag von wp_xyz »

Was muss denn das OnClose machen? Vielleicht brauchst das Event ja auch gar nicht und kannst alles in den Destructor packen - man denkt manchmal zu viel nur immer in dieselbe Richtung. Wenn es, wie in den Beispielen oben, nur um die Variable Serial_Monitor_Form geht, die nach dem Zerstören auf nil gesetzt werden muss, kannst du dies vielleicht auch direkt von der Klasse im Destructor machen lassen. Dann darf es natürlich die Instanz natürlich nur 1x geben, und du müsstest beim Registrieren sicherstellen, dass eine bereits existierende Instanz des Formulars vorher zerstört wird oder die Registrierung eines weiteren Formulars verhindert wird.

Mathias
Beiträge: 4856
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form schliessen und zerstören

Beitrag von Mathias »

Ich hab mich etschieden, das Form nicht mehr zu zerstören, es reicht es nur zu verstecken. Ich unterbreche dan den Timer umd mache den Comport zu.
Bei OnShow dann das Umgekehrte.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 586
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.7 FPC 3.04)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Form schliessen und zerstören

Beitrag von fliegermichl »

Mathias hat geschrieben:
Fr 1. Mai 2020, 13:21
Nachtrag, wen ich es mit einer StringList mache dann knallts:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  o: TStringList;
begin
  o := TStringList.Create;
  Caption := o.ClassName;
  o.Free;
  o.Free;  // Knall
end;      
Das müsste doch auch direkt im OnClose gehen, ähnlich wie ich es oben schon geschrieben habe:
Probiere ich mal aus. :wink:
Deswegen immer FreeAndNil. Wenn man das mit einem nil Zeiger aufruft, ist zwar Unfug, passiert aber nichts.

Mathias
Beiträge: 4856
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form schliessen und zerstören

Beitrag von Mathias »

Deswegen immer FreeAndNil. Wenn man das mit einem nil Zeiger aufruft, ist zwar Unfug, passiert aber nichts.
Was mich verwundert, wieso wurde das nicht direkt im Free implementiert ?
Ein Abfrage, ob es nil ist, wird getestet.

Code: Alles auswählen

     procedure TObject.Free;

        begin
           // the call via self avoids a warning
           if self<>nil then
             self.destroy;
        end;     
Hätte man nach dem self.destroy nicht ein

Code: Alles auswählen

self := nil
einbauen können ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 3252
Registriert: Fr 8. Apr 2011, 09:01

Re: Form schliessen und zerstören

Beitrag von wp_xyz »

FreeAndNil, ja oder nein, das ist fast eine Glaubensfrage wie Windows gegen Linux, oder Lazarus gegen CodeTyphon.

Während ich früher auch immer alles mögliche auf Nil gesetzt habe, hat mich ein Artikel von Nick Hodges (finde ich gerade nicht) nachdenklich gemacht. Denn es hilft, Probleme zu verschleiern. Wenn ich ein Objekt zerstöre und später daraufzugreife, habe ich einen Absturz. Aber wenn ich das Objekt zerstöre und die Variable auf nil setze, und beim späteren Zugriff auf Nil prüfe, läuft alles - bis vielleicht auf irgendwelche ominösen Fehler, die manchmal auftreten und schwer zu finden sind. Das köönte eine Folge des durch die Nil-Prüfung verschleierten Fehlers in der Ablauflogik sein können, nämlich dass das Programm überhaupt auf ein nicht mehr existierendes Objekt zugegriffen hat. Hätte ich das mit Nil nicht gemacht, hätte mir der Absturz sofort gesagt, da stimmt etwas nicht, ich habe das Objekt doch zerstört, und ich wäre relativ nahe an der Fehlerursache. Wegen der verschleierten Fehlermeldung kann im anderen Fall der Fehler überall sein.

Daher: FreeAndNil nur, wenn es nötig ist, also z.B. um einer anderen Routine mitzuteilen, dass das Objekt inzwischen zerstört wurde. Was im übrigen auf den hier diskutierten Anwendungsfall zutrifft

Mathias
Beiträge: 4856
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form schliessen und zerstören

Beitrag von Mathias »

. Wenn ich ein Objekt zerstöre und später daraufzugreife, habe ich einen Absturz. Aber wenn ich das Objekt zerstöre und die Variable auf nil setze, und beim späteren Zugriff auf Nil prüfe, läuft alles
Da hast du recht, man brauch mehr Disziplin.
Es gibt sogar ganz schlechte Coder, die gar nichts zerstören, sondern nur immer neu erzeugen. Aber da ist Java sicher nicht unschuldig.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2256
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.8, FPC 3.0.4)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Form schliessen und zerstören

Beitrag von m.fuchs »

Mathias hat geschrieben:
Sa 2. Mai 2020, 15:20
Deswegen immer FreeAndNil. Wenn man das mit einem nil Zeiger aufruft, ist zwar Unfug, passiert aber nichts.
Was mich verwundert, wieso wurde das nicht direkt im Free implementiert ?
Hätte man nach dem self.destroy nicht ein self := nil einbauen können?
Weil das nichts nützen würde. Self ist ja nicht das gleiche wie deine Variable die auf das Objekt zeigt. Diese Variable wiederum ist .Free nicht bekannt, könnte also auch nicht auf nil gesetzt werden.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2256
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.8, FPC 3.0.4)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Form schliessen und zerstören

Beitrag von m.fuchs »

wp_xyz hat geschrieben:
Sa 2. Mai 2020, 15:48
Während ich früher auch immer alles mögliche auf Nil gesetzt habe, hat mich ein Artikel von Nick Hodges (finde ich gerade nicht) nachdenklich gemacht. Denn es hilft, Probleme zu verschleiern. Wenn ich ein Objekt zerstöre und später daraufzugreife, habe ich einen Absturz. Aber wenn ich das Objekt zerstöre und die Variable auf nil setze, und beim späteren Zugriff auf Nil prüfe, läuft alles - bis vielleicht auf irgendwelche ominösen Fehler, die manchmal auftreten und schwer zu finden sind.
Hm, irgendwie fällt mir da nicht so wirklich ein Beispiel ein, wo das FreeAndNil so ein Problem erzeugt. Hast du zufällig eines da?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4146
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Form schliessen und zerstören

Beitrag von af0815 »

Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 3252
Registriert: Fr 8. Apr 2011, 09:01

Re: Form schliessen und zerstören

Beitrag von wp_xyz »

Genau.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 586
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.7 FPC 3.04)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Form schliessen und zerstören

Beitrag von fliegermichl »

FreeAndNil ist natürlich kein Allheilmittel.
Beispiel

Code: Alles auswählen

var a, b : TMyObject;
begin
 a := TMyObject.Create;
 b := a;
 // Jetzt zeigen sowohl a als auch b auf die neu erzeugte Instanz
 FreeAndNil(a);
 // die Instanz wurde freigegeben und a ist jetzt auch nil. b zeigt aber immer noch auf den Speicher, auf dem die Instanz früher mal war.
end;

Antworten