![]() |
Eigene VCL-Komponenten, die ein Interface implementieren
Folgende Situation: ich möchte mir eine Sammlung einiger Standard-WinControls (Edits, Checkbox, Listbox...) erstellen, die allesamt folgendes von mir definiertes Interface implementieren sollen:
Delphi-Quellcode:
Es sollen also alle Controls über die Methoden LoadFromXml, SaveToXml und die property AutoLoadAndSaveToXml verfügen.
ILoadAndSaveToXml = interface(IInterface)
['{C565EF46-47C1-482D-9C71-4570B555BBA4}'] function GetAutoLoadAndSaveToXml: Boolean; procedure SetAutoLoadAndSaveToXml(const Value: Boolean); property AutoLoadAndSaveToXml: Boolean read GetAutoLoadAndSaveToXml write SetAutoLoadAndSaveToXml; procedure LoadFromXml(const XmlElement: IXMLDOMElement); procedure SaveToXml(const XmlElement: IXMLDOMElement); end; Anschließend möchte ich in einer Anwendung mittels ComponentCount alle vorhandenen Controls durchlaufen, schauen ob sie das besagte Interface ILoadAndSaveToXml unterstützen und falls ja, die besagten Methoden aufrufen. Frage: wie mache ich das? Das habe ich bisher versucht: Ich habe mir z.B. ein eigenes Edit wie folgt deklariert:
Delphi-Quellcode:
Die Methoden habe ich mit entsprechendem Leben gefüllt. Theoretisch müsste ich auch noch QueryInterface und _AddRef und _Release selbst implementieren, da meine ganzen Controls ja nicht von TInterfacedObject abgeleitet sind, aber das hab ich erstmal weg gelassen.
TMyEdit = class(TEdit, ILoadAndSaveToXml)
private FAutoLoadAndSaveToXml: Boolean; function GetAutoLoadAndSaveToXml: Boolean; procedure SetAutoLoadAndSaveToXml(const Value: Boolean); published property AutoLoadAndSaveToXml: Boolean read GetAutoLoadAndSaveToXml write SetAutoLoadAndSaveToXml; procedure LoadFromXml(const XmlElement: IXMLDOMElement); procedure SaveToXml(const XmlElement: IXMLDOMElement); end; Alles schön und gut, nur wie finde ich nun zur Laufzeit heraus, ob eine Komponente auf dem Formular das Interface ILoadAndSaveToXml unterstützt, damit ich die Methoden aufrufen kann? Theoretisch ginge das ja über QueryInterface, aber das steht mir nur bei meinen eigenen Controls zu Verfügung, nicht bei allen anderen, die keine von IInterface abgeleitete Schnittstelle implementieren, oder? Oder ist das, was ich hier gerade versuche, ohnehin völliger Blödsinn :shock: ? Also Controls, die zusätzlich Interfaces implementieren? Danke für eure Hilfe! |
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Zwei mögliche Ansätze, mit denen ich in einer eigenen Komponente arbeite, hätte ich hier:
1)
Delphi-Quellcode:
2)
if IsPublishedProp(Control, 'AutoLoadAndSaveToXml') then ...
Delphi-Quellcode:
Vielleicht gibts zu IsPublishedProp ein Äquivalent für Methoden...
if (Control is TMyEdit) then ...
|
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Zitat:
Bei Delphi sollte man entweder über Interfaces Arbeiten oder Interfaces komplett links liegen lassen. Gemischter Betrieb klappt fast nie. Mussten schon Tage an Fehlersuche investieren bis wir herausgefunden hatten wiesoe unsere App hin und wieder krachte. Und da VCL-Komponenten beim erzeugen einen Owner verwenden hättest du fast immer den gefährlichen gemischten Betrieb. |
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Zitat:
Delphi-Quellcode:
Ein simples
if (Control is TMyEdit) or (Control is TMyListBox) or (Control is TMyComboBox) or ...
Delphi-Quellcode:
wäre mir lieber, wenn es das denn gäbe. So könnte ich nach und nach immer mehr Controls in meine Bibliothek mit aufnehmen, die das Interface implementieren, ohne an dem Formular irgendwelche Änderungen vornehmen zu müssen.
if Control.Supports(ILoadAndSavetoXml) then ...
|
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Geht doch mit dem ersten Ansatz, insofern alle deine Kompos z.B. die Property "AutoLoadAndSaveToXml" unterstützen:
Delphi-Quellcode:
if IsPublishedProp(Control, 'AutoLoadAndSaveToXml') then ...
|
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Funktioniert der Operator "is" nicht bei Interfaces?
|
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Zitat:
|
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Hallo Matthias,
alle von TComponent abgeleiteten Komponenten implementieren (in TComponent) das Interface IInterface - also auch deine speziellen Controls, ohne dass du die entsprechenden Funktionen selbst programmieren musst. Zusätzlich ist in TComponent die Referenzzählung ausgeschaltet, falls du nicht gerade mit COM hantierst und Controls ableitest, die das Interface IVCLComObject implementieren. Die einfache Abfrage lautet daher
Delphi-Quellcode:
Für alle nicht von TComponent abgeleiteten Klassen gelten natürlich die von Bernhard gemachten Aussagen bezüglich der gemischten Verwendung von Interface- und Objektreferenzen.
var
intf: ILoadAndSaveToXml; begin if Supports(Component, ILoadAndSaveToXml, intf) then intf.SaveToXML (...); end; Gruß Hawkeye |
Re: Eigene VCL-Komponenten, die ein Interface implementieren
Zitat:
Delphi-Quellcode:
mit folgender Fehlermeldung:
if (Components[i] is ILoadAndSaveToXml) then
Zitat:
Zitat:
danke für die Hintergrundinfos bezüglich TComponent und der "Supports"-Funktion. Genau die haben mir gefehlt. Klar, wenn TComponent bereits IInterface implementiert, dann tun das auch alle WinControls. So muss ich mich dann doch nicht selbst drum kümmern. Außerdem bin ich dann beim Implementieren zusätzlicher Interfaces in meinen eigenen Controls immer auf der sicheren Seite, ohne dass mir die Referenzzählung dabei in die Quere kommt (solange ich die IInterface-Methoden nicht überschreibe). Habs auch schon ausgetestet, funktioniert astrein =) . Womit ich soeben mein erstes eigenes Interface definiert hätte, das noch dazu nen richtig sinnvollen Zweck erfüllt :lol: :dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:25 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