Рекурсивное обновление шрифтов в форме Delphi - PullRequest
4 голосов
/ 01 октября 2008

Я пытаюсь перебрать все элементы управления в форме и включить сглаживание шрифтов ClearType. Примерно так:

procedure TForm4.UpdateControls(AParent: TWinControl);
var
  I: Integer;
  ACtrl: TControl;
  tagLOGFONT: TLogFont;
begin
  for I := 0 to AParent.ControlCount-1 do
  begin
    ACtrl:= AParent.Controls[I];

    // if ParentFont=False, update the font here...

    if ACtrl is TWinControl then
      UpdateControls(Ctrl as TWinControl);
  end;
end;

Теперь есть простой способ проверить, есть ли у ACtrl свойство Font, чтобы я мог передать Font.Handle как-то так:

GetObject(ACtrl.Font.Handle, SizeOf(TLogFont), @tagLOGFONT);
tagLOGFONT.lfQuality := 5;
ACtrl.Font.Handle := CreateFontIndirect(tagLOGFONT);

Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 01 октября 2008

Вы используете модуль TypInfo, точнее методы IsPublishedProp и GetOrdProp.

В вашем случае это будет что-то вроде:

if IsPublishedProp(ACtrl, 'Font') then
  ModifyFont(TFont(GetOrdProp(ACtrl, 'Font')))

Фрагмент одной из моих библиотек, который должен указать вам правильный путь:

function ContainsNonemptyControl(controlParent: TWinControl;
  const requiredControlNamePrefix: string;
  const ignoreControls: string = ''): boolean;
var
  child   : TControl;
  iControl: integer;
  ignored : TStringList;
  obj     : TObject;
begin
  Result := true;
  if ignoreControls = '' then
    ignored := nil
  else begin
    ignored := TStringList.Create;
    ignored.Text := ignoreControls;
  end;
  try
    for iControl := 0 to controlParent.ControlCount-1 do begin
      child := controlParent.Controls[iControl];
      if (requiredControlNamePrefix = '') or
         SameText(requiredControlNamePrefix, Copy(child.Name, 1,
           Length(requiredControlNamePrefix))) then
      if (not assigned(ignored)) or (ignored.IndexOf(child.Name) < 0) then
      if IsPublishedProp(child, 'Text') and (GetStrProp(child, 'Text') <> '') then
        Exit
      else if IsPublishedProp(child, 'Lines') then begin
        obj := TObject(cardinal(GetOrdProp(child, 'Lines')));
        if (obj is TStrings) and (Unwrap(TStrings(obj).Text, child) <> '') then
          Exit;
      end;
    end; //for iControl
  finally FreeAndNil(ignored); end;
  Result := false;
end; { ContainsNonemptyControl }
5 голосов
/ 26 ноября 2008

Нет необходимости использовать RTTI для этого. Каждый потомок TControl имеет свойство Font. На уровне TControl его видимость защищена, но вы можете использовать этот обходной путь для доступа к нему:

type
  THackControl = class(TControl);

ModifyFont(THackControl(AParent.Controls[I]).Font);
0 голосов
/ 17 марта 2014

Вот пример C ++ Builder для ответа TOndrej :

struct THackControl : TControl
{
    __fastcall virtual THackControl(Classes::TComponent* AOwner);
    TFont* Font() { return TControl::Font; };
};

for(int ControlIdx = 0; ControlIdx < ControlCount; ++ControlIdx)
{
    ((THackControl*)Controls[ControlIdx])->Font()->Color = clRed;
}
0 голосов
/ 26 ноября 2008

Стоит упомянуть еще одну вещь. Каждый элемент управления имеет свойство ParentFont, которое - если оно установлено - позволяет выбору шрифта формы распространяться на каждый элемент управления. Я стараюсь убедиться, что ParentFont установлен в true, где это возможно, что также облегчает создание тем в соответствии с текущей ОС.

В любом случае, конечно, вам не нужно ничего делать, чтобы включить сглаживание ClearType? Это должно произойти автоматически, если вы используете шрифт TrueType и пользователь включил «эффект» Cleartype.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...