![]() |
Delphi-Version: 7
Form (zur Laufzeit erstellt) richtig schliessen.
Liste der Anhänge anzeigen (Anzahl: 1)
Hi
Vorne mal weg. Ich lerne Delphi über Probieren, Testen und Fragen stellen. Ich versuche eine Form die ich zur Laufzeit erstelle richtig schließen und aus dem Speicher entfernen. Das hier ist nur eine Vorlage, es geht hauptsächlich nur darum die neue zur Laufzeit erstellte Form aus dem Speicher zu löschen. Im Projekt werden viele Forms erstellt, die dürfen nicht Modal erstellt werden. Das ganze habe ich versucht in einer Class zu packen, wegen den Events. Nun zum Problem. Möglicherweise ist Alles OK. Ich kann es aber nicht selbst beurteilen. Für mich ist der Speicher frei wenn ich FreAndNil oder Form.Free benutze. Ich habe in der Form1 ein Button zum testen hinzugefügt. Damit kann ich es leicht erledigen. Nun komme ich zu der Frage. In der zur Laufzeit erstellten Form habe ich ein Button (EXIT) erstellt. Mit diesem Button möchte ich die Form schließen und den Speicher freigeben. Ich gehe davon aus dass in meinem Fall der destructor es erledigen soll. ich kriege aber immer eine Fehlermeldung. Im Netz habe ich einiges gefunden, das habe ich mir zusammengebastelt. Allerdings habe aber keine Ahnung ob der Speicher damit freigegeben wird. Wenn ich Debugge wird bei Exit der destructor nicht abgerufen. Wenn ich es von Form1 tue allerdings schon. Bitte ein Mal drüber schauen und Tipp geben wie es richtig geht. Bzw. beurteilen ob es korrekt ist. Ich kann die Form nicht Modal erstellen, die sollte aber beim Exit zerstört werden und der Speicher frei sein. Bitte auch die eine Frage im Quellcode beachten. //Muss ich hier einzelne Komponenten freigeben ??? // oder reicht es Form.Free ??? Unit1
Delphi-Quellcode:
unit ClassForm
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) ButtonForm_2: TButton; Memo1: TMemo; ButtonFrei: TButton; ButtonForm_3: TButton; procedure ButtonForm_2Click(Sender: TObject); procedure ButtonFreiClick(Sender: TObject); procedure ButtonForm_3Click(Sender: TObject); { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation uses ClassForm; {$R *.dfm} var Form_2 : TFormNeu; //Test. Damit ich den Speicher von Form1 freigeben kann Form_3 : TFormNeu; //Test. Damit ich den Speicher von Form1 freigeben kann procedure TForm1.ButtonForm_2Click(Sender: TObject); var Logo : string; Liste : TStringList; begin Liste := TStringList.Create; Liste.Add('Form2'); Liste.Add('Titel der Form2'); Logo := 'Logo2'; Form_2 := TFormNeu.Create(Logo,Liste); try Form_2.Erstellen; Memo1.Lines.AddStrings(Form_2.ListeAusgang); //Übernahme der Parameter von neuen Form beim Erstellen finally //... end; ButtonForm_2.Enabled := False; Liste.Free; end; procedure TForm1.ButtonForm_3Click(Sender: TObject); var Logo : string; Liste : TStringList; begin Liste := TStringList.Create; Liste.Add('Form3'); Liste.Add('Titel der Form3'); Logo := 'Logo3'; Form_3 := TFormNeu.Create(Logo,Liste); try Form_3.Erstellen; Memo1.Lines.AddStrings(Form_3.ListeAusgang); //Übernahme der Parameter von neuen Form beim Erstellen finally //... end; ButtonForm_3.Enabled := False; Liste.Free; end; procedure TForm1.ButtonFreiClick(Sender: TObject); begin FreeAndNil(Form_2); FreeAndNil(Form_3); ButtonForm_2.Enabled := True; ButtonForm_3.Enabled := True; end; end.
Delphi-Quellcode:
unit ClassForm;
interface uses Classes, SysUtils, Windows, Controls, Graphics, Forms, Dialogs, StdCtrls; type TFormNeu = class private Form : TForm; GroupBoxArt : TGroupBox; Radio1 : TRadioButton; Radio2 : TRadioButton; ButtonRadioWahl : TButton; OkButton : TButton; CancelButton : TButton; FormNeuEdit : TEdit; FormNeuLabel : TLabel; FListeEingang : TStringList; FListeAusgang : TStringList; function Aufgabe: string; virtual; procedure NeuerWert(Sender : TObject); procedure WertSenden(Sender : TObject); procedure Exit(Sender : TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); public constructor Create(Logo: String; const Liste: TStringList); destructor Destroy; override; property Erstellen : string read Aufgabe; property ListeAusgang : TStringList read FListeAusgang; end; implementation uses Unit1; constructor TFormNeu.Create(Logo: string; const Liste: TStringList); begin inherited Create; FListeAusgang := TStringList.Create; FListeEingang := TStringList.Create; FListeEingang.AddStrings(Liste); end; destructor TFormNeu.Destroy; begin inherited Destroy; FListeEingang.Free; FListeAusgang.Free; //Muss ich hier einzelne Komponenten freigeben ??? // oder reicht es Form.Free ??? Form.Free; end; function TFormNeu.Aufgabe : string; begin Form := TForm.Create(Form1); with Form do begin BorderStyle := bsDialog; Width := 350; Height := 322; Left := Form1.Left + Form1.Width; Top := Form1.Top; Caption := FListeEingang.Strings[1]; OnClose := FormClose; Show; end; GroupBoxArt := TGroupBox.Create(Form); with GroupBoxArt do begin Parent := Form; Caption := ' Wert-Wahl'; Width := 342; Height := 59; Left := 1; Top := 4; Show; end; Radio1 := TRadioButton.Create(Form); with Radio1 do begin Parent := GroupBoxArt; Checked := True; Caption := 'Wert1'; Left := 8; Top := 21; Show; end; Radio2 := TRadioButton.Create(Form); with Radio2 do begin Parent := GroupBoxArt; Checked := False; Caption := 'Wert2'; Left := 8; Top := 37; Show; end; ButtonRadioWahl := TButton.Create(Form); with ButtonRadioWahl do begin Parent := GroupBoxArt; Caption := 'Wert aktivieren'; Width := 100; Height := 18; Left := 94; Top := 37; OnClick := NeuerWert; Show; end; FormNeuLabel := TLabel.Create(Form); with FormNeuLabel do begin Width := Form.Width - 50; Height := 20; Left := 15; Top := 200; Caption := 'Label für sonstwas'; Parent := Form; end; FormNeuEdit := TEdit.Create(Form); with FormNeuEdit do begin Width := Form.Width - 50; Height := 20; Left := 15; Top := 225; Text := FListeEingang.Strings[0]; Parent := Form; //PasswordChar := '*'; end; OkButton := TButton.Create(Form); with OKButton do begin Width := 80; Height := 25; Left := FormNeuEdit.Left; Top := FormNeuEdit.Top + FormNeuEdit.Height + 10; Caption := 'OK'; Parent := Form; Default := True; OnClick := WertSenden; end; CancelButton := TButton.Create(Form); with CancelButton do begin Width := 80; Height := 25; Left := FormNeuEdit.Left + FormNeuEdit.Width - 80; Top := FormNeuEdit.Top + FormNeuEdit.Height + 10; Caption := 'EXIT'; Parent := Form; OnClick := Exit; Cancel := True; end; try try FListeAusgang.Add(FormNeuEdit.Text); //Beim Erstellen der Form gebe ich paar Parameter zurück except on E:Exception do Result := 'Fehler: ' + E.Message; end; finally //... end; end; procedure TFormNeu.NeuerWert(Sender : TObject); begin if Radio1.Checked then ShowMessage('Wert1') else ShowMessage('Wert2'); end; procedure TFormNeu.WertSenden(Sender : TObject); begin Form1.Memo1.Lines.Add(FormNeuEdit.Text); // Hiermit übergebe ich etwas an die Memo1 in Form1. end; procedure TFormNeu.Exit(Sender : TObject); begin Form1.ButtonForm_2.Enabled := True; Form1.ButtonForm_3.Enabled := True; TForm(Form).Close; {Damit schliesse ich die zur Laufzeit erstellte Form} end; procedure TFormNeu.FormClose(Sender: TObject; var Action: TCloseAction); begin inherited; Action := caFree; end; end. Testprojekt ist angehängt. |
AW: Form (zur Laufzeit erstellt) richtig schliessen.
|
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Damit die Forms den Speicher nicht zumüllen, da reicht das caFree im OnClose völlig aus. Damit das nicht vergessen wird, empfehle ich, eine Musterform zu bauen. Grundlegende Tastatur/Maus/Anzeige-Eigenschaften kann man da auch gut unterbringen. Diese Form dann als Vorlage in die Objektablage verschieben und von da ab vererben. Also nicht sagen : Neu-> Form, sondern Neu->Weitere->Form raussuchen. Richtig gemacht, dann ist zumindest das caFree schon da drin.
|
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Zitat:
|
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Zitat:
|
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Forms und deren Inhalte per Code erstellen. Oder findest du das etwa praktisch? :D
Das kann man in Delphi doch alles per Form-Designer machen und dann statt ellenlangen redundanten Spaghetticode zu schreiben, einfach die Form dort instanzieren wo man sie braucht und dann am Ende wieder freigeben. Vorallem wenn man (nach einem längeren Zeitraum) mal was ändern / verschieben / hinzufügen will, fängt man an zu suchen und zu basteln. |
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Ui... das ging schnell.
Ich danke Euch. Ich fühle mich damit bestätigt. Damit kann ich leben. In der Doku steht es wirklich schwarz auf Weiß. caFree Das Formular wird geschlossen und sein Speicher freigegeben. @nuclearping Mag ja, sein. Ich hätte aber gerne ein Erklärung wie ich es richtig machen kann. Ich erstelle unterschiedliche Anzahl an Formen. von 5 bis sagen wir 100 oder sogar mehr. Ich weiß nicht wie viele ich brauche. Die Formen sehen Optisch gleich aus, geben aber unterschiedliche Parameter zurück. Um die Formen untereinander zu unterscheiden bekommt Jede Form ein Logo. Damit weiß ich wo ich bin. Meine Methode wäre halt ein Mal eine Vorlage zu erstellen und per Parameter Logo und Namen vergeben. Alles Andere wird immer gleich erstellt. Diese Vorlage habe ich einfach gehalten um es leichter erklären zu können. Im Endeffekt werden mehrere dynamische Arrays erstellt, aus denen ich je nach Bedarf die Daten übergebe. Damit habe ich später leichtes Spiel, egal wie viele Formen ich erstellen muss. Bitte um Tipp falls es anders zu lösen geht. Ich bin für Alles offen. Jeder Tipp wird gerne gelesen. Eine Zusatzfrage: Hat schon Jemand XE10 am laufen? Gibt es Vorteile zu XE7? Ich benutze zwar die D7 würde aber eventuell auf neuere Version umsteigen wollen. Sind die Dateigrößen noch mehr gewachsen? Mich hat es wirklich gestört dass die exe manchmal 30MB groß war. Selbst im Release sind die Dateien richtig groß. |
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Zitat:
Und hierzu : Zitat:
|
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Wenn die Forms optisch gleich aussehen, also die selben Button haben und so, dann ist es doch wirklich einfacher so eine Form nur 1x zu erstellen und dann verändert man nur die Sachen, die anders sind von aussen ala
Form:=MyForm.Create(self); MyForm.Logo:=Irgendwas; |
AW: Form (zur Laufzeit erstellt) richtig schliessen.
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
In deinem Projekt, Datei -> Neu -> VCL-Formular (so heisst es zumindest hier bei mir). Kann sein, dass es in D7 nur Datei -> Neu ... gibt und du dann dort ein Fenster bekommst, wo du Reiter, usw. hast. Du erstellst eine neue Form und packst da deine Komponenten drauf und speicherst das Ganze ab und instanzierst die Form da wo du sie brauchst. Ich hab mal mein altes Delphi 6 entstaubt (*hust*) und dir ein Demo-Projekt angehangen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:26 Uhr. |
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