![]() |
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:
funktioniert nicht.
procedure TmyPanel.CloseClick(Sender: TObject);
begin FreeAndNil(Self); // oder einfach Free; end; |
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?!
|
Re: Selbstzerstörung eines Controls
So hab ichs bis jetzt auch gemacht, aber ich dachte vielleicht gibts noch eine elegantere Lösung :lol:
|
Re: Selbstzerstörung eines Controls
Geht schon musst nur sicherstellen, dass der button kein sub-object von dem panel mehr ist:
Delphi-Quellcode:
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:
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; cu, maximov. |
Re: Selbstzerstörung eines Controls
Danke ich probiers gleich aus.
|
Re: Selbstzerstörung eines Controls
Zitat:
im Destruktor von TComponent, dem (indirekten) Vorfahren von TButton wird ua diese Referenz implizit aufgelöst
Delphi-Quellcode:
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:
destructor TComponent.Destroy;
//... begin //... if FOwner <> nil then FOwner.RemoveComponent(Self); inherited Destroy; end;
Delphi-Quellcode:
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...
procedure TDataSet.SetActive(Value: Boolean);
begin //... DoBeforeOpen; try OpenCursor; finally if State <> dsOpening then OpenCursorComplete; end; //... end; |
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. |
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:
und dann von Deinem Click-Event so verwendet werden:
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;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin PostMessage(Handle, WM_FREEVCLCONTROL, Integer(Sender), 0); end; |
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) |
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 07:51 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-2025 by Thomas Breitkreuz