如何检测字体家族内特定样式字体是否已安装(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
相关产品推荐
相关产品推荐

