从字体名称查找字体文件






4.56/5 (19投票s)
如何根据字体的显示名称找到字体文件的名称
引言
这个问题似乎经常在新闻组中循环出现,所以我认为分享一下我提出的一个解决方案。 问题是,给定字体的显示名称(例如,Arial),确定已安装字体文件的名称(例如,ARIAL.TTF)。 解决方案涉及枚举注册表中列出的字体,首先检查 Windows 操作系统版本。
它的作用
演示 FontFileTest 项目展示了如何从字体的显示名称中检索字体文件名(例如,您将在 MS Word 字体组合框中看到的名称)。所有 Windows 的 Win32 版本,追溯到最初的 Win95,在 Windows 目录下都有一个名为“Fonts”的目录。此目录在注册表的键HKLM\Software\Microsoft\Windows\CurrentVersion\Fonts
下被镜像。 当然,除了 NT,其中“Windows”被替换为“Windows NT”。
如何使用
您只需要调用一个函数,即GetFontFile
。这负责检查操作系统版本和枚举字体。原型如下所示:BOOL GetFontFile(LPCTSTR lpszFontName, CString& strDisplayName, CString& strFontFile)
。 参数lpszFontName
传入字体的显示名称,而strDisplayName
和strFontFile
在成功返回时包含字体的显示名称和文件名。
要将此函数集成到您自己的程序中,您首先需要将以下文件添加到您的项目中
- GetFontFile.cpp
- GetFontFile.h
- GetNameValue.cpp
- GetNameValue.h
- GetWinVer.cpp
- GetWinVer.h
接下来,在您想要调用GetFontFile
函数的模块中包含头文件GetFontFile.h。 有关如何调用GetFontFile
的示例,请参阅演示项目中的FontFileTestDlg.cpp。
此代码是在 VC 6.0 下构建的,并在 Win95、Win98、NT4 和 Win2000 下进行了测试。 需要记住的一件事是,GetFontFile()
试图匹配您通过lpszFontName
传入的任何字符串。 它不必是完整的显示名称。 这意味着如果您这样调用它:GetFontFile("a", strName, strFile)
,它将匹配注册表中显示名称以“a”开头的第一个字体。 由于您枚举字体时注册表中的字体未排序(尽管在使用 Regedit 时它们似乎是已排序的),因此很难说这是哪种字体。 要查看它的工作原理,请查看调试输出窗口中的TRACE
输出。
为什么它可能不适用于您
不幸的是,这不能被认为是查找字体文件名的 100% 有效的方法。 如果字体以正常方式安装,并且位于 Windows “Font” 目录中,那么此方法可能会起作用。 对于大多数屏幕字体和 TrueType 字体,它可能会起作用。 但是,此方法可能不适用于动态创建或安装的字体,或特定于特定设备的字体,或者未安装到字体目录中的字体。 我注意到在某些系统上,似乎存在某些“隐藏”字体,例如“System”字体,有时还有“MS Sans Serif”和“MS Serif”。 在发布消息或向我发送电子邮件之前,请首先检查字体是否在上述键下的注册表中列出。 您必须自行决定是否可以忍受我在这里提到的问题。
致谢
感谢 Chris Maunder 和所有在此发布的人,提供了非常有用的源代码。
用法
本软件已发布到公共领域。您可以随意以任何您喜欢的方式使用它。 如果您修改或扩展它,请考虑在此处发布新代码供大家共享。 本软件按“原样”提供,不提供任何明示或暗示的保证。 我不承担因本软件可能造成的任何损害或业务损失的责任。