Parent Problem bei eigener Komponente
Hallo,
ich habe ein Problem und konnte im www bislang noch keine Lösung finden. Vielleicht fehlen mir auch nur die passenden Suchbegriffe. Vieleicht finde ich hier eine Lösung für mein Problem. Ich habe mir eine Eigenen Komponente erzeugt. Um das Beispiel verständlich zu halten basiert meine Komponente auf ein TPanel.
Code:
Ich registriere die Kompononete entsprechend und kann diese dann auch aus meiner Toolpalete in meinem Dialog ziehen.
TMeineKompo = class(TPanel)
public Pan1: TPanel; Pan2: TPanel; constructor Create(aOwner: TComponent); override; end; Jetzt möchte ich zur Designzeit in dem Dialog weitere Komponenten (z.B. Panel) in das Panel (Pan2) meiner Komponente platzieren. Ich kann zwar ein Panel unter der Komponente hängen, jedoch ist der Parent nicht mein gewünschtes Panel Pan2 sonder die Komponente selbst. Wie bekomme ich das hin, dass ich weitere Komponenten zur Designzeit in delphi in das Panel Pan2 meiner Komponente packen kann? Ich hoffe ich konnte mein Problem einigermaßen nachvollziehend erklären. ;-) Viele Grüße Stegi |
AW: Parent Problem bei eigener Komponente
Moin und willkommen in der Delphi-PRAXiS. :-)
Nach Deiner Beschreibung fehlt Dir ein Wert im Set "ControlStyle". Dort kannst - musst - Du definieren, dass Du gern als Basis für andere Controls dienen möchtest: http://docwiki.embarcadero.com/Libra...l.ControlStyle In etwa wie folgt:
Delphi-Quellcode:
constructor TMeineKompo.Create(AOwner: TComponent);
begin inherited Create(AOwner); ControlStyle := ControlStyle + [csAcceptsControls]; //... end; |
AW: Parent Problem bei eigener Komponente
Ohne es ausprobiert zu haben- Müsste er das nicht durch das Erben von
Delphi-Quellcode:
bereits erledigt haben? Sein Problem ist ja nicht dass man auf dem Designer keine Controls hineinwerfen könne, sondern dass die hineingesteckten nicht direkt im
TPanel
Delphi-Quellcode:
-Nachfahren, sondern in einem da drin bereits enthaltenen Container landen sollen.
TPanel
Spontan hätte ich gesagt, dazu müsste man einfach nur das von
Delphi-Quellcode:
geerbte
TWinControl
Delphi-Quellcode:
überschreiben. Aber das ist nicht virtuell.
procedure InsertControl(AControl: TControl);
Und somit hätte ich spontan auch keine Idee. |
AW: Parent Problem bei eigener Komponente
Zitat:
Aber ob der FormDesigner dann noch anbietet diese Komponenten zu bearbeiten, weiß ich auch nicht. |
AW: Parent Problem bei eigener Komponente
im Constructor
Delphi-Quellcode:
würde das mit den Panels über nen Setter machen
Pan1 := TMein(bla).Create(Self);
Pan1.Parent := Self; . . . FPan1 usw |
AW: Parent Problem bei eigener Komponente
Es geht um die Designzeit, da bringt es ja nichts, im Konstruktor den Parent setzen zu wollen.
|
AW: Parent Problem bei eigener Komponente
Zitat:
|
AW: Parent Problem bei eigener Komponente
Ja nee is klar.
|
AW: Parent Problem bei eigener Komponente
Zitat:
|
AW: Parent Problem bei eigener Komponente
Zitat:
Delphi-Quellcode:
) die Werte für
TComponentState
Delphi-Quellcode:
und
csDesigning
Delphi-Quellcode:
bedeuten.
csDesignInstance
Wenn also eine Komponente zur Designzeit niemals auch nur irgendwas da zum Leben erweckt, wozu sind denn diese komischen Dingsbums-Dinger da? |
AW: Parent Problem bei eigener Komponente
Außer bei TForms, welche über CreateForm erstellt werden, sind diese Property im Constructor niemals richtig befüllt. (man kann sie ja erst setzen, wenn die Komponente befüllt wurde :zwinker:)
|
AW: Parent Problem bei eigener Komponente
Wichtiger ist doch aber jetzt, ob Stegis Problem gelöst ist oder ob nicht
:witch: |
AW: Parent Problem bei eigener Komponente
Schon mal probiert die beiden Panels in den Container Controls der eigenen Komponente beim Construct zu packen?
|
AW: Parent Problem bei eigener Komponente
Hi,
sorry, konnte heute erst die Vorschläge versuchen auszuprobieren. Leider ohne Erfolg. Im Constructor von meiner Komponente werden bereits die zwei Panels erzeugt und der Parent der zwei Panels ist selbstverständlich die Kompononente selbst. Aber dennoch klappt es nicht. Man müsste irgendwie allen Komponenten die man in die eigenen Kompononete zieht die eigenen Komponente als Parent mitgeben. :gruebel: |
AW: Parent Problem bei eigener Komponente
So klappt es:
Delphi-Quellcode:
Gruß oki
unit PanelUnit;
interface uses ExtCtrls, Classes; type TMyPanel = class(TPanel) private Panel1 : TPanel; { private-Deklarationen } protected { protected-Deklarationen } procedure CreateWnd(); override; public { public-Deklarationen } Constructor Create(AOwner : TComponent); override; published { published-Deklarationen } end; procedure Register(); implementation procedure Register(); begin RegisterComponents('oki', [TMyPanel]); end; { TMyPanel } constructor TMyPanel.Create(AOwner: TComponent); begin inherited; end; procedure TMyPanel.CreateWnd; begin inherited; Panel1 := TPanel.Create(self); Panel1.Parent := self; self.Owner.InsertComponent(Panel1); end; end. |
AW: Parent Problem bei eigener Komponente
Und so hast du dir eine wunderschöne Endlosschleife gebastelt.
MyPanel hat Panel1 als Owner und Panel1 hat das MyPanel als Owner. Als Ergebnis halten sich beide gegenseitig im Speicher und am Ende hat man ein Speicherleck, genauso, als wenn MyPanel garkeinen Owner hätte und es Panel1 nicht gäbe. Außerdem wird/kann CreateWnd mehrmals zur Laufzeit aufgerufen werden, womit es mehrere Panel1 geben könnte. Die Variable Panel1 wird sonst nirgendwo anders verwendet und kann auch gut und gern einfach nur eine Lokale in CreateWnd sein. Wozu das Create hier im Beispiel sein soll, weiß wohl keiner.
Delphi-Quellcode:
Hab den Thread jetzt nicht mehr so ganz im Kopf, aber wozu soll das Panel1 jetzt eigentlich dienen?
unit PanelUnit;
interface uses ExtCtrls, Classes; type TMyPanel = class(TPanel) private { private-Deklarationen } protected { protected-Deklarationen } //procedure CreateWnd(); override; public { public-Deklarationen } constructor Create(AOwner: TComponent); override; published { published-Deklarationen } end; procedure Register(); implementation procedure Register(); begin RegisterComponents('oki', [TMyPanel]); end; { TMyPanel } //procedure TMyPanel.CreateWnd; constructor TMyPanel.Create(AOwner: TComponent); var Panel1: TPanel; begin inherited; Panel1 := TPanel.Create(self); Panel1.Parent := self; if Assigned(Owner) then Owner.InsertComponent(Panel1); end; end.
Delphi-Quellcode:
unit PanelUnit;
interface uses ExtCtrls, Classes; type TMyPanel = class(TPanel) private { private-Deklarationen } protected { protected-Deklarationen } //procedure CreateWnd(); override; public { public-Deklarationen } constructor Create(AOwner: TComponent); override; published { published-Deklarationen } end; procedure Register(); implementation procedure Register(); begin RegisterComponents('oki', [TMyPanel]); end; { TMyPanel } //procedure TMyPanel.CreateWnd; constructor TMyPanel.Create(AOwner: TComponent); begin inherited; if Assigned(Owner) then Owner.RemoveComponent(Panel1); end; end. |
AW: Parent Problem bei eigener Komponente
Hi himitsu.
Okay, hab ich alles etwas leichtfertig zusammengehackt :oops:. Ich entschuldige mich dafür und werde in Zukunft sorgsamer sein. Gleichfalls hast du aber auch nicht gründlich gelesen. Zitat:
Wo liegt eigentlich der Unterschied zwischen meinem und deinem Code-Beispiel, außer dass Panel1 nich private ist (seh ich ein, ist ein Fehler meinerseits) und dass du den Code von CreateWnd nach Create verschoben hast? (Das Assign ist eine vernünftige Ergänzung für den Fall, dass MyPanel per Code ohne Owner erzeugt wird). Zitat:
Das CreateWnd mehrfach aufgerufen wird ist mir neu. Dank für den Hinweis. Ist das schon immer so oder erst ab einer speziellen Delphi-Version? Deinen zweiten Code-Abschnitt verstehe ich nicht. Was soll das RemoveComponent? Gruß oki |
AW: Parent Problem bei eigener Komponente
CreateWnd wird jedesmal aufgerufen, wenn das interne Window (HWND) neu erstellt wird, das passiert z.B. beim Ändern des Parent, oder beim Umstellen des FormStyle usw.
Ups, mit dem Owner hab ich falschrum geguckt. :oops:
Delphi-Quellcode:
entspricht
procedure TMyPanel.CreateWnd;
begin inherited; Panel1 := TPanel.Create(self); Panel1.Parent := self; Self.Owner.InsertComponent(Panel1); end;
Delphi-Quellcode:
Demnach wäre das InsertComponent dann nur "nutzlos", da der Owner bereits gesetzt wurde.
procedure TMyPanel.CreateWnd;
begin inherited; //Panel1 := TPanel.Create(self); Panel1 := TPanel.Create(nil); Panel1.Owner := Self; Panel1.Parent := Self; //Self.Owner.InsertComponent(Panel1); Panel1.Owner := Self; // hatte das vorhin als Self.Owner := Panel1; übersetzt end; Hmmmmmmmmmmmmmmmm... :gruebel: Also der zweite Code, lies einfach nur den Owner weg, durch weglassen des Panel1 .... unter der Annahme der falschen Richtung des InsertComponent.
Delphi-Quellcode:
hätte man auch als
constructor TMyPanel.Create(AOwner: TComponent);
begin inherited; if Assigned(Owner) then Owner.RemoveComponent(Panel1); end;
Delphi-Quellcode:
schreiben können, aber ist ja nun doch falsch.
constructor TMyPanel.Create(AOwner: TComponent);
begin inherited Create(nil); end; |
AW: Parent Problem bei eigener Komponente
Delphi-Quellcode:
ist aber genau der Punkt, der zur Designzeit Zugriff auf das Panel1 liefert. Ohne gehts nicht. Bitte achte drauf, InsertComponent rufe ich nicht für MyPanel auf, sondern für dessen Owner!
self.Owner.InsertComponents(Panel1);
Das ist doch
Delphi-Quellcode:
gleich dem
Panel1 := TPanel.Create(self);
Panel1.Parent := self;
Delphi-Quellcode:
mit dem kleinen Problem, dass Owner eine nur-lese-Eigenschaft ist und so nicht gehen sollte. Führt aber alleine nicht dazu, dass man weitere Controls in Panel1 zur Designzeit legen kann.
Panel1 := TPanel.Create(nil);
Panel1.Owner := Self; Panel1.Parent := Self; CreateWnd hatte ich immer so verstanden, dass das nach dem Create aufgerufen wird wenn ein Handle verfügbar ist. Das ist beim Create noch nicht da. Das das bei einer vorhandenen Componente zur Lebenszeit wiederholt aufgerufen wird ist mir noch nie vorgekommen. Wenn ich in einer eigenen Komponente das Handle benötige habe ich den Code immer da platziert, auch für weitere Objekte. Hatte nie Probleme. :shock: Muss ich noch mal nachlesen. Gruß oki |
AW: Parent Problem bei eigener Komponente
Zitat:
Delphi-Quellcode:
Und daß sich Komponenten nur im OI bearbeiten lassen, wenn sie die Form als Owner besitzen, wurde gleich zu Beginn von jemandem erwähnt. :stupid:
constructor TMyPanel.Create(AOwner: TComponent);
begin inherited; Panel1 := TPanel.Create(Owner); // aka Self.Owner, anstatt nur Self Panel1.Parent := Self; end; (rate mal wer AOwner/Owner des MyPanel ist) |
AW: Parent Problem bei eigener Komponente
Hallo Himitsu,
ich glaube, wir sind uns im Grunde einig, verstehen aber vielleicht die Aufgabenstellung unterschiedlich. Ich vermute mal, du meinst ausschließlich das Problem, wie man eine Komponente in einem eigenen Panel (MyPanel) zur Erstellungszeit einfügt. Dafür reicht dein Code. Ich habe den Threadersteller aber so verstanden, dass er zur Designzeit auf dem erstellten Panel (Panel1 und nicht MyPanel) weitere Komponenten platzieren will. Dazu braucht er aber Zugriff auf das eingebettete Panel1 zur Designzeit. Das ist nur möglich, wenn er das eingebettete Panel1 in die Liste Components des Formulars packt. Erst dann kann er zur Designzeit weitere Komponenten in Panel1 platzieren. Zitat:
Mir erschließt sich nicht wirklich, warum er nicht zur Designzeit auch Panel1 in MyPanel platziert und das unbedingt innerhalb der Kompo passieren muss. Egal, mit dem Zugriff auf Panel1 ergeben sich aber weitere Probleme wie: - Panel1 kann somit auch zur Designzeit entfernt werden, - Liegt MyPanel nicht auf der Form, sondern auf einem weiteren Panel reicht self.Owner.InsertComponent nicht aus. Es muss das Formular gesucht werden. Das kann man sicher über eine rekursive Funktion durch alle Owner mit Rückgabe des "Letzten" lösen. - Panel1 kann über den OI zur Designzeit verändert werden (Position, Größe etc.). Was soll statisch bleiben? Hier müssten dann diverse Methoden überladen werden um diese Änderungen zu verhindern. Und so gibt es bestimmt noch Dinge an die ich nicht gedacht habe, weis ja auch nicht welche konkreten Eigenschaften die Komponente haben soll. Wurde nicht genannt. Grundsätzlich gehe ich aber davon aus, dass die grundlegende Aufgabenstellung ist, Wie kann ich in meiner Komponente ein Panel integrieten, in das ich zur Designzeit weitere Komponenten legen kann. Gruß oki |
AW: Parent Problem bei eigener Komponente
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
oki, du hast es richtig verstanden. Vielleicht versuche ich noch einmal den Grund für mein Vorhaben zu schildern. Ich möchte eine Komponente erstellen die wie eine Art Groupbox fungiert nur ohne einen Rahmen und mit einen farblichen Balken oberhalb. Ähnlich den MS Word Optionen (siehe Bild). Hierfür dachte ich, ich erstelle eine Komponente abgeleitet vom TCustomPanel welches ein weiteres Panel alTop hat und ein weiteres Panel alclint in dem alle weiteren Komponente zur Designzeit reingepackt werden können. Ich möchte dies für alle meine Kollegen so einfach und effizient wie möglich machen. Sie sollen sich nicht mehr um margins, font, farben etc. kümmern müssen sondern einfach nur ihre Komponenten mit Align = alTop hineinwerfen müssen. Ich hoffe ich konnte etwas mehr Licht ins dunkle meiner Idee bringen. ;-) Gruß Stegi |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:36 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