Ermitteln, ob ein Control eine Caption-Eigenschaft hat
-
Wie kann ich herausbekommen, ob ein Control eine Caption-Eigenschaft hat?
Ich möchte in einer verschachtelten Schleife alle Controls einer Form ermitteln, und wenn sie eine Caption-Eigenschaft haben, diese dann setzen. Dazu lade ich mir mit Hilfe des Control-Namens den Text aus einer Datei.
Bisher mache ich das so:
void Language::SetControlCaption(TControl *Control, AnsiString saCaption) { if (saCaption.Length()) { try { if (Control->ClassNameIs("TButton")) { TButton *Button = dynamic_cast<TButton *>(Control); Button->Caption = "Toll"; } else if (Control->ClassNameIs("TGroupBox")) { TGroupBox *GroupBox = dynamic_cast<TGroupBox *>(Control); GroupBox->Caption = "Toll"; } } catch ( ... ) { // erst mal nix } } }
Diese Methode hat natürlich den Nachteil, das ich alle Controls kennen muß, die eine Caption-Eigenschaft haben. Wie geht das eleganter?
Gruß Nighthero
-
Naja Caption Eigentschaft is bissl blöd weil Borland die mehrmals deklariert hat und nur der Name gleich ist, sonst könntest du einfach ein paar Ebenen Tiefer gehen in der Klassenhierachie und das testen.
Was vieleicht gehen würde wäre vieleicht
try { dynamic_cast<TLabel*>(Control) -> Caption = "hallo"; } catch(...) { // hat kein Caption }
[ Dieser Beitrag wurde am 09.05.2003 um 11:58 Uhr von dreaddy editiert. ]
-
Das löst aber mein Problem nicht, da ich ja den dynamic_cast auch wieder mit allen möglichen Klassen machen muß, die eine Caption-Eigenschaft haben. Wenn ich ein neues Control in meine Anwendung einfüge, das ich in der Liste noch nicht drin habe, wird es übergangen.
Ich stelle mir also irgendwie eine allgemeingültige Form von diesem Code vor:
try { Form->Controls[iCount]->Caption = "MyCaption"; } catch (...) { // keine Caption-Eigenschaft }
Gruß Nighthero
-
das ist ja grad der Witz an der Sache, du änderst so von allen Viechern die ein "Caption" haben die Captions, ansonsten kommt ein Fehler den du dir catcht...
es geht ja auch folgendes:
TButton* hi_im_a_button = new TButton; ((TLabel*)hi_im_a_button)->Caption = "bin zwar kein Label, aber geht weil ich die Eigenschaft Caption habe";
*edit* verklammert
[ Dieser Beitrag wurde am 09.05.2003 um 13:05 Uhr von dreaddy editiert. ]
-
Hi,
@Nighthero: Was du vor hast ist recht unsauber. Wähle einen anderen Ansatz. Was möchtest du damit erreichen ?
-
Andreas, ich muß Dir vollkommen zustimmen. Ich hasse solche try/catch Orgien, auch dynamic_cast und Konsorten versuche zu vermeiden wo es nur geht und suche lieber andere Lösungswege. In diesem Caption-Fall könnte man sich entweder der Tag-Eigenschaft bedienen, oder, was ich schon gemacht habe, man gibt dem Control im Namen ein bestimmtes Merkmal mit, z.B. lässt man den Namen jedes Objekts, welches einen Canvas hat welchem man bepinseln will, mit "Can" anfangen. Den Namen kann man leicht abfragen und im Programm entsprechend reagieren ohne zu tryen und zu catchen.
Das verlangt natürlich ein gewisses Maß an Kreativität ...
-
Ich möchte auf diese Art mein Programm mehrsprachig machen. Der Vorteil bei Textdateien ist eben der, daß jeder, dem die Texte nicht passen, diese ändern kann, oder wenn jemand eine weitere Sprache hinzufügen möchte, geht das auch ohne Programmierkenntnisse.
Gruß Nighthero
-
hm. dann würdich lieber eine kleine Paradox Tabelle zusammen mit nem Übersetzungsprogramm(ein dbgrid und ein paar Knöpfe)nehmen mit je einer Spalte für jede Sprache.
Hab ich jedenfalls bei mir so gemacht(so 2000 Sätze) und abgesehen von der eigentlichen Übersetzung ist die Arbeit zum hinzufügen einer neuen Sprache jetzt gleich 0.
Vorteil ist auch das der Übersetzer nicht alles kaputt macht wenn er 2 mal return drückt oder mal ein " vergisst.
Und das du lustige Funktionen wie "Alle ersetzen", "kopieren" usw einbauen kannst.
-
hm,
sicherlich ist das auch eine Frage bei wievielen Elementen und Formularen und bei wievielen Anwendungen du sowas machen möchtest. Wenn du generell diese Art und Weise der Sprachhandhabung in deinen Anwendungen umsetzen möchtest, so würde ich den notwendige Komponeten eine Interface- Klasse zur Verfügung stellen, die die Umsetzung der Textzuordnung realisiert. Nicht die Anwendung muss dann die Texte verteilen, sondern die Komponenten holen sich über das Interface die Texte selbst ->Objektorientiert. Allerdings musst du ein solches Interface dann auch selbst implementieren. Damit eine Komponente mit solch ein Interface interagieren kann, musst du dann aber auch die Komponenten anpassen, was sich als aufwendig erweisen sollte.
Wir haben unsere Komponeten auf einen gemeinsammen Nenner gebracht. Alles, von Labels bis zum DBGrid sind von einer eigenen Basisklasse abgeleitet. Dadurch können wir solche Interface- Lösungen ohne Probleme implementieren. Wir können da sogar noch viel weiter gehen...
Wenn du diesen Aufwand nicht treiben möchtest, so nimm dreaddy's Lösung oder benutz eine *.ini- Datei für die Formulare.
Noch eine Möglichkeit wäre die Formulare über Streams direkt bei Programmstart aus einer Datei zu laden. Diese würden dann so aussehen wie die *.dfm- Dateien. Sowas würde man ohne großen Aufwand realisieren können...