Компонент Delphi: как использовать родительский шрифт?

У меня есть специальный компонент, который использует ParentFont .

] Во время построения моего компонента я вижу, что изначально для шрифта компонента установлен шрифт по умолчанию MS Sans Serif :

constructor TCustomWidget.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);

   ...
end;

Проверка показывает Self.Font.Name: 'MS Sans Serif'

Некоторое время спустя шрифт моего компонента обновляется, чтобы отразить шрифт родителя:

TReader.ReadComponent(nil)
   SetCompName
      TControl.SetParentComponent
         TControl.SetParent
            TWinControl.InsertControl
               AControl.Perform(CM_PARENTFONTCHANGED, 0, 0);

И после этого все отлично, шрифт моего компонента был изменен на шрифт родителя (например, `MS Shell Dlg 2 ').

Проблема в том, что мои дочерние элементы управления не синхронизируются со своим родительским шрифтом (то есть с моим компонентом).

В конструкторе компонентов я создаю дочерние элементы управления:

constructor TCustomWidget.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);

   ...
   CreateComponents;
end;

procedure TCustomWidget.CreateComponents;
begin
   ...
   FpnlBottom := TPanel.Create(Self);
   FpnlBottom.Caption := '';
   FpnlBottom.Parent := Self;
   FpnlBottom.Align := alBottom;
   FpnlBottom.Height := 46;
   FpnlBottom.ParentFont := True;
   ...
end;

И изначально мой FpnlBottom также имеет шрифт по умолчанию MS Sans Serif .

Позже, когда шрифт моего компонента был обновлен до его родительского шрифта (например, MS Shell Dlg 2 ), дочерние элементы управления не обновляют свои шрифты и осталось MS Sans Serif .

  • Почему свойство моего дочернего элемента управления ParentFont не соблюдается?
  • Как заставить работать свойство моего дочернего элемента управления ParentFont ?

Образец кода

Инструмент два часа, чтобы сократить его до управляемого, воспроизводимого кода:

unit WinControl1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;

type
    TWidget = class(TWinControl)
    private
        FTitleLabel: Tlabel;
        FpnlBottom: TPanel;

        procedure CreateComponents;
    protected
        procedure FontChange(Sender: TObject);
    public
        constructor Create(AOwner: TComponent); override;
    published
        {Inherited from TWinControl}
        property Align;
        property Font;
        property ParentFont;
    end;

    procedure Register;

implementation

procedure Register;
begin
    RegisterComponents('Samples',[TWidget]);
end;

{ TCustomWidget }

constructor TWidget.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);

    ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible];

    Self.Width := 384;
    Self.Height := 240;

    Self.Font.OnChange := FontChange;

    CreateComponents;
end;

procedure TWidget.CreateComponents;
begin
    FpnlBottom := TPanel.Create(Self);
    FpnlBottom.Parent := Self;
    FpnlBottom.Align := alBottom;
    FpnlBottom.Color := clWindow;
    FpnlBottom.Caption := 'FpnlBottom';
    FpnlBottom.Height := 45;

    FTitleLabel := TLabel.Create(Self);
    FTitleLabel.Parent := FpnlBottom;
    FTitleLabel.Left := 11;
    FTitleLabel.Top := 11;
    FTitleLabel.Caption := 'Hello, world!';
    FTitleLabel.AutoSize := True;
    FTitleLabel.Font.Color := $00993300;
    FTitleLabel.Font.Size := Self.Font.Size+3;
    FTitleLabel.ParentFont := False;
end;

procedure TWidget.FontChange(Sender: TObject);
begin
    //title label is always 3 points larger than the rest of the content
    FTitleLabel.Font.Name := Self.Font.Name;
    FTitleLabel.Font.Size := Self.Font.Size+3;

    OutputDebugString(PChar('New font '+Self.Font.Name));
end;

end.
5
задан Ian Boyd 14 February 2011 в 22:16
поделиться