如何检测TWinControl是否具有FONT属性?

use*_*348 -4 delphi rtti delphi-10.3-rio

我需要更改通过Controls容器控件的属性收集的控件的 FONT 属性:

for i := 0 to ContainerControl.ControlCount - 1 do
begin  
  ContainerControl.Controls[i].Font.Size := 8;  // error  
end;
Run Code Online (Sandbox Code Playgroud)

为此,我需要类型转换ContainerControl.Controls[i]为具有 FONT 属性的 TWinControl 类。有这样的班级吗?或者我如何检测特定的 TWinControl 是否具有 FONT 属性?或者如何将特定 TWincontrol 类型转换为特定其他 TWinControl 的类型?

Rem*_*eau 6

所有可视控件都有一个Font属性,但它位于图层protectedTControl,并且并非所有派生控件都将其提升为published. 如果您只对已发布的 控件感兴趣,Font则必须使用 RTTI 来测试它们,例如:

uses
  ..., TypInfo;

var
  Ctrl: TControl;
  i: Integer;
begin
  for i := 0 to ContainerControl.ControlCount - 1 do
  begin  
    Ctrl := ContainerControl.Controls[i];
    if IsPublishedProp(Ctrl, 'Font') then
      TFont(GetObjectProp(Ctrl, 'Font', TFont)).Size := 8;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

或者:

uses
  ..., TypInfo;

var
  Ctrl: TControl;
  Prop: PPropInfo;
  i: Integer;
begin
  for i := 0 to ContainerControl.ControlCount - 1 do
  begin  
    Ctrl := ContainerControl.Controls[i];
    Prop := GetPropInfo(Ctrl, 'Font', [tkClass]);
    if Prop <> nil then
      TFont(GetObjectProp(Ctrl, Prop, TFont)).Size := 8;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

或者,仅在 Delphi 2010 及更高版本中:

uses
  ..., System.Rtti;

var
  Ctrl: TControl;
  Ctx: TRttiContext;
  Prop: TRttiProperty;
  i: Integer;
begin
  Ctx := TRttiContext.Create;
  try
    for i := 0 to ContainerControl.ControlCount - 1 do
    begin  
      Ctrl := ContainerControl.Controls[i];
      Prop := Ctx.GetType(Ctrl.ClassType).GetProperty('Font');
      if (Prop <> nil) and (Prop.Visibility = TMemberVisibility.mvPublished) then
        TFont(Prop.GetValue(Ctrl).AsObject).Size := 8;
    end;
  finally
    Ctx.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)