AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Eigene VCL-Komponenten, die ein Interface implementieren
Thema durchsuchen
Ansicht
Themen-Optionen

Eigene VCL-Komponenten, die ein Interface implementieren

Ein Thema von MatthiasR · begonnen am 17. Nov 2009 · letzter Beitrag vom 18. Nov 2009
Antwort Antwort
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#1

Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 16:32
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:
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;
Es sollen also alle Controls über die Methoden LoadFromXml, SaveToXml und die property AutoLoadAndSaveToXml verfügen.

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:
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;
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.

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 ? Also Controls, die zusätzlich Interfaces implementieren?

Danke für eure Hilfe!
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 16:47
Zwei mögliche Ansätze, mit denen ich in einer eigenen Komponente arbeite, hätte ich hier:

1) if IsPublishedProp(Control, 'AutoLoadAndSaveToXml') then ... 2) if (Control is TMyEdit) then ... Vielleicht gibts zu IsPublishedProp ein Äquivalent für Methoden...
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.202 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 16:51
Zitat von MatthiasR:
... ohnehin völliger Blödsinn ?
Wäre ein schöner Ansatz wenn du nicht gefahr läufst das du dir permanent ins Knie schießt (Automatische Freigabe von Interfaces obwohl noch objektzeiger vorhanden sind)...

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.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#4

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 16:53
Zitat von GPRSNerd:
1) if IsPublishedProp(Control, 'ReadOnly') then ... 2) if (Control is TMyEdit) then ...
Letzteres wäre auch mein nächster Ansatz gewesen, wobei ich dann alle potentiell möglichen Klassen berücksichtigen müsste. Also:
if (Control is TMyEdit) or (Control is TMyListBox) or (Control is TMyComboBox) or ... Ein simples
if Control.Supports(ILoadAndSavetoXml) then ... 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.
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 16:56
Geht doch mit dem ersten Ansatz, insofern alle deine Kompos z.B. die Property "AutoLoadAndSaveToXml" unterstützen:

if IsPublishedProp(Control, 'AutoLoadAndSaveToXml') then ...
Stefan
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 17:45
Funktioniert der Operator "is" nicht bei Interfaces?
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.202 Beiträge
 
Delphi 10.4 Sydney
 
#7

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 17:46
Zitat von NamenLozer:
Funktioniert der Operator "is" nicht bei Interfaces?
AFAIK nur wenn du für das Interface eine GUID vergibst.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#8

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 17. Nov 2009, 18:00
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:
var
  intf: ILoadAndSaveToXml;
begin
  if Supports(Component, ILoadAndSaveToXml, intf) then
    intf.SaveToXML (...);
end;
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.

Gruß Hawkeye
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#9

Re: Eigene VCL-Komponenten, die ein Interface implementieren

  Alt 18. Nov 2009, 09:02
Zitat von Bernhard Geyer:
Zitat von NamenLozer:
Funktioniert der Operator "is" nicht bei Interfaces?
AFAIK nur wenn du für das Interface eine GUID vergibst.
Das hatte ich zu aller erst ausprobiert. Zumindest bei mir beschwert sich der Compiler, wenn ich
if (Components[i] is ILoadAndSaveToXml) then mit folgender Fehlermeldung:
Zitat:
[Fehler] Unit1.pas(39): Operator ist auf diesen Operandentyp nicht anwendbar
Obwohl ich dem Interface eine GUID verpasst habe. Wenn es direkt mit "is" geklappt hätte, hätte ich die Frage hier nicht gestellt
Zitat von Hawkeye219:
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:
var
  intf: ILoadAndSaveToXml;
begin
  if Supports(Component, ILoadAndSaveToXml, intf) then
    intf.SaveToXML (...);
end;
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.

Gruß Hawkeye
Hallo Hawkeye,

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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:54 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