Einzelnen Beitrag anzeigen

IMPEGA

Registriert seit: 19. Jan 2008
Ort: Brhv
80 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Form (zur Laufzeit erstellt) richtig schliessen.

  Alt 30. Sep 2015, 13:01
Delphi-Version: 7
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 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.
unit ClassForm
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.
Angehängte Dateien
Dateityp: zip Test.zip (221,1 KB, 2x aufgerufen)
  Mit Zitat antworten Zitat