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

如何检测字体家族内特定样式字体是否已安装(VCL项目适用)

检测VCL中字体家族的具体样式

在VCL环境下,Screen.Fonts仅返回字体家族名称,无法直接获取家族内的细分样式(如Bold、Italic等)。要验证特定样式是否安装,需借助Windows API实现更细致的字体枚举,以下是两种可行方案:

方案1:通过EnumFontFamiliesEx API枚举字体详情

这是最精准的方式,通过枚举系统所有字体,筛选目标家族的具体样式属性:

实现代码

type
  TFontStyleInfo = record
    IsBold: Boolean;
    IsItalic: Boolean;
    // 可扩展其他属性如Underline、Strikeout等
  end;
  TFontStyleList = array of TFontStyleInfo;

var
  TargetFamily: string;
  FontStyles: TFontStyleList;

function EnumFontProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
var
  StyleInfo: TFontStyleInfo;
begin
  if LogFont.lfFaceName = TargetFamily then
  begin
    StyleInfo.IsBold := (LogFont.lfWeight >= FW_BOLD);
    StyleInfo.IsItalic := (LogFont.lfItalic <> 0);
    SetLength(FontStyles, Length(FontStyles) + 1);
    FontStyles[High(FontStyles)] := StyleInfo;
  end;
  Result := 1; // 继续枚举所有字体
end;

// 调用示例:检查Roboto Bold是否存在
procedure CheckRobotoBoldAvailability;
var
  DC: HDC;
  LogFont: TLogFont;
  HasBold: Boolean;
begin
  TargetFamily := 'Roboto';
  SetLength(FontStyles, 0);
  HasBold := False;
  
  DC := GetDC(0);
  try
    ZeroMemory(@LogFont, SizeOf(LogFont));
    LogFont.lfCharSet := DEFAULT_CHARSET;
    StrPCopy(LogFont.lfFaceName, TargetFamily);
    EnumFontFamiliesEx(DC, LogFont, @EnumFontProc, 0, 0);
  finally
    ReleaseDC(0, DC);
  end;

  for var Style in FontStyles do
  begin
    if Style.IsBold then
    begin
      HasBold := True;
      Break;
    end;
  end;

  if HasBold then
    ShowMessage('Roboto Bold 已安装')
  else
    ShowMessage('Roboto Bold 未安装');
end;

方案2:尝试创建字体并验证样式

通过直接创建指定样式的字体,判断系统是否实际使用了目标样式(而非模拟替换):

实现代码

function IsSpecificFontStyleInstalled(const FamilyName: string; WantBold: Boolean; WantItalic: Boolean): Boolean;
var
  TestFont: TFont;
begin
  TestFont := TFont.Create;
  try
    TestFont.Name := FamilyName;
    TestFont.Bold := WantBold;
    TestFont.Italic := WantItalic;
    // 若系统替换了样式,字体属性会和设置值不一致
    Result := (TestFont.Name = FamilyName) and (TestFont.Bold = WantBold) and (TestFont.Italic = WantItalic);
  finally
    TestFont.Free;
  end;
end;

// 调用示例
if IsSpecificFontStyleInstalled('Roboto', True, False) then
  ShowMessage('Roboto Bold 已安装')
else
  ShowMessage('Roboto Bold 未安装');

注意事项

  • 方案2实现简单,但部分场景下系统会自动模拟缺失的样式(比如给普通Roboto加粗),可能导致判断误差,方案1的准确性更高。
  • 枚举字体时,若目标字体使用特定字符集(如Unicode),需在TLogFont中设置对应的lfCharSet参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:22:41