【问题标题】:Fonts added with AddFontResourceEx are not working in GDI+使用 AddFontResourceEx 添加的字体在 GDI+ 中不起作用
【发布时间】:2017-07-24 13:34:33
【问题描述】:

AddFontResourceEx 为每种字体返回 1,但这些字体在 GDI+ 中不可访问(在 VS2015 和 Windows 10 上测试,也在 Windows 2008 R2 Server 上测试)。

如果我使用 Windows 字体资源管理器手动安装字体,一切正常。 似乎 GDI+ 找不到使用 AddFontResourceEx 或 AddFontResource 添加的字体,知道我怎样才能让它工作吗?

我使用 CodeJock 库,它使用 GDI+ 字体呈现 XAML 图形,所以我无法控制如何创建字体。

int n = 0;
CPathW pw;

pw.Combine(theApp.m_strMyAppFolder, _T("Roboto-Light.ttf"));
n =AddFontResourceEx(pw, FR_PRIVATE, nullptr);

pw.Combine(theApp.m_strMyAppFolder, _T("Roboto-Thin.ttf"));
AddFontResourceEx(pw, FR_PRIVATE, nullptr);

pw.Combine(theApp.m_strMyAppFolder, _T("Roboto-Regular.ttf"));
AddFontResourceEx(pw, FR_PRIVATE, nullptr);

pw.Combine(theApp.m_strMyAppFolder, _T("Ubuntu-R.ttf"));
AddFontResourceEx(pw, FR_PRIVATE, nullptr);

pw.Combine(theApp.m_strMyAppFolder, _T("Ubuntu-L.ttf"));
AddFontResourceEx(pw, FR_PRIVATE, nullptr);

::SendNotifyMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);

【问题讨论】:

  • 您是否尝试在同一进程中使用这些字体? “此函数允许一个进程使用字体,而不允许其他进程访问该字体。”
  • 是的,它是同一个进程,没有 DLLs
  • 该问题假定 AddFontResourceEx() 存在错误。它没有错误。不要忽略返回值,错误处理不是可选的。并且不要忽略问题出在使用该库的代码中的可能性。在 SO 问题中,这些几率总是非常非常高。
  • 每种字体返回1,这不是错误,是安装的字体个数。

标签: c++ windows fonts gdi+


【解决方案1】:

对于 GDI+,您需要使用 PrivateFontCollection 类,它解决了与带有 FR_PRIVATE 的 AddFontResourceEx() 类似的目的。

PrivateFontCollection::AddFontFile() 的文档中已经有一个示例,所以我只是对此发表评论。

该示例将 Windows 字体文件夹中的字体添加到私有字体集合中,这是毫无意义的,因为这些字体无论如何都是可用的。 您已经从 AddFontResourceEx() 示例中的应用程序文件夹中加载了字体,因此您可以为 PrivateFontCollection::AddFontFile() 使用相同的路径。

另外需要注意的是,只要应用程序正在运行,PrivateFontCollection 对象就应该一直存在,并且不应在每次想要使用这些字体绘制文本时重新创建。一个好地方是应用程序类中的成员变量。这应该很明显,但是该示例使您看起来好像每次都必须重新创建PrivateFontCollection。这将对性能造成重大影响。

编辑:

我使用 CodeJock 库,它使用 GDI+ 字体呈现 XAML 图形

PrivateFontCollection 在这种情况下可能不太容易使用,因为它不会使字体在您的应用程序中全局可用,但必须用作Font 的构造函数参数。但是您写道,您无法控制 CodeJock 如何创建字体。

也许 CodeJock 直接在 XAML 中支持私有字体,请参阅 this example,它适用于 C#,但也可能适用于 CodeJock。

【讨论】:

  • 谢谢!我试图在 XAML 中指定字体文件,但 Codejock 库不支持这个。好的部分是几乎所有的 codejock 类都可以被覆盖和修改,所以还是有一些希望的。那么您是说 PrivateFontCollection 不会使该字体在我的应用程序中全局可用?
  • PrivateFontCollection 不会使字体在我的应用程序中全局可用 ...没错。您必须创建这样的字体对象才能使用 PrivateFontCollection 中的字体:Font myFont(familyName, 16, FontStyleRegular, UnitPixel, &privateFontCollection)(参见 PrivateFontCollection::AddFontFile 文档中的示例)。
  • 谢谢,我会尝试寻找另一种解决方案来为 Codejock XAML TextBox 创建字体。
猜你喜欢
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
相关资源
最近更新 更多