![]() |
Delphi-Version: XE4
Element '' hat kein übergeordnetes Fenster
Hi,
bei einer Komponente habe ich den Constructor Create überschrieben:
Delphi-Quellcode:
public
constructor Create(AOwner: TComponent); override;
Delphi-Quellcode:
Wenn ich jetzt meine Komponente auf eine Form setze, dann kommt obige Fehlermeldung "Element '' hat kein übergeordnetes Fenster".
constructor TUrlaubsplaner.Create(AOwner: TComponent);
begin inherited Create(AOwner); . . . end; Ich habe ![]()
Delphi-Quellcode:
Wenn ich das mache, dann bekomme wenn ich die Komponente auf die Form setze immer "Zugriffsverletzung im modul VCL180.bpl".
parent = AOwner as TWinControl;
Wenn ich mir den Constructor Create z.B. von TCustomPanel anschaue, dann ist da auch nur
Delphi-Quellcode:
drin.
inherited Create(AOwner);
Warum geht da, und bei mir nicht? |
AW: Element '' hat kein übergeordnetes Fenster
In der Meldung ist der "Parent" gemeint, also da wo die Komponente drauf liegt
und nicht der Owner, also der Besitzer, welcher für die Freigabe verantwortlich ist. Insofern stimmt die Variante mit dem Setzen des Parent. Es kommt jetzt aber auch darauf an wer der Owner ist und ob der eventuell auch sichtbar ist. Zitat:
Aber du hast auch nicht verraten wo (bei welchem Befehl) diese Fehlermeldung auftritt. Tipp: Binde z.B. sowas wie Eurekalog in die IDE ein und bekomm so eventuell die Fehlerzeile raus. Oder starte eine zweite IDE, debugge damit die Andere und dann fürge dort deine Komponente hinzu. Oder füge ein Logging, bzw. ShowMessages, oder eine andere Exception-Behandlung, in deinen Code ein und erfahre so wo es knallt. [edit] Zitat:
|
AW: Element '' hat kein übergeordnetes Fenster
Was ist den die Superklasse?
|
AW: Element '' hat kein übergeordnetes Fenster
Machst Du im Kontruktor bereits etwas, was evtl. ein Zeichnen auslöst? IIRC wird der Parent erst später zugewiesen, so dass zu diesem Zeitpunkt noch niemand da ist, der für die Darstellung zuständig wäre.
|
AW: Element '' hat kein übergeordnetes Fenster
Im Constructor erzeuge ich mir einige Panels, die angeordnet werden, und PaintBoxes, die mit bestimmten Inhalten gefüllt werden.
Die Panels werden nur erzeugt und über Align, Width und Color ein bischen in Form gebracht. Bei den Paintboxen auch Align und Witdh gesetzt, aber im entprechenden OnPaint natürlich auch was gezeichnet. Dort greife ich auf den Canvas von den Paintboxen zu, was den Fehler verursacht. |
AW: Element '' hat kein übergeordnetes Fenster
Was passiert denn, wenn Du in Deinem OnPaint mal ein
Delphi-Quellcode:
als erste Zeile einfügst?
if not Assigned(Parent) then exit;
|
AW: Element '' hat kein übergeordnetes Fenster
Das kann ich zwar machen, aber dann wird zur Entwurfszeit nicht gezeichnet. Das wäre aber wichtig, weil man sonst nicht sehen kann, wie sich Änderungen an den Parametern auf die Darstellung auswirken.
|
AW: Element '' hat kein übergeordnetes Fenster
Da ohne Parent eh nicht gezeichnet werden kann, denn worauf soll denn gemalt werden, ist das doch egal? :stupid:
Auch zur Entwurfszeit ist somit (später) ein Parent vorhanden. Bei Windows-Komponenten kann/sollte man auch auf HandleAllocated prüfen (nicht auf Handle<>0, denn damit würde man versuchen Eines zu erstellen), anstatt auf den Parent. |
AW: Element '' hat kein übergeordnetes Fenster
Wenn Windows ein Control zeichnen will dann muss es bis nach oben zu einem Formular Parent-Zuweisungen geben.
Versuche mal folgendes: Lass die Parents Deiner Panels auf nil und weise Self erst als Parent zu, wenn Deiner Komponente ein Parent zugewiesen wird (dazu musst Du den Setter überschreiben, ich weiß aber nicht ob der virtual ist). Alternativ kannst Du Deine Panels auch Visible=false setzen und beim ersten Zeichnen Deiner Komponente auf True. Du musst irgendwie dafür sorgen, dass Windows Deine Panels erst zeichnen will, wenn Deine Komponente dafür bereit ist. Das gleiche Problem erhält man übrigens, wenn man eine fokussierte Komponente löscht und Windows die später aber nochmal neu zeichnen will. |
AW: Element '' hat kein übergeordnetes Fenster
Meine Komponente basiert auf einem TCustomPanel. Müßte demnach nicht ein Handle automatisch vorhanden sein? Und darauf sind auch Panels. Müßten die nicht automatisch ein Handle erhalten?
Die Paintboxen bekommen nach ihrem Create als ersten das Parent ihres Panels, auf dem sie gezeichnet werden. Hier mal meine komplette Createmothode:
Delphi-Quellcode:
Und hier mein GetDateHeight-Function, ich ich im Create aufrufe:
constructor TUrlaubsplaner.Create(AOwner: TComponent); //TCustomPanel
begin inherited Create(AOwner); self.FLog:=TStringList.Create; self.FPersons:=TPersons.Create(TPerson); self.FEntryTypes:=TEntryTypes.Create(TEntryType); self.FEntries:=TEntries.Create(TEntry); self.FColors:=TtuColors.Create; Self.FFonts:=TFonts.Create; self.FLineWidth:=TLineWitdh.Create; self.FOptions:=TOptions.Create; self.FShowMonths:=True; self.FColumnDayWidth:=20; self.FStartDay:=Now; self.FEndDay:=now+10; self.FRowSpacing:=4; self.FMousePressed:=False; FPanelLeft:= TPanel.Create(Self); //alLeft FPanelLeft.Parent:=Self; FPanelLeft.Align:=alLeft; FPanelLeft.Width:=80; FPanelLeft.BevelOuter:=bvNone; FPanelLeftBottom:=TPanel.Create(Self); //alBottom FPanelLeftBottom.Parent:=FPanelLeft; FPanelLeftBottom.Align:=alBottom; FPanelLeftBottom.Height:=17; FPanelLeftBottom.BevelOuter:=bvNone; FPanelLeftBottom.Color:=self.FColors.Color; FPanelLeftTop:=TPanel.Create(Self); //alTop FPanelLeftTop.Parent:=FPanelLeft; FPanelLeftTop.Align:=alTop; FPanelLeftTop.Height:=40; FPanelLeftTop.BevelOuter:=bvNone; FPanelLeftTop.Color:=self.FColors.Color; FPanelPersonal:=TPanel.Create(Self); //alClient FPanelPersonal.Parent:=FPanelLeft; FPanelPersonal.Align:=alClient; FPanelPersonal.BevelOuter:=bvNone; FSplitter:=TSplitter.Create(self); FSplitter.Parent:=Self; FSplitter.Left:=185; FSplitter.Align:=alLeft; FSplitter.Color:=clSilver; FPanelRight:=TPanel.Create(Self); //alClient FPanelRight.Parent:=self; FPanelRight.Align:=alClient; FPanelRight.BevelOuter:=bvNone; FPanelRightBottom:=TPanel.Create(Self); //alBottom FPanelRightBottom.Parent:=FPanelRight; FPanelRightBottom.Align:=alBottom; FPanelRightBottom.Height:=17; FPanelRightBottom.BevelOuter:=bvNone; FPanelRightBottomRight:=TPanel.Create(self); //alRight FPanelRightBottomRight.Parent:=FPanelRightBottom; FPanelRightBottomRight.Align:=alRight; FPanelRightBottomRight.Width:=17; FPanelRightBottomRight.BevelOuter:=bvNone; FPanelRightBottomRight.Color:=self.FColors.Color; FScrollbarHorizontal:=TScrollbar.Create(Self); //alRight FScrollbarHorizontal.Parent:=FPanelRightBottom; FScrollbarHorizontal.Kind:=sbHorizontal; FScrollbarHorizontal.Align:=alClient; FScrollbarHorizontal.OnScroll:=OnHorizontalScroll; FPanelRightTop:=TPanel.Create(Self); //alTop FPanelRightTop.Parent:=FPanelRight; FPanelRightTop.Align:=alTop; FPanelRightTop.Height:=40; FPanelRightTop.BevelOuter:=bvNone; FPanelRightTopRight:=TPanel.Create(Self); //alRight FPanelRightTopRight.Parent:=FPanelRightTop; FPanelRightTopRight.Align:=alRight; FPanelRightTopRight.Width:=17; FPanelRightTopRight.BevelOuter:=bvNone; FPanelRightTopRight.Color:=self.FColors.Color; FPanelDate:=TPanel.Create(Self); //alClient FPanelDate.Parent:=FPanelRightTop; FPanelDate.Align:=alClient; FPanelDate.BevelOuter:=bvNone; FPanelDays:=TPanel.Create(Self); //alClient FPanelDays.Parent:=FPanelRight; FPanelDays.Align:=alClient; FPanelDays.BevelOuter:=bvNone; FScrollbarVertical:=TScrollBar.Create(Self); //alClient FScrollbarVertical.Parent:=FPanelDays; FScrollbarVertical.Kind:=sbVertical; FScrollbarVertical.Align:=alRight; FScrollbarVertical.OnScroll:=OnVerticalScroll; FDatePaint:=TPaintBox.Create(self); FDatePaint.Parent:=FPanelDate; FPanelLeftTop.Height:=GetDateHeight; //Hier könnte der Fehler sein. FPanelRightTop.Height:=GetDateHeight; FDatePaint.Left:=0; FDatePaint.Top:=0; FDatePaint.Height:=FPanelDate.Height; FPersonPaint:=TPaintBox.Create(self); FPersonPaint.Parent:=FPanelPersonal; FPersonPaint.Left:=0; FPersonPaint.Top:=0; FPersonPaint.Width:=FPanelPersonal.Width; FGridPaint:=TPaintBox.Create(self); FGridPaint.Parent:=FPanelDays; FGridPaint.Left:=0; FGridPaint.Top:=0; FGridPaint.OnMouseUp:=OnGridMouseUp; FGridPaint.OnMouseDown:=OnGridMouseDown; FGridPaint.OnMouseMove:=OnGridMouseMove; FGridPaint.OnDblClick:=OnGridDblClick; Self.Clear; end; destructor TUrlaubsplaner.Destroy; begin self.FPersons.Free; self.FEntryTypes.Free; Self.FEntries.Free; Self.FColors.Free; self.FFonts.Free; self.FLineWidth.Free; self.FOptions.Free; self.FLog.Free; inherited; end;
Delphi-Quellcode:
function TUrlaubsplaner.GetDateHeight: Integer;
var m, dn, d: Integer; begin FDatePaint.Font:=Self.FFonts.MonthFont; m:=FDatePaint.Canvas.TextHeight('00'); FDatePaint.Font:=self.FFonts.DateFont; d:=FDatePaint.Canvas.TextHeight('00'); dn:=FDatePaint.Canvas.TextHeight('00'); Result:=d+4; if self.FOptions.ShowDayNames then Result:=Result+dn+4; if self.FShowMonths then Result:=Result+m+4; FIntMonthHeight:=m+4; FIntDayNameHeight:=dn+4; FIntDayCountHeight:=d+4; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:49 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