You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置TFontDialog示例文本及相关问题与替代方案咨询

Delphi TFontDialog 相关问题解答

1. 替换TFontDialog的示例文本及默认不显示的原因

示例文本默认不显示的原因

TFontDialog是对Windows原生ChooseFont对话框的封装,原生对话框的示例文本仅在检测到有效的完整字体配置时才会显示。如果只是预先设置了字号,但Font对象的Name、Style等属性没有明确赋值(或者赋值无效),对话框初始化时不会自动触发示例文本的渲染,只有当用户手动调整字体参数(如点击字号、选择字体)后,对话框才会更新示例区域。

替换示例文本的方法

需要通过Windows钩子拦截对话框的创建过程,找到示例文本对应的静态控件并修改内容。以下是Delphi实现代码:

unit FontDialogHook;

interface

uses
  Windows, Messages, Classes, Dialogs, Controls;

type
  TCustomFontDialog = class(TFontDialog)
  private
    FHookHandle: HHOOK;
    FSampleText: string;
    procedure SetSampleText(const Value: string);
    function DialogHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
  protected
    procedure DoShow; override;
    procedure DoClose; override;
  public
    property SampleText: string read FSampleText write SetSampleText;
  end;

implementation

{ TCustomFontDialog }

function TCustomFontDialog.DialogHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
  pCFS: PChooseFont;
  hSampleWnd: HWND;
begin
  Result := 0;
  if nCode = HC_ACTION then
  begin
    case wParam of
      WM_INITDIALOG:
        begin
          pCFS := PChooseFont(lParam);
          // 找到示例文本控件(原生对话框的示例控件ID通常是0x00000400,可根据系统版本调整)
          hSampleWnd := GetDlgItem(pCFS^.hwndOwner, $0400);
          if (hSampleWnd <> 0) and (FSampleText <> '') then
            SendMessage(hSampleWnd, WM_SETTEXT, 0, LPARAM(PChar(FSampleText)));
        end;
    end;
  end;
  Result := CallNextHookEx(FHookHandle, nCode, wParam, lParam);
end;

procedure TCustomFontDialog.DoShow;
begin
  inherited;
  // 设置钩子拦截对话框消息
  FHookHandle := SetWindowsHookEx(WH_CBT, @DialogHook, 0, GetCurrentThreadId);
end;

procedure TCustomFontDialog.DoClose;
begin
  if FHookHandle <> 0 then
    UnhookWindowsHookEx(FHookHandle);
  inherited;
end;

procedure TCustomFontDialog.SetSampleText(const Value: string);
begin
  FSampleText := Value;
end;

end.

使用时,创建TCustomFontDialog实例并设置SampleText属性即可替换示例文本:

var
  FontDlg: TCustomFontDialog;
begin
  FontDlg := TCustomFontDialog.Create(nil);
  try
    FontDlg.SampleText := '自定义示例文本:Hello World 测试';
    FontDlg.Font.Size := 12;
    FontDlg.Font.Name := 'Segoe UI';
    if FontDlg.Execute then
      // 应用字体设置到目标控件
  finally
    FontDlg.Free;
  end;
end;

2. 支持Segoe UI字重的自定义字体对话框方案

原生TFontDialog对Segoe UI的Semibold、Light等字重支持有限,因为它依赖LOGFONT结构,无法直接映射现代字体的字重属性。以下是一个轻量的自定义字体对话框实现,支持完整字重选择:

核心源码(Delphi)

unit CustomFontForm;

interface

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

type
  TFontWeight = (fwThin, fwExtraLight, fwLight, fwRegular, fwMedium, fwSemibold, fwBold, fwExtraBold, fwBlack);

  TfrmCustomFontDialog = class(TForm)
    lblFont: TLabel;
    cboFontName: TComboBox;
    lblSize: TLabel;
    cboFontSize: TComboBox;
    lblWeight: TLabel;
    cboWeight: TComboBox;
    pnlSample: TPanel;
    lblSample: TLabel;
    btnOK: TButton;
    btnCancel: TButton;
    procedure FormCreate(Sender: TObject);
    procedure cboFontNameChange(Sender: TObject);
    procedure cboFontSizeChange(Sender: TObject);
    procedure cboWeightChange(Sender: TObject);
  private
    procedure UpdateSampleText;
  public
    procedure GetSelectedFont(ATargetFont: TFont);
  end;

implementation

{$R *.dfm}

{ TfrmCustomFontDialog }

procedure TfrmCustomFontDialog.FormCreate(Sender: TObject);
begin
  // 填充系统字体列表
  Screen.Fonts.Sort;
  cboFontName.Items.Assign(Screen.Fonts);
  // 填充常用字号
  cboFontSize.Items.AddStrings(['8', '9', '10', '11', '12', '14', '16', '18', '20', '24', '28', '32', '36', '48', '72']);
  // 填充字重选项
  cboWeight.Items.AddStrings(['Thin', 'ExtraLight', 'Light', 'Regular', 'Medium', 'Semibold', 'Bold', 'ExtraBold', 'Black']);

  // 初始化默认值
  cboFontName.Text := 'Segoe UI';
  cboFontSize.Text := '12';
  cboWeight.ItemIndex := Ord(fwRegular);
  UpdateSampleText;
end;

procedure TfrmCustomFontDialog.cboFontNameChange(Sender: TObject);
begin
  UpdateSampleText;
end;

procedure TfrmCustomFontDialog.cboFontSizeChange(Sender: TObject);
begin
  UpdateSampleText;
end;

procedure TfrmCustomFontDialog.cboWeightChange(Sender: TObject);
begin
  UpdateSampleText;
end;

procedure TfrmCustomFontDialog.UpdateSampleText;
var
  Weight: TFontWeight;
begin
  Weight := TFontWeight(cboWeight.ItemIndex);
  lblSample.Font.Name := cboFontName.Text;
  lblSample.Font.Size := StrToIntDef(cboFontSize.Text, 12);

  // Delphi 10.3+支持直接设置Font.Weight,精准匹配字重
  if CompilerVersion >= 32 then
  begin
    case Weight of
      fwThin: lblSample.Font.Weight := fwThin;
      fwExtraLight: lblSample.Font.Weight := fwExtraLight;
      fwLight: lblSample.Font.Weight := fwLight;
      fwRegular: lblSample.Font.Weight := fwRegular;
      fwMedium: lblSample.Font.Weight := fwMedium;
      fwSemibold: lblSample.Font.Weight := fwSemibold;
      fwBold: lblSample.Font.Weight := fwBold;
      fwExtraBold: lblSample.Font.Weight := fwExtraBold;
      fwBlack: lblSample.Font.Weight := fwBlack;
    end;
  end
  else
  begin
    // 低版本Delphi用Style模拟
    lblSample.Font.Style := IfThen(Weight >= fwSemibold, [fsBold], []);
  end;
end;

procedure TfrmCustomFontDialog.GetSelectedFont(ATargetFont: TFont);
var
  Weight: TFontWeight;
begin
  Weight := TFontWeight(cboWeight.ItemIndex);
  ATargetFont.Name := cboFontName.Text;
  ATargetFont.Size := StrToIntDef(cboFontSize.Text, 12);

  if CompilerVersion >= 32 then
    ATargetFont.Weight := TFontWeight(Weight)
  else
    ATargetFont.Style := IfThen(Weight >= fwSemibold, [fsBold], []);
end;

end.

使用方法

var
  FontDlg: TfrmCustomFontDialog;
  TargetFont: TFont;
begin
  TargetFont := TFont.Create;
  try
    FontDlg := TfrmCustomFontDialog.Create(nil);
    try
      if FontDlg.ShowModal = mrOK then
      begin
        FontDlg.GetSelectedFont(TargetFont);
        // 应用到目标控件,比如Label1.Font.Assign(TargetFont);
      end;
    finally
      FontDlg.Free;
    end;
  finally
    TargetFont.Free;
  end;
end;

这个自定义对话框利用Delphi高版本的Font.Weight属性,可精准识别Segoe UI的各种字重样式,避免了原生对话框的局限性。


内容的提问来源于stack exchange,提问作者kgz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:23:14