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 Selbstzerstörung eines Controls (https://www.delphipraxis.net/11424-selbstzerstoerung-eines-controls.html)

Garby 6. Nov 2003 13:14


Selbstzerstörung eines Controls
 
Hallo,

ich habe eine Komponente myManel von TPanel abgeleitet. Dort habe ich einen Button draufgesetzt.
Frage: wie kann ich im Button.Click das Panel zerstören?
Delphi-Quellcode:
procedure TmyPanel.CloseClick(Sender: TObject);
begin
  FreeAndNil(Self); // oder einfach Free;
end;
funktioniert nicht.

SirThornberry 6. Nov 2003 13:20

Re: Selbstzerstörung eines Controls
 
das geht nicht. müsste ein Abstract error kommen da du du ja das ganze noch nutzt während es freigegeben werden soll. Selbstzerstörunge geht somit nicht. Du könntest einer anderen komponente das zerstören überlassen?!

Garby 6. Nov 2003 13:32

Re: Selbstzerstörung eines Controls
 
So hab ichs bis jetzt auch gemacht, aber ich dachte vielleicht gibts noch eine elegantere Lösung :lol:

maximov 6. Nov 2003 14:04

Re: Selbstzerstörung eines Controls
 
Geht schon musst nur sicherstellen, dass der button kein sub-object von dem panel mehr ist:

Delphi-Quellcode:
procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  TButton(sender).Parent := nil;
  Panel1.Free;
end;

procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  free;
end;
Das problem war eigentlich nur, dass er nach dem mouseDown noch mouseUp für den button erzeugt und da, bei dir kein button mehr existierte hats gekrach. ergo kannst du auch alles in mouseUp schreiben :wink:

cu,
maximov.

Garby 6. Nov 2003 14:21

Re: Selbstzerstörung eines Controls
 
Danke ich probiers gleich aus.

choose 6. Nov 2003 17:40

Re: Selbstzerstörung eines Controls
 
Zitat:

Zitat von maximov
Geht schon musst nur sicherstellen, dass der button kein sub-object von dem panel mehr ist

Hallo Maximov,

im Destruktor von TComponent, dem (indirekten) Vorfahren von TButton wird ua diese Referenz implizit aufgelöst
Delphi-Quellcode:
destructor TComponent.Destroy;
//...
begin
//...
  if FOwner <> nil then FOwner.RemoveComponent(Self);
  inherited Destroy;
end;
Jedoch sollte man generell nicht in den Eventhandlern, das Auslösende Objekt freigeben. In vielen Fällen ist die VCL so programmiert, dass dies zu einem Absturz führt. Hier zB ein Ausschnitt aus der Implementierung von TDataset aus db.pas:
Delphi-Quellcode:
procedure TDataSet.SetActive(Value: Boolean);
begin
  //...
        DoBeforeOpen;
        try
          OpenCursor;
        finally
          if State <> dsOpening then
            OpenCursorComplete;
        end;
  //...
end;
Wenn Du also in OnBeforeOpen das ereignisauslösende Objekt freigibst, wird (abhängig von der konkreten Implementierung des Erbens) wahrscheinlich in OpenCursor spätestens aber bei if State <> dsOpening ein Fehler auftreten...

maximov 7. Nov 2003 09:35

Re: Selbstzerstörung eines Controls
 
Das is ja alles schön und gut, aber solange es funktioniert und nach dem 'mouseUp' wird der button nicht mehr von message-routinen angefasst...ergo kein fehler! Ich geb zu das es sub-optimal ist. Mir wäre auch eine lösung lieber gewesen, wie man es zB. mit formularen machen kann, in denen 'release' ( PostMessage(handle,CM_RELEASE,..) ) benutzt werden kann :-D

cu, maximov.

choose 7. Nov 2003 12:43

Re: Selbstzerstörung eines Controls
 
Hallo maximov,

danke für die Idee! Für den speziellen Fall, könnte man das tatsächlich mit einem PostMessage machen, weil die Ereignissbehandlungsroutine durch die selbe Queue aufgerufen worden ist.

Eine Lösung könnte so implementiert
Delphi-Quellcode:
const
  WM_FREEVCLCONTROL = WM_USER+42;

type
  TForm1 = class(TForm)
  //...
  private
    procedure WMFreeVCLControl(var Message: TMessage);message WM_FREEVCLCONTROL;
  //...
  end;

procedure TForm1.WMFreeVCLControl(var Message: TMessage);
begin
  Assert( Message.WParam<>0 );
  TObject(Message.WParam).Free;
end;
und dann von Deinem Click-Event so verwendet werden:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  PostMessage(Handle, WM_FREEVCLCONTROL, Integer(Sender), 0);
end;

Garby 7. Nov 2003 12:56

Re: Selbstzerstörung eines Controls
 
Hallo choose,

so hab ichs auch gemacht, ist halt nur ein wenig umständlicher.

@maximov: Was passiert bei deiner Methode der Button über Shortcut betätigt wird (da gibts ja kein OnMouseUp)

maximov 7. Nov 2003 20:54

Re: Selbstzerstörung eines Controls
 
Wenn der aufruf per shortcut gemacht wird, gehe ich davon aus, dass du actions oder der gleichen beuntzt. Da actions aber keine visuellen componenten sind haben sie auch keine parent-suizid probleme :wink: ...weil sie als parent höchstens das formular haben.

mfg. mäxmov.


PS: @Choose: das mit dem 'WM_FREEVCLCONTROL' muss ich mir merken!


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:33 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