Как определить, имеет ли TWinControl свойство FONT? - PullRequest
0 голосов
/ 24 февраля 2020

Мне нужно изменить свойство FONT элементов управления, собранных с помощью свойства Controls элемента управления контейнера:

for i := 0 to ContainerControl.ControlCount - 1 do
begin  
  ContainerControl.Controls[i].Font.Size := 8;  // error  
end;

Для этого мне нужно будет выполнить тип ContainerControl.Controls[i] для класса TWinControl, имеющего свойство FONT. Есть ли такой класс? Или как я могу определить, имеет ли указанный c TWinControl свойство FONT? Или как можно указать тип c TWincontrol для типа c другого TWinControl?

Ответы [ 2 ]

4 голосов
/ 25 февраля 2020

Все визуальные элементы управления имеют свойство Font, но оно равно protected на уровне TControl, и не все производные элементы управления повышают его до 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;

В качестве альтернативы:

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;

В качестве альтернативы, только в 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;
2 голосов
/ 24 февраля 2020

Каждый TControl имеет свойство Font, оно просто защищено. Таким образом, вы можете использовать обычный трюк :

type
  TControlAccess = class(TControl);

TControlAccess(MyControl).Font.Size := 10;
...