![]() |
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; |
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:
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...if not Assigned(TestForm) then TestForm:=TForm2.Create(self); TestForm.OnDestroy:=TestFormDestroy; TestForm.Show; ... procedure TForm1.TestFormDestroy(Sender: TObject); begin TestForm:=nil; end; Grüße |
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 |
AW: 2. Form schliessen Variable=Nil
Zitat:
|
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; |
AW: 2. Form schliessen Variable=Nil
Hallo ibp,
Zitat:
Bis bald Chemiker |
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:
Diese Funktion aktiviert das Fenster, wenn bereits vorhanden, ansonsten wird es erzeugt:
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;
Delphi-Quellcode:
Hoffe, das hilft.
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; |
AW: 2. Form schliessen Variable=Nil
@ConnorMcLeod
ich wollte keine Funktion à la FindXYZ nutzen! |
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 01:47 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 by Thomas Breitkreuz