Fonts 使用枚举字体的最佳方法

Fonts 使用枚举字体的最佳方法,fonts,Fonts,自学的VB黑客在这里只有一点.net的经验。我在这个主题上找到的大多数帖子都相当陈旧,所以我在寻找最佳的方向,在我开始寻找任何一个特定的兔子洞之前,并确保我没有遗漏任何新的东西 我在vb.net中编写了一个加载和卸载字体的应用程序。我正在读取注册表以查看加载了哪些字体,直接从字体文件中读取字体信息,并使用AddFontResource、RemoveFontResource和修改注册表以备机器重新启动时使用 所有这些都是有效的,但正如所指出的,仅仅因为它在注册表中并不意味着它在枚举。我们将生产字体

自学的VB黑客在这里只有一点.net的经验。我在这个主题上找到的大多数帖子都相当陈旧,所以我在寻找最佳的方向,在我开始寻找任何一个特定的兔子洞之前,并确保我没有遗漏任何新的东西

我在vb.net中编写了一个加载和卸载字体的应用程序。我正在读取注册表以查看加载了哪些字体,直接从字体文件中读取字体信息,并使用AddFontResource、RemoveFontResource和修改注册表以备机器重新启动时使用

所有这些都是有效的,但正如所指出的,仅仅因为它在注册表中并不意味着它在枚举。我们将生产字体存储在网络驱动器上,Windows 10在重新启动/登录后重新连接时非常糟糕,因此我做了大量的研究,列举了所有加载的字体,令人惊讶的是,似乎没有任何东西可以立即工作

EnumFontFamiliesEx API的使用让我难以置信(仅仅是因为我缺乏知识),甚至我编写的代码也运行得比较好,但没有加载一些字体。和那个链接的OP一样,我还没有弄明白为什么,至少现在还没有。我已经按照建议修改了下载的代码以使用EnumFontFamiliesExW API,但仍然缺少字体

建议使用DirectWrite,我认为它是DirectX的一部分?在看了几遍之后,沮丧的情绪把我带到了这里

因此,我认为有两个问题:

  • (大人物)有比EnumFontFamiliesExW更新的吗

  • 对于OTF和TTF字体,我正在阅读“排版族名称”(定义为ID16),因为Adobe产品会显示这些字体。使用EnumFontFamiliesExW是否可以读取此ID?我没有看到任何迹象表明这是真的

  • 哎呀,抱歉这么久,如果你能走到这一步,谢谢你的阅读

    快速回答 (大人物)有比EnumFontFamiliesExW更新的吗

    是:DirectWrite

    对于OTF和TTF字体,我正在阅读“排版族名称”(此处定义的ID 16),因为Adobe产品会显示这些字体。使用EnumFontFamiliesExW是否可以读取此ID?我没有看到任何迹象表明这是真的

    快速的回答是否定的,GDI没有给你名字IDS16/17。DWrite确实如此,但在某些情况下,字体的性质可能要求您以某种方式调用。这实际上有点复杂,难以完全解释。我将给你一些全面的信息,但对于这一点,特别是,跳到字体系列模型

    现在,您的问题似乎还有一个方面,即某些字体在您希望它们枚举时不会枚举。很难对此发表评论,当然没有更多细节

    Windows字体API Windows有三代不同的文本/字体平台API:GDI、GDI+和DirectWrite。出于您的目的,我们可以忽略GDI+

    还有WPF,它是.Net的一部分。Net不是Windows的一部分,其功能基本上是D(Direct)Write的一个子集,因此除了下面的历史记录外,我也将跳过它

    GDI和DWrite都有API来枚举加载到操作系统会话中的字体。现在,有一些事情需要理解:

    已安装与已加载 当GDI在引导期间初始化时,它没有任何字体。*它只在操作系统的另一部分开始调用或调用时获取字体。操作系统的另一部分读取注册表中的
    font
    项,并为每个条目调用其中一个API

    (*不是100%正确:GDI本身首先读取HKLM…\GRE_Initialize键下的reg条目以加载某些位图字体。)

    但请注意,任何应用程序也可以调用
    AddFontResource()

    因此,在调用
    AddFontResource()
    传递字体文件后,字体在GDI中被“加载”。“已安装字体”的概念适用于在注册表中注册的字体,这些字体将在引导时自动加载

    请注意,还有/函数。因此,在使用会话期间的某个时候,安装的字体可能会被卸载

    同样的概念基本上也适用于DWrite。它读取注册表来加载字体(而不是等待其他东西来加载字体)。它还与GDI进行对话,以便在加载的字体方面保持同步。它支持加载其他字体,但仅适用于呼叫应用程序。所以,如果你的目的是加载字体在任何应用程序中使用,那么目前还没有一种方法可以做到这一点

    系统与用户 另一件可能有用的事情是,Windows 10支持区分系统范围内安装或加载的字体与每个用户的字体。系统范围内安装的字体在注册表的
    HKLM
    配置单元中注册,并且(默认情况下)存储在%windir%\font文件夹中。每用户字体在注册表的
    HKCU
    (当前用户)配置单元中注册,并存储在%userprofile%\AppData文件夹中的某个位置

    当您从GDI或DWrite获得字体枚举时,它将包括(当前加载的)系统范围的字体以及该用户的字体

    所有应用程序/一个应用程序/未枚举 通常在GDI中加载字体时,任何应用程序都可以枚举和使用这些字体。但是
    AddFontResourceEx()
    添加了可用于限制以下内容的标志:

    • FR\u PRIVATE
      :只有加载字体的应用程序才能使用它
    • FR\u NOT\u ENUM
      :字体永远不会被枚举,即使对于加载它的应用程序也是如此
    DWrite支持特定于应用程序的字体,并具有比GDI更多的功能。例如,它提供了一种应用程序可以直接从云服务加载字体的方法。但这些字体只适用于一个应用程序。对于这类场景,DWrite有一些不同的API