Aufruf einer (Klasse-)Methode nur anhand des Namens
-
KlausB schrieb:
schau mal in die FAQ
da ist es sehr gut beschriebenKannst Du mir sagen wo? Ich finde es nicht. Vielleicht suche ich an
der falschen Stelle...Gruß,
Alexander Kempf
-
junix schrieb:
Ah jetzt... KlausB hat recht in der FAQ gibts im Abschnitt "komponenten" was dazu "Zugriff aber nicht durch Namen"...
Den Eintrag hatte ich schon gesehen, aber das löst mein Problem nicht.
Hier ist mal ein Ausschnitt aus meinem Code:TForm* form; //ein paar Zeilen ausgelassen TMetaClass* mc; for (int i=0; i<form->ComponentCount; ++i) { mc = form->Components[i]->ClassType(); while (!mc->ClassNameIs("TComponent") && !mc->ClassNameIs("TControl")) mc = mc->ClassParent(); if (mc->ClassNameIs("TControl")) { // Einfach mal nach TButton konvertieren... // ... ist aber Schweinerei! ((TButton*) form->Components[i])->OnMouseMove = &FormMouseMove; // FormMouseMove ist irgendwo anders definiert } }
Der obige Code funktioniert, aber einfach mal aus Spaß auf TButton casten,
ist irgendwie nicht so sauber. Hier ist es natürlich auch eine Eigenschaft,
aber mit Methoden hat man das gleiche Problem.Gruß,
Alexander Kempf
-
Entweder du fragst nach ClassNameIs("TButton") dann kannst du einfach mal drauf los casten oder du verwendest dynamic_cast. (Belies dich dazu ebenfalls in der FAQ) der C-Style-Cast sollte eigentlich seit C++ nichtmehr verwendet werden...
-junix
-
junix schrieb:
Entweder du fragst nach ClassNameIs("TButton") dann kannst du einfach mal drauf los casten oder du verwendest dynamic_cast. (Belies dich dazu ebenfalls in der FAQ) der C-Style-Cast sollte eigentlich seit C++ nichtmehr verwendet werden...
-junix
In dem Beispiel kann ich keinen dynamic_cast verwenden, sonst funktioniert's
nur für TButton, was ja auch eigentlich sehr sinnvoll ist. Mein Problem ist,
daß ein Formular ja normalerweise nicht nur aus Buttons besteht;)
Es wird sehr viele Controls unterschiedlicher Typen besitzen, die aber alle
von TControl erben und deswegen potentiell eine Eigenschaft OnMouseMove be-
sitzen könnten.
Natürlich kann ich in einer riesigen if-else-if-Kette versuchen alle Typen
abzuprüfen. Aber was, wenn ein Control auf dem Formular ist, das nicht in
meiner Liste ist? Mit meinem C-Style-Cast auf TButton funktioniert das, weil
es keinerlei Typsicherheit bietet, aber es ist nicht gerade schön.Gruß,
Alexander Kempf
-
vielleicht sagst du auch mal, was genau du erreichen willst, eventuell gibt es ja einen anderen lösungsweg zu deinem problem...
-
Du könntest auch von allen Komponenten neue Ableiten, die dann mit Hilfe von ActiveX und Typelibraries, auch ihr Methoden als String preisgeben würden.
-
Jede Klasse könnte eine Map mit dem String als Schlüssel und eine Methodenzeiger als Wert besitzen.
-
Würde sowas funktionieren ?
class TNewControl: public TControl { public: __property OnMouseMove; }; ... // Einfach mal nach TButton konvertieren... // ... ist aber Schweinerei! TNewControl *ctrl = dynamic_cast<TNewControl*>(form->Components); if (ctrl) ctrl->OnMouseMove = &FormMouseMove; ...
-
bIce schrieb:
Du könntest auch von allen Komponenten neue Ableiten, die dann mit Hilfe von ActiveX und Typelibraries, auch ihr Methoden als String preisgeben würden.
kommt mir sehr aufwendig vor und ich kenne u.U. auch nicht alle Komponenten
im Vorfeld. Dann wird's mit dem Ableiten schwierig...
-
Anonymous schrieb:
Jede Klasse könnte eine Map mit dem String als Schlüssel und eine Methodenzeiger als Wert besitzen.
Kann ich das z.B. bei TButton o.ä. selbst beeinflussen?
Ich glaube, das habe ich nicht ganz verstanden.
-
bIce schrieb:
Würde sowas funktionieren ?
class TNewControl: public TControl { public: __property OnMouseMove; }; ... // Einfach mal nach TButton konvertieren... // ... ist aber Schweinerei! TNewControl *ctrl = dynamic_cast<TNewControl*>(form->Components); if (ctrl) ctrl->OnMouseMove = &FormMouseMove; ...
Wegen des dynamic_cast dürfte sowas nicht funktionieren (oder?). Lasse ich
den dynamic_cast weg, habe ich das gleiche wie vorher, nur mit einer selbst-
geschriebenen Klasse anstatt TButton. (Oder liege ich völlig falsch?)
-
Sunday schrieb:
vielleicht sagst du auch mal, was genau du erreichen willst, eventuell gibt es ja einen anderen lösungsweg zu deinem problem...
Also, ich möchte eine Komponente erstellen, die immer, wenn ein Formular in
der Anwendung geladen wird, dieses Formular übersetzt. D.h. ich gehe alle
Komponenten auf dem Formular durch und setze Caption, Text oder auch andere
Eigenschaften. Welche Eigenschaften eine solche Komponente hat, kann ich
dabei nicht vorher wissen: Es können ja auch Komponenten von Dritt-Her-
stellern sein.
Deshalb möchte ich zur Laufzeit herausfinden, welche Eigenschaften eine
Komponente hat und möchte auch den Wert ändern können.
Ist mein Problem jetzt etwas besser verständlich?
-
Alexander Kempf schrieb:
Welche Eigenschaften eine solche Komponente hat, kann ich dabei nicht vorher wissen: Es können ja auch Komponenten von Dritt-Herstellern sein.
Wenn du nicht weisst, um was für Komponenten es sich handelt, woher willst du denn dann wissen, was du da eigentlich reinschreiben sollst?
-
Du kannst anstelle nach TButton auch nach einem gemeinsamen Vorfahren casten(natürlich mit dynamic_cast), der die gewünschte Eigenschaft oder Methode hat, um die Anzahl der Fälle zu reduzieren. Dazu zeigt dir die Hilfe die Objekthierarchie an.
-
Geo:
Damit (StichWort InheritsFrom()) kann man den Umfang der Abfragen zwar reduzieren, am "Problem" des if/else-Konstukts ändert sich aber nichts. Und wenn eine (3rd-party)Komponente von einer in der Hierarchie hochstehenden Klasse wie zB. TWinControl direkt abgeleitet wurde nützt dir das ja auch nicht wirklich etwas.
-
Jansen schrieb:
Alexander Kempf schrieb:
Welche Eigenschaften eine solche Komponente hat, kann ich dabei nicht vorher wissen: Es können ja auch Komponenten von Dritt-Herstellern sein.
Wenn du nicht weisst, um was für Komponenten es sich handelt, woher willst du denn dann wissen, was du da eigentlich reinschreiben sollst?
Ich stelle mir das so vor, daß die Informationen z.B. aus einer XML-Datei
oder aus einer Datenbank kommen. Wie die Daten da reinkommen ist ein anderes
Thema, aber auch dafür habe ich schon (noch nicht ganz konkrete) Vorstellungen.
Es gibt ja aber auf jeden Fall für visuelle Komponenten Eigenschaften die mit
großer Wahrscheinlichkeit wirklich existieren, wie "Caption" oder "Text". Die
könnte man dann mal "auf Verdacht" setzen und das ganze in einen try/catch-
Block setzen.
Schwierig, schwierig...
-
Jansen schrieb:
Geo:
Damit (StichWort InheritsFrom()) kann man den Umfang der Abfragen zwar reduzieren, am "Problem" des if/else-Konstukts ändert sich aber nichts. Und wenn eine (3rd-party)Komponente von einer in der Hierarchie hochstehenden Klasse wie zB. TWinControl direkt abgeleitet wurde nützt dir das ja auch nicht wirklich etwas.Genau.
Ich glaube, hier hat mich jemand verstandenGanz schön schwer, was zu er-
klären, so daß es alle verstehen.