Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update fonts recursively on a Delphi form

Tags:

windows

delphi

I'm trying to iterate all the controls on a form and enable ClearType font smoothing. Something like this:

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;

Now, is there a easy way to check if ACtrl have a Font property so i can pass the Font.Handle to somethink like:

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

Thank you in advance.

like image 446
ciscocert Avatar asked Dec 23 '22 14:12

ciscocert


2 Answers

You use TypInfo unit, more specifically methods IsPublishedProp and GetOrdProp.

In your case, it would be something like:

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

A fragment from one of my libraries that should put you on the right path:

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 }
like image 54
gabr Avatar answered Jan 08 '23 17:01

gabr


There's no need to use RTTI for this. Every TControl descendant has a Font property. At TControl level its visibility is protected but you can use this workaround to access it:

type
  THackControl = class(TControl);

ModifyFont(THackControl(AParent.Controls[I]).Font);
like image 42
Ondrej Kelle Avatar answered Jan 08 '23 17:01

Ondrej Kelle