![]() |
Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Hallo,
ich arbeite gerade an meiner ersten visuellen Komponente in Delphi und habe einige Fragen dazu. Ursprünglich dachte ich, es wäre sinnvoll, zuerst die gesamte Funktionalität zu entwickeln und sie dann in eine visuelle Komponente umzuwandeln. Im Nachhinein scheint das jedoch keine gute Idee gewesen zu sein.:? Ich habe eine Klasse erstellt, die von
Delphi-Quellcode:
abgeleitet ist. Dies dient als Grundlage für meine visuelle Komponente, da
TLayout
Delphi-Quellcode:
bereits viele Grundfunktionen bietet, die ich benötige. Auf diesem Layout habe ich auch eine eigene Button-Komponente erstellt, die von
TLayout
Delphi-Quellcode:
abgeleitet ist. Nennen wir diese Klasse einfach
TRectangle
Delphi-Quellcode:
. Ich habe
TMyButton
Delphi-Quellcode:
in einer eigenen Unit abgelegt und sie in den Uses-Teil meiner visuellen Komponente aufgenommen. Auf diese Weise kann ich die Komponente im Code erstellen, und sie funktioniert zur Laufzeit einwandfrei.
TMyButton
Das Problem tritt auf, wenn ich versuche, die Komponente zur Entwurfszeit auf die Form zu ziehen. Das funktioniert noch, aber ab diesem Zeitpunkt lässt sich die Form nicht mehr speichern und ein neu laden der Form ist auch nicht mehr möglich. Delphi meldet dann, dass es die Klasse
Delphi-Quellcode:
nicht finden kann. Ich habe gesehen, dass einige Beispiele alle Klassen in einer Unit zusammenfassen, was jedoch dazu führt, dass die Unit sehr groß wird. Ist dies die einzige Möglichkeit, oder wie sollte das Deployment einer visuellen Komponente in diesem Kontext richtig durchgeführt werden?
TMyButton
Hat jemand bereits Erfahrungen mit visuellen Komponenten und kann mir weiterhelfen? |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Wo und in welchen Units/Packages was drin ist, ist eigentlich vollkommen egal.
Wie kommt TMyButton auf dein LayoutDingens? Im FormDesigner (DesignTimePackage) müssen alle Komnponenten registriert sein (RegisterComponents/RegisterNoIcon/RegisterClasses ... jenachdem wie die "Sichtbarkeit" ist, bzw. ob in KomponentenPalette drin) Zur Laufzeit müssen die Klassen auch registriert sein, damit der DFM-Loader sie auch finden/laden kann. Gibt es für eine Komponente mindestens eine Published-Variable in der Klasse, dann registriert der DFM-Loader diese Klasse (RegisterClass anschließend wieder UnRegisterClass). z.B. für SubComponenten (die z.B. nicht Owner=Form haben), welche dennoch vom DFM-Loader geladen/erstellt werden, aber die keine Variable besitzen, muß man vorher selber mit RegisterClass ran. |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Hi Himitsu,
danke für deine Antwort, ich glaub ich bin noch nicht tief genug in der Materie drin um deine Rückmeldung richtig einzuordnen. Ich versuche dir mal die Fragen zu beantworten: Zitat:
Zitat:
Zitat:
Grüße PJM |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Alle Klassen/Komponenten, welche der FormDesigner, bzw. der DFM-Loader erstellt, die müssen "bekannt" sein, damit er diese Klasse über ihren Namen finden kann.
Wenn ein TMyLayout diese Komponente erstellt, dann wird auch deine Komponete als Owner übergeben? Steht der erstellte Button anschließend in der DFM drin? (wurde also beim Speichern "gefunden" und vom DFM-Streaming gespeichert, um wieder geladen zu werden) |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Moin Himitsu,
Also, ich entwickle in der FMX Ecke, deshalb ich meine .dfm eine .fmx, aber das sollte ja erst mal egal ein. In der fmx steht nach dem reinladen erst mal alles drin. Ich sehe tatsächlich auch die Komponente wenn ich sie das erste mal auf meine Maske ziehe. Erst wenn ich das erste mal versuche zu speichern, bzw. in die Codeansicht wechsle und dann wieder in die Designeransicht gehe (Tabs am unteren Rand der IDE), dann bekomme ich den Fehler das er die darunterliegenden Klassen nicht finden kann. Als Owner übergebe ich immer die jeweils darüberliegende Klasse, also: Owner von TMyLayout: Maske auf die ich die Komponente gelegt hab Wowner von TMyButton: TMyLayout |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Zitat:
damit wir nicht die ganze Zeit über hypothetisches reden, hab ich das Verhalten mal nachgestellt. Das ist der Quellcode für die Unit. Einfach in ein Package werfen und als Komponente installieren. Beim versuch das ganze mit x64 laufen zu lassen, erhalte ich die Info, dass TMySpeedButton nicht gefunden werden kann. Das rein ziehen der Komponente funktioniert aber problemlos.
Delphi-Quellcode:
unit uMyVisualLayout;
interface uses System.SysUtils, System.Classes, FMX.Types, FMX.Controls, FMX.Layouts, FMX.StdCtrls, FMX.Objects, FMX.Graphics; Type TMyImage = class(TImage) private FBackupImage: TBitmap; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; Type TMySpeedbutton = class(TSpeedButton) private FLabelText: TLabel; function GetNewText: String; procedure SetNewText(const Value: String); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; property NewText: String read GetNewText write SetNewText; end; Type TMyLayout = class(TLayout) private { Private-Deklarationen } Speedbutton1, Speedbutton2, Speedbutton3: TMySpeedbutton; TopFlowLayout: TFlowLayout; procedure ButtonClick(Sender: Tobject); protected { Protected-Deklarationen } public constructor Create(AOwner: TComponent); override; { Public-Deklarationen } published { Published-Deklarationen } end; procedure Register; implementation procedure Register; begin RegisterComponents('TestVisualComponent', [TMyLayout]); end; { TMyLayout } procedure TMyLayout.ButtonClick(Sender: Tobject); begin log.d(TSpeedButton(Sender).Name + ' Clicked!'); end; constructor TMyLayout.Create(AOwner: TComponent); begin inherited; TopFlowLayout := TFlowLayout.Create(self); TopFlowLayout.Parent := self; TopFlowLayout.Align := TAlignLayout.MostTop; Speedbutton1 := TMySpeedbutton.Create(self); Speedbutton1.Parent := TopFlowLayout; Speedbutton1.Align := TAlignLayout.Client; Speedbutton1.NewText := 'Speedbutton1'; Speedbutton1.OnClick := ButtonClick; Speedbutton2 := TMySpeedbutton.Create(self); Speedbutton2.Parent := TopFlowLayout; Speedbutton2.Align := TAlignLayout.Client; Speedbutton2.NewText := 'Speedbutton2'; Speedbutton2.OnClick := ButtonClick; Speedbutton3 := TMySpeedbutton.Create(self); Speedbutton3.Parent := TopFlowLayout; Speedbutton3.Align := TAlignLayout.Client; Speedbutton3.NewText := 'Speedbutton3'; Speedbutton3.OnClick := ButtonClick; end; { TMyImage } constructor TMyImage.Create(AOwner: TComponent); begin inherited; FBackupImage := TBitmap.Create; end; destructor TMyImage.Destroy; begin FBackupImage.Free; inherited; end; { TMySpeedbutton } constructor TMySpeedbutton.Create(AOwner: TComponent); begin inherited; FLabelText := TLabel.Create(self); FLabelText.Parent := self; FLabelText.Align := TAlignLayout.Client; end; destructor TMySpeedbutton.Destroy; begin FLabelText.Free; inherited; end; function TMySpeedbutton.GetNewText: String; begin Result := FLabelText.Text; end; procedure TMySpeedbutton.SetNewText(const Value: String); begin FLabelText.Text := Value; end; end. |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Also mir fehlt da schonmal ein
Delphi-Quellcode:
.
SetSubComponent(True)
|
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Zitat:
![]() Emba meint ich brauch es nur wenn ich was im Published hab, das ich gerne gespeichert hätte. Kannst du bissel näher ausführen für was das gebraucht wird? |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
Das SetSubKomponent braucht man nur, wenn man Objekte als Published veröffentlicht.
Normal werden hier nur Zeiger/Verlinkungen gespeichert, aber dadurch weiß der DFM-Writer/Reader dann, dass stattdessen die Eigenschaften der Subkomponente gespeichert werden sollen. |
AW: Visuelle Komponente mit mehreren Klassen in unterschiedlichen Units
FLabelText.Free; bzw. ist unnötig TMySpeedbutton.Destroy, da es durch den Owner freigegeben wird. Aber Falsch ist es auch nicht.
Ansonsten seh ich eigentlich nichts Schlimmes. Nach außen sind diese Subkomponenten ja nicht sichtbar, für den DFM-Reader/Writer. :gruebel: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:55 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 by Thomas Breitkreuz