Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Frame soll sich selbst löschen (https://www.delphipraxis.net/107417-frame-soll-sich-selbst-loeschen.html)

corny2000 27. Jan 2008 14:11


Frame soll sich selbst löschen
 
Hallo,

Ich verwende Delphi 7 und habe folgenden Eintrag in der Hilfe-Datei unter der Erklärung für die prozedur "free" gefunden:

Zitat:

Warnung: Sie dürfen eine Komponente nie in einer ihrer eigenen Ereignisbehandlungsroutinen oder in einer Ereignisbehandlungsroutine eines untergeordneten Objekts freigeben. Geben Sie beispielsweise auf keinen Fall eine Schaltfläche oder ihr übergeordnetes Formular in der OnClick Ereignisbehandlungsroutine der Schaltfläche frei.
Nun, genau DIES muss ich aber für mein Projekt hinbekommen. Ich habe ein kleines Beispiel-Projekt zur Veranschaulichung erzeugt.

Ich erzeuge ein Formular mit einem Button und einem Panel:

http://web.whosting.ch/Fashionhbj/frame1.jpg

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var MyFrame: TFrame1;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not Assigned(MyFrame) then
  begin
    MyFrame := TFrame1.Create(Panel1);
    MyFrame.Parent := Panel1;
    MyFrame.Align := alClient;
  end else MyFrame.Free;
end;
Klickt man nun auf den Button, wird MyFrame erzeugt oder gelöscht. Funktioniert ganz fantastisch!


MyFrame ist vom Typ Frame1. Diese sieht folgendermaßen aus:

http://web.whosting.ch/Fashionhbj/frame0.jpg

Delphi-Quellcode:
type
  TFrame1 = class(TFrame)
    FrameButton: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

implementation

uses UTest;

{$R *.dfm}

procedure TFrame1.FrameButtonClick(Sender: TObject);
begin
  Form1.Button1.Click;
end;
Wie am Quellcode von FrameButtonClick auf TFrame1 ersichtlich, möchte ich den Frame löschen, sobald dieser Button geklickt wird.

http://web.whosting.ch/Fashionhbj/frame2.jpg


Natürlich geht das so nicht, denn folgendes geschieht:
- Ich klicke auf FrameButton in MyFrame
- Es wird Button1Click in Form1 aufgerufen
- Button1.Click in Form1 sorgt dafür, dass der Frame zerstört wird
- Nach Beenden von Button1Click in Form1 kehrt das Programm in FrameButtonClick auf MyFrame zurück - oh hoppla, MyFrame wurde doch schon gelöscht - Adressfehler, Programmabsturz.


Was also EIGENTLICH in FrameButtonClick stehen müsste wäre so etwas wie:
1. sobald dieser Frame freigegeben wurde, führe Button1Click auf Frame1 aus

-> Es gibt ein Kommando ".Release" was wohl genau das macht. Dummerweise gibt es das nicht für Frames.
-> Bei TForm geht das, einfach Self.Close

Hat einer ne Idee, wie man das Programm austricksen kann, damit ich mit dem Button auf den Frame den Frame löschen kann?

Bernhard Geyer 27. Jan 2008 16:44

Re: Frame soll sich selbst löschen
 
Zitat:

Zitat von corny2000
Es gibt ein Kommando ".Release" was wohl genau das macht. Dummerweise gibt es das nicht für Frames.
-> Bei TForm geht das, einfach Self.Close

Hat einer ne Idee, wie man das Programm austricksen kann, damit ich mit dem Button auf den Frame den Frame löschen kann?

Du mußt den gleichen Trick machen wie dort. Einfach ein weiteres Event definieren (UM_FREEFRAME = WM_USER + 101) und dieses Auslösen und beim Eintreffen diese (procedure UMFREEFRAME(Msg: TMessage) message UM_FREEFRAME) das Frame freigeben.

corny2000 27. Jan 2008 19:48

Re: Frame soll sich selbst löschen
 
Hallo,

Danke für die Antwort!


Leider ist mein Problem damit nur zur Hälfte gelöst.

Diese Zeile schickt die Message an meine Form:
Delphi-Quellcode:
PostMessage(Form1.Handle, UM_FREEFRAME, 0, 0);
Jetzt habe ich in Form1 eine procedure die mir das abfängt:

Delphi-Quellcode:
procedure FreeFrame(var Msg: TMessage);
begin
  Frame1.Free;
end;
Leider funktioniert das nur, solange ich den Namen des Frames kenne, den ich schließen will. Erzeuge ich meine Frames aber dynamisch, muss ich irgendwie übergeben können, WELCHEN meiner Frames ich löschen möchte.
Kann man diese Information wohlmöglich in der Message mit unterbringen?
Delphi-Quellcode:
PostMessage(Form1.Handle, UM_FREEFRAME, 0, 0);

Bernhard Geyer 27. Jan 2008 20:33

Re: Frame soll sich selbst löschen
 
Schau mal deine beiden Parameter an die du bisher mit 0 belegt hast. Da beide eine breite von 32-Bit haben könnte man da sicherlich irgendwelche Informationen wie einen Referenzzeiger, oder ähnliches unterbringen :gruebel:

corny2000 27. Jan 2008 21:02

Re: Frame soll sich selbst löschen
 
Diese Information wird in WPARAM übergeben...

Delphi-Quellcode:
PostMessage(Form1.Handle, UM_FREEFRAME, Integer(MyDynamicFrame), 0);

...und muss dann später wieder entsprechend konvertiert werden:

Delphi-Quellcode:
TFrame1(msg.WParam).Free;


Mein Problem ist hiemit gelöst. Danke für die Hilfe!


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:43 Uhr.

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