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/)
-   -   Eigene Komponente mit erweitertem Construktor? (https://www.delphipraxis.net/194952-eigene-komponente-mit-erweitertem-construktor.html)

sko1 22. Jan 2018 10:21

Eigene Komponente mit erweitertem Construktor?
 
Hallo,

eine eigene Komponente erzeuge ich normalerweise mit

Delphi-Quellcode:
    constructor Create(AOwner: TComponent); override;
...
constructor TMyControl.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
...
ich möchte jetzt den Aufruf von Create um einen weiteren Parameter erweitern (z.B. ein Dateiname einer Datei die im Create bereits geladen werden soll)

Irgendwie fehlt mir der Ansatz wie man das bewerkstelligen könnte ...

Ciao
Stefan

Bernhard Geyer 22. Jan 2018 10:30

AW: Eigene Komponente mit erweitertem Construktor?
 
Bei (GUI)-Controls sollte man das nicht machen, da diese ja nach nicht mehr ohne Einschränkung durch "Fallen lassen" in der Delphi-IDE eingestzt werden können.
Den das normale Dephi-DFM-Streaming zum erzeugen des Formulares kann nur mit dem Standard-Konstruktor umgehen.

himitsu 22. Jan 2018 10:36

AW: Eigene Komponente mit erweitertem Construktor?
 
Ohne das
Delphi-Quellcode:
override
, da du ja was Neues machst. :zwinker:
Und wie bereits gemacht, das
Delphi-Quellcode:
inherited;
mit explititem Aufruf
Delphi-Quellcode:
inherited Create(AOwner);
, aber besser ohne Inherited, also nur
Delphi-Quellcode:
Create(AOwner);
, siehe abschließenden Absatz.

Eventuell aber mit
Delphi-Quellcode:
virtual
, falls du es in Nachfahren überschreiben willst.
Aber zu bedenken ist, dass bei Erstellung über die DFM (Komponente auf der Form) immer nur das originale Create(AOwner) vom DFM-Loader aufgerufen wird,
also wichtige Initialisierungscodes müssen immer in Create. Aus diesem Grund auch ohne inherited, um auch nachfolgende Überschreibungen von Create(AOwner) zu erwischen.

[edit] Wie Bernhard schon sagte: Der wichtige Code muß ins originale Create und nur zusätzlicher/abweichender Codes in deinen neuen Constructor.
Da dann auch immer den normalen Constructor
Delphi-Quellcode:
Create(AOwner)
aufrufen ... wenn es nicht anders geht, dann
Delphi-Quellcode:
Create(AOwner)
als
Delphi-Quellcode:
final
dekalieren und ein weiteres Überschreiben sperren.

HolgerX 22. Jan 2018 12:37

AW: Eigene Komponente mit erweitertem Construktor?
 
Hmm..

Um eine neue neue Function/Constructor mit anderen Parameter zu erstellen gibt es (meines Wissens) das reintroduce, damit wird ähnlich des Overloads eine neue Function mit anderen Parametern angelegt, mit dem Unterschied, dass die Überschriebene Function der Vorgängerclasse nicht mehr direkt verwenden kann.

Wenn Du nur eine 2., alternative Funktion erstellen willst, ist das overload statt reintroduce das Richtige.


Ersetzen:
Delphi-Quellcode:
    constructor Create(AOwner: TComponent;AFileName : string); reintroduce;
...
constructor TMyControl.Create(AOwner: TComponent;AFileName : string);
begin
  inherited Create(AOwner);
  FFileName := AFileName;
end;

...

Zusätzlich
Delphi-Quellcode:
    constructor Create(AOwner: TComponent;AFileName : string); overload;
...
constructor TMyControl.Create(AOwner: TComponent;AFileName : string);
begin
  inherited Create(AOwner);
  FFileName := AFileName;
end;

...

himitsu 22. Jan 2018 13:00

AW: Eigene Komponente mit erweitertem Construktor?
 
Nein, reintroduce gibt nur dem Compiler zu verstehen, dass du absichtlich eine alte virtuelle Methode verdecken willst, und deaktiviert da die Compilerwarnung.
Es ist quasi das Gegenteil von
Delphi-Quellcode:
overload
.
http://docwiki.embarcadero.com/RADSt...i)#Reintroduce

Ist nötig, wenn man nur den neuen Constructor verwenden und den alten Constructor verstecken will, was aber keine gute Idee ist, falls die Komponente auch auf eine Form gepappt werden kann/darf.

HolgerX 22. Jan 2018 13:11

AW: Eigene Komponente mit erweitertem Construktor?
 
Hmm.

Zitat:

Zitat von himitsu (Beitrag 1391636)
Nein, reintroduce gibt nur dem Compiler zu verstehen, dass du absichtlich eine alte virtuelle Methode verdecken willst, und deaktiviert da die Compilerwarnung.
Es ist quasi das Gegenteil von
Delphi-Quellcode:
overload
.


hatte ich das nicht geschrieben:

Zitat:

Zitat von HolgerX (Beitrag 1391632)
Um eine neue neue Function/Constructor mit anderen Parameter zu erstellen gibt es (meines Wissens) das reintroduce, damit wird ähnlich des Overloads eine neue Function mit anderen Parametern angelegt, mit dem Unterschied, dass die Überschriebene Function der Vorgängerclasse nicht mehr direkt verwenden kann.

OK, vielleicht nicht so klar ausgedrückt ;)

sko1 22. Jan 2018 13:57

AW: Eigene Komponente mit erweitertem Construktor?
 
Vielen Dank, ich denke da komme ich jetzt weiter!

Diese Komponente wird (aus hier nicht zu erklärenden Gründen) nicht in der Komponentenpalette installiert werden und wird immer per Code erzeugt, damit sind ein paar Einwände "entkräftet"...

Was ich aber gerade denke:
Kann man eine public Property der Komponente bereits vor dem Create beschreiben und im Create verwenden?

Also z.B. einen Filenamen setzen bevor Create aufgerufen wird (diese Datei soll das Aussehen der Komponente steuern).

Ich mag für so was keine globale Variable einsetzen...

Ciao
Stefan

DeddyH 22. Jan 2018 14:11

AW: Eigene Komponente mit erweitertem Construktor?
 
Du kannst keine Eigenschaften von etwas setzen, was noch gar nicht existiert. Ohne Variable außerhalb der Klasse (oder evtl. eine Klassenvariable), die Du initialisierst und deren Wert Du im/nach dem Konstruktor dann der Property zuweist, dürfte das also schwierig werden.

Bernhard Geyer 22. Jan 2018 14:11

AW: Eigene Komponente mit erweitertem Construktor?
 
Zitat:

Zitat von sko1 (Beitrag 1391645)
Diese Komponente wird (aus hier nicht zu erklärenden Gründen) nicht in der Komponentenpalette installiert werden und wird immer per Code erzeugt, damit sind ein paar Einwände "entkräftet"...

Dann ist sie auch keine Komponenten im Sinne von, das ihre Vorfahrklasse TComponent sein müsste.
Dann reicht eine Ableitung von TObject auch aus.

bcvs 22. Jan 2018 14:15

AW: Eigene Komponente mit erweitertem Construktor?
 
Zitat:

Zitat von sko1 (Beitrag 1391645)
Diese Komponente wird (aus hier nicht zu erklärenden Gründen) nicht in der Komponentenpalette installiert werden und wird immer per Code erzeugt, damit sind ein paar Einwände "entkräftet"...

Dann braucht es aber doch auch keine Komponente zu sein. Dann kannst du ja von TObject ableiten und den Constructor aufbauen, wie du willst.

Edit: Sorry, Bernhard war schneller.

Codehunter 22. Jan 2018 14:22

AW: Eigene Komponente mit erweitertem Construktor?
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1391649)
Zitat:

Zitat von sko1 (Beitrag 1391645)
Diese Komponente wird (aus hier nicht zu erklärenden Gründen) nicht in der Komponentenpalette installiert werden und wird immer per Code erzeugt, damit sind ein paar Einwände "entkräftet"...

Dann ist sie auch keine Komponenten im Sinne von, das ihre Vorfahrklasse TComponent sein müsste.
Dann reicht eine Ableitung von TObject auch aus.

Wenn es eine visuelle Komponente ist, dann schon. Ich habe auch etliche solche Komponenten gebaut, die nie in der Komponentenpalette auftauchen. So zum Beispiel Inline-Editoren für den Virtual Treeview. Die werden naturgemäß IMMER zur Runtime erzeugt.

mucsim 23. Jan 2018 11:05

AW: Eigene Komponente mit erweitertem Construktor?
 
Zitat:

ich möchte jetzt den Aufruf von Create um einen weiteren Parameter erweitern (z.B. ein Dateiname einer Datei die im Create bereits geladen werden soll)
Dafür erstellt man einfach einen

constructor Create(AOwner : TComponent; FileName : String)
begin
inherited Create( AOwner );
...
LoadFromFile( FileName );
end;

Man muss in dem code natürlich explizit dieses neue Create aufrufen - wie oben beschrieben kein Problem, da die Komponente/Control ja zur Laufzeit erzeugt werden soll.

Eigenschaften kann man dann auch innerhalb des Create setzen, also nachdem inherited aufgerufen wurde.

Wenn es sich um eine visuelle Komponente handelt muss man aufpassen - innerhalb von Create hat diese noch kein Fensterhandle.

Für Komponenten die aus der DFM geladen werden, wird nach dem Laden auch noch "Loaded" aufgerufen. Dies sollte man für manche Komponenten auch machen, wenn sie zur Laufzeit erzeugt wurden und die Eigenschaften gesetzt wurden.

Codehunter 23. Jan 2018 11:31

AW: Eigene Komponente mit erweitertem Construktor?
 
Willkommen in der DP!

Zitat:

Zitat von mucsim (Beitrag 1391746)
Delphi-Quellcode:
constructor Create(AOwner : TComponent; FileName : String)
begin
   inherited Create( AOwner );
   ...
   LoadFromFile( FileName );
end;

Vorsicht... Mit dem inherited ruft man den Konstruktor der Elternklasse auf, nicht den der eigenen Klasse. Wenn man da aber schon einen überschriebenen Konstruktor in Standarddeklaration hat, sollte man den aufrufen. Andernfalls kopiert man sich den selben Code in beide Konstruktoren und das ist unschön.

himitsu 23. Jan 2018 11:59

AW: Eigene Komponente mit erweitertem Construktor?
 
Zitat:

Zitat von Codehunter (Beitrag 1391748)
Vorsicht... Mit dem inherited ruft man den Konstruktor der Elternklasse auf, nicht den der eigenen Klasse. Wenn man da aber schon einen überschriebenen Konstruktor in Standarddeklaration hat, sollte man den aufrufen. Andernfalls kopiert man sich den selben Code in beide Konstruktoren und das ist unschön.

Jupp, für Ausführlich siehe Antwort #3.


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