6
votes

I'm using Delphi's GetObjectProp function to get the properties of the form components, I get all the properties of several components, but I can not get the TextSettings.Font.Style (Bold, Italic, ...) property of components like TLabel for example. I need to know if the component text is bold or italic. The procedure I am working on trying to get these properties follows below:

procedure Tfrm1.aoClicarComponente(Sender: TObject);
var
  TextSettings: TTextSettings;
  Fonte: TFont;
  Estilo: TFontStyle;
  Componente_cc: TControl; 
begin
Componente_cc := TControl(Label1);
if IsPublishedProp(Componente_cc, 'TextSettings') then
    begin
      TextSettings := GetObjectProp(Componente_cc, 'TextSettings') as TTextSettings;
        if Assigned(TextSettings) then
           Fonte := GetObjectProp(TextSettings, 'Font') as TFont;
        if Assigned(Fonte) then
           Estilo := GetObjectProp(Fonte, 'Style') as TFontStyle; // <-- error in this line 
        if Assigned(Estilo) then
           Edit1.text := GetPropValue(Estilo, 'fsBold', true);
    end
end; 

The error displayed on the line where I marked above is.

[dcc64 Error] uPrincipal.pas(1350): E2015 Operator not applicable to this operand type

What am I doing wrong?

1
In the example I simplified the code for better understanding, but in the actual application it is more complex, with components created at runtime and can be of any Class, so I'm using rtti. I changed it to its TFontStyles segestao but the error remains.Anderson
Style is of TFontStyles type and it's not an object type but set of type property. And fsBold is not a property but a possible member of that set.Victoria
But how do I get the property if it is not a object type?Anderson
Use GetOrdProp. Set is just an ordinal value that you can query for members by in operator. Or if you want to print out the set members as string, you can use GetSetProp.Victoria

1 Answers

6
votes

GetObjectProp(Fonte, 'Style') will not work since Style is not an object-based property to begin with, it is a Set-based property. And GetPropValue(Estilo, 'fsBold', true) is just plain wrong (not that you would get far enough to call it anyway), because fsBold is not a property, it is a member of the TFontStyle enum. To retreive the Style property value, you would have to use GetOrdProp(Fonte, 'Style'), GetSetProp(Fonte, 'Style'), or GetPropValue(Fonte, 'Style') instead (as an integer, string, or variant, respectively).

That being said, once you have retrieved the TextSettings object, you don't need to use RTTI at all to access its Font.Style property, just access the property directly.

Try this instead:

procedure Tfrm1.aoClicarComponente(Sender: TObject);
var
  Componente_cc: TControl;
  TextSettings: TTextSettings;
begin
  Componente_cc := ...;
  if IsPublishedProp(Componente_cc, 'TextSettings') then
  begin
    TextSettings := GetObjectProp(Componente_cc, 'TextSettings') as TTextSettings;
    Edit1.Text := BoolToStr(TFontStyle.fsBold in TextSettings.Font.Style, true);
  end;
end; 

A better (and preferred) solution is to not use RTTI at all. FMX classes that have a TextSettings property also implement the ITextSettings interface for exactly this situation, eg:

procedure Tfrm1.aoClicarComponente(Sender: TObject);
var
  Componente_cc: TControl;
  Settings: ITextSettings;
begin
  Componente_cc := ...;
  if Supports(Componente_cc, ITextSettings, Settings) then
  begin
    Edit1.Text := BoolToStr(TFontStyle.fsBold in Settings.TextSettings.Font.Style, true);
  end;
end; 

Read Embarcadero's documentation for more details:

Setting Text Parameters in FireMonkey