Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   2. Form schliessen Variable=Nil (https://www.delphipraxis.net/162425-2-form-schliessen-variable%3Dnil.html)

ibp 23. Aug 2011 10:51

AW: 2. Form schliessen Variable=Nil
 
so nun fasse ich zusammen...

Aufgabenstellung:

Aus Unit_x wird zu Laufzeit eine Form_Y aus Unit_y erzeugt. Form_Y wird nicht automatisch erzeugt. Aus unit_x kann auf die Form_Y über eine private Variable zugegriffen werden. Die Form_Y kann durch den Schließen-Button nach Bedarf beendet werden, dabei wird die Variable in Unit_x auf Nil gestzt. Unit_y kennt nicht Unit_x. Es können mehrere Instanzen von Form_y aus anderen Units erzeugt werden.

Meine Lösung:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Unit2,

...

type
  TForm1 = class(TForm)
    btnCreate: TButton;
    btnTest: TButton;
    procedure FormDestroy(Sender: TObject);
    procedure btnShowTestFormClick(Sender: TObject);
    procedure btntestClick(Sender: TObject);
  private
    { Private-Deklarationen }
    TestForm:TForm2;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

...

procedure TForm1.FormDestroy(Sender: TObject);
begin
  TestForm.free;
end;

procedure TForm1.btnShowTestFormClick(Sender: TObject);
begin
  TestForm.DoShow(@TestForm);
end;

procedure TForm1.btnTestClick(Sender: TObject);
begin
  if Assigned(TestForm) then
    ShowMessage('TestForm existiert')
  else
    ShowMessage('TestForm nicht existent')
end;
Delphi-Quellcode:
unit Unit2;

type
  TForm2 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    PCallVarAdr:^TForm;
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent; const SelfVarAdr:Pointer); overload;
    procedure DoShow(const SelfVarAdr:Pointer);
  end;

implementation

{$R *.dfm}

constructor TForm2.Create(AOwner: TComponent; const SelfVarAdr:Pointer);
begin
  inherited Create(AOwner);

  PCallVarAdr := SelfVarAdr;

  Show;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  if Assigned(PCallVarAdr) and Assigned(PCallVarAdr^) and (PCallVarAdr^=Self) then
  begin
    PCallVarAdr^:=nil;
  end;
end;

procedure TForm2.DoShow(const SelfVarAdr:Pointer);
begin
  if Assigned(TForm(SelfVarAdr^)) then
  begin
    BringToFront;
  end
  else
  begin
    TForm2.Create(nil,SelfVarAdr);
  end;
end;

Lemmy 23. Aug 2011 11:03

AW: 2. Form schliessen Variable=Nil
 
Hi,

Alternative zu deiner Zeiger-Geschichte wäre das OnDestroy-Event von Form2 auf eine Methode in Form1 umzuleiten und dort das Feld zu nillen:

Delphi-Quellcode:

  if not Assigned(TestForm) then
    TestForm:=TForm2.Create(self);
  TestForm.OnDestroy:=TestFormDestroy;
  TestForm.Show;
...
procedure TForm1.TestFormDestroy(Sender: TObject);
begin
  TestForm:=nil;
end;
Nachteil an der Geschichte wäre, wenn die OnDestroy schon durch was anderes belegt ist - hier könnte man diese Wert allerdings "zwischenspeichern" und dann im TEstFormDestroy aufrufen...

Grüße

Chemiker 23. Aug 2011 11:24

AW: 2. Form schliessen Variable=Nil
 
Hallo ibp,

nur wie willst Du das lösen, wenn Du von Form3 auf das Form2 zugreifen willst und das Form2 noch vorhanden ist?

Bis bald Chemiker

ibp 23. Aug 2011 12:06

AW: 2. Form schliessen Variable=Nil
 
Zitat:

Zitat von Chemiker (Beitrag 1118879)
nur wie willst Du das lösen, wenn Du von Form3 auf das Form2 zugreifen willst und das Form2 noch vorhanden ist?

Als eigene Instanz. Es geht nicht darum, dass mehrere units auf die gleiche Instanz zugreifen, jede bekommt dann seine eigene.

Sir Rufo 23. Aug 2011 12:18

AW: 2. Form schliessen Variable=Nil
 
Also bei der Aufgabenstellung sollte man das vielleicht so lösen:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Unit2;

type
  TForm1 = class( TForm )

  private
    PrivateForm : TForm2;
    procedure SubFormDestroy( Sender : TObject );
    procedure ErzeugeSubForm( Sender : TObject );
...

implementation

procedure TForm1.ErzeugeSubForm( Sender : TObject );
begin
  PrivateForm := TForm2.Create( Self );
  PrivateForm.OnDestroy := SubFormDestroy;
end;

procedure TForm1.SubFormDestroy( Sender : TObject );
begin
  PrivateForm := nil;
end;

Chemiker 23. Aug 2011 12:20

AW: 2. Form schliessen Variable=Nil
 
Hallo ibp,

Zitat:

Form2 darf, wenn nur einmal existieren.
dann habe ich das falsch verstanden.

Bis bald Chemiker

ConnorMcLeod 23. Aug 2011 12:23

AW: 2. Form schliessen Variable=Nil
 
Ich weiss zwar nicht mehr, wo die Idee her ist, aber bei mir funktioniert das so: das bewusste Fenster bekommt einen wohldefinierten Namen - am Besten in einer Konstanten hinterlegt.

Diese Funktion findet ein Fenster mit einem bestimmten Namen:
Delphi-Quellcode:
function FindFormByName(AFormName: string): TForm;
var
  li: integer;
begin
  Result := nil;

  for li:= 0 to Screen.FormCount-1 do
  begin
    if (Screen.Forms[li].Name = AFormName) then
    begin
      Result := Screen.Forms[li];
      break;
    end;
  end;
end;
Diese Funktion aktiviert das Fenster, wenn bereits vorhanden, ansonsten wird es erzeugt:
Delphi-Quellcode:
const
  FORMNAME = 'MeinSuperFenster';
var
  lfrm    : TMyForm; // das zu zeigende Fenster
begin
  lfrm  := TMyForm(FindFormByName(FORMNAME));
  if Assigned(lfrm) then
  begin
    lfrm.Show;
    lfrm.BringToFront;
  end
  else
  begin
    lfrm     := TMyForm.Create(Application);
    lfrm.Name := FORMNAME;
    lfrm.Show;
  end;
Hoffe, das hilft.

ibp 23. Aug 2011 12:28

AW: 2. Form schliessen Variable=Nil
 
@ConnorMcLeod

ich wollte keine Funktion à la FindXYZ nutzen!

ConnorMcLeod 28. Aug 2011 16:18

AW: 2. Form schliessen Variable=Nil
 
nächste Variante:
das zweite Fenster sendet eine userdefined message an seinen Owner (das erste Fenster) im OnDestroy und der Owner reagiert auf diese Message mit dem Nilen der Variable.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:35 Uhr.
Seite 4 von 4   « Erste     234   

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