![]() |
Bei Komponenten einen Untereintrag (Font -> Size) ändern
Hallo,
ich beiß mir grade die Zähne aus am Problem, die Schriftgröße von Buttons (TJvSpeedbuttons) zu ändern. Eigentlich habe ich den passenden Code (von Marabu (Danke!)) schon gefunden, aber der klappt eben nicht ganz:
Delphi-Quellcode:
Mit dem Abruf:
procedure SetProperty(c: TComponent; cClass, cName: String; cValue: Variant);
var i: Integer; ppi: PPropInfo; begin if SameText(c.ClassName, cClass) then begin ppi := GetPropInfo(c, cName); if Assigned(ppi) then SetPropValue(c, cName, cValue); end; for i := 0 to Pred(c.ComponentCount) do SetProperty(c.Components[i], cClass, cName, cValue); end;
Delphi-Quellcode:
kann ich die Farbe ändern, klappt also super.
SetProperty(Application, 'TJvSpeedbutton', 'Color', clRed);
Aber eben die 'Size' von 'Font' nicht, da die ja ein Untereintrag ist! Geht das gar nicht so? Oder wie müsste der Befehl denn aussehen? SetProperty(Application, 'TButton', 'Font', 10); :gruebel: <- hier müsste ja noch 'size' stehen, also: SetProperty(Application, 'TButton', 'Font', 'size', 10) o. ä. Wie kann man das machen? Für Hilfe bin ich sehr dankbar... nach 2 Tagen ist der Frust doch recht groß! :roll: litotes |
Re: Bei Komponenten einen Untereintrag (Font -> Size) änd
Du mußt das rekursiv für das Font-Objekt machen.
|
Re: Bei Komponenten einen Untereintrag (Font -> Size) änd
Hier mal eine allgemeine Routine, die du mit voll qualifizierten Eigenschaftsnamen füttern kannst:
Delphi-Quellcode:
Beispielhafte Aufrufe:
uses
TypInfo; { Interne Routine für beide Varianten von SetPropertyByName } procedure SetNestedProp(Obj: TObject; Prop: string; Value: Variant); var p: Integer; i: PPropInfo; begin repeat p := Pos('.', Prop); if p = 0 then begin i := GetPropInfo(Obj, Prop); if i <> nil then SetPropValue(Obj, i, Value); Obj := nil; end else begin // GetObjectProp liefert nil, falls die // Eigenschaft nicht gefunden wird. Obj := GetObjectProp(Obj, Copy(Prop, 1, p - 1)); Delete(Prop, 1, p); end; until Obj = nil; end; { Variante 1: <ClassName> ist der Klassenname, Vererbung wird nicht berücksichtigt. <PropertyName> kann Punkte enthalten, die Eigenschaften von Eigenschaften bezeichnen (z.B. Font.Size). <ChildrenOnly> gibt an, ob die Eigenschaft frühestens bei Unterkomponenten gesetzt werden soll. } procedure SetPropertyByName(Component: TComponent; const ClassName, PropertyName: string; Value: Variant); overload; procedure SetRecursive(Obj: TComponent); var k: Integer; begin if Obj.ClassNameIs(ClassName) then SetNestedProp(Obj, PropertyName, Value); for k := 0 to Obj.ComponentCount - 1 do SetRecursive(Obj.Components[k]); end; begin SetRecursive(Component); end; { Variante 2: <BaseClass> ist die Basisklasse, Vererbung wird berücksichtigt. Ansonsten wie oben. } procedure SetPropertyByName(Component: TComponent; BaseClass: TClass; const PropertyName: string; Value: Variant); overload; procedure SetRecursive(Obj: TComponent); var k: Integer; begin if Obj is BaseClass then SetNestedProp(Obj, PropertyName, Value); for k := 0 to Obj.ComponentCount - 1 do SetRecursive(Obj.Components[k]); end; begin SetRecursive(Component); end;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin // Bei allen Buttons die Schriftgröße auf 12 setzen SetPropertyByName(Self, 'TButton', 'Font.Size', 12); // Bei allen Checkboxen die Schriftart ändern SetPropertyByName(Self, 'TCheckBox', 'Font.Name', 'Times New Roman'); // Bei allen Nachfahren von TCustomEdit (TEdit, TMemo, TRichEdit) // die Schriftfarbe ändern SetPropertyByName(Self, TCustomEdit, 'Font.Color', clRed); // Bei allen Nachfahren von TButtonControl (TButton, TCheckBox, TRadioButton) // den Schriftstil auf "kursiv" setzen. SetPropertyByName(Self, TButtonControl, 'Font.Style', '[fsItalic]'); // Bei *ALLEN* Controls die Hintergrundfarbe auf Blau ändern SetPropertyByName(Self, TControl, 'Color', clBlue, True); end; |
Re: Bei Komponenten einen Untereintrag (Font -> Size) änd
Hallo,
erstmal vielen, vielen Dank an Flocke für den fertigen Code! :thumb: Leider compiliert er nicht, und zwar folgenden Teil:
Delphi-Quellcode:
Und zwar beschwert er sich über die Zeile:
procedure SetNestedProp(Obj: TObject; Prop: string; Value: Variant);
var p: Integer; i: PPropInfo; begin repeat p := Pos('.', Prop); if p = 0 then begin i := GetPropInfo(Obj, Prop); if i <> nil then SetPropValue(Obj, i, Value); Obj := nil; end else begin // GetObjectProp liefert nil, falls die // Eigenschaft nicht gefunden wird. Obj := GetObjectProp(Obj, Copy(Prop, 1, p - 1)); Delete(Prop, 1, p); end; until Obj = nil; end;
Delphi-Quellcode:
Fehlermeldung: Inkompatible Typen: String und PPropInfo.
SetPropValue(Obj, i, Value);
Da ich den Code leider nicht so gut verstehe, um darin erfolgreich herumzuwerkeln (bin noch Anfänger), die Fragen: Was kann ich da tun? Muss ich da einen Typecast machen, und wenn ja, wie? Kompiliert er bei euch? Bei Flocke? Vielen Dank, litotes :) |
Re: Bei Komponenten einen Untereintrag (Font -> Size) änd
Bei mir compilierts (D2007), die Funktion ist überladen.
Ändere einfach mal folgende Zeile:
Delphi-Quellcode:
SetPropValue(Obj, Prop, Value);
|
Re: Bei Komponenten einen Untereintrag (Font -> Size) änd
Herzlichen Dank Flocke!
Jetzt kompilierts... Kannst du mir auch noch den Unterschied erklären? Litotes |
Re: Bei Komponenten einen Untereintrag (Font -> Size) änd
Zitat:
Die Variante mit dem String-Parameter ruft bei mir eigentlich nur die andere Variante auf und übergibt als Parameter das Ergebnis von GetPropInfo. Da wir das schon haben, ist es natürlich effizienter das direkt zu übergeben, anstatt die Klasse nochmal anhand des Namens suchen zu lassen. Ich habe gerade noch einmal nachgeschaut: die überladene Funktion mit PPropInfo-Parameter gibt's seit Delphi 2005, bis einschließlich Delphi 7 gab's nur die Variante mit dem String-Parameter. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:15 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