2

我一直在尝试获取 Windows 上已安装字体的列表,包括字体样式。

经过调查,我发现我需要使用:EnumFontFamiliesEx。我使用它但我只得到字体名称而不是该字体的所有样式。

例如:对于字体:“Verdana”

在此处输入图像描述

有四种不同的风格,但我只得到一种——常规的。我的问题是:如何获取包含所有样式的字体列表?

我的代码:

void getFonts()
{
    LOGFONT lf;
    memset(&lf, 0, sizeof(lf));
    lf.lfCharSet = DEFAULT_CHARSET;
    HDC hDC = GetDC(NULL);
    EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)(EnumFontFamExProc), NULL, 0);
}

int CALLBACK EnumFontFamExProc(
    ENUMLOGFONTEX *lpelfe,
    NEWTEXTMETRICEX *lpntme,
    DWORD FontType,
    LPARAM lParam
)
{
    UTF8String fontName = (lpelfe->elfFullName);
    return 1;
}

ENUMLOGFONTEX *lpelfe - 包含字体。但我没有得到所有不同的风格

经过更多调查,我发现如果我将 lfFaceName 更改为特定字体,该方法将返回所有样式。

// To enumerate all styles of all fonts for the ANSI character set 
lf.lfFaceName[0] = '\0';
lf.lfCharSet = ANSI_CHARSET;

// To enumerate all styles of Arial font that cover the ANSI charset 
hr = StringCchCopy( (LPSTR)lf.lfFaceName, LF_FACESIZE, "Arial" );

所以我不确定我应该做什么,我需要获取所有已安装字体的所有样式。

先感谢您

4

2 回答 2

1

请参阅EnumFontFamiliesEx的详细信息,特别是 lfFaceName 参数:

如果设置为空字符串,该函数将枚举每个可用字体名称中的一种字体。如果设置为有效的字体名称,该函数将枚举具有指定名称的所有字体。

最常见的情况是获取要在字体选择 UI(例如,下拉菜单)中显示的系列列表,而不是所有单独的面孔。出于这个原因,如果您在 lfFacename 设置为 "" 的情况下调用,您将得到:家庭列表。如果你真的想获得所有的个人面孔——每个家庭有多个面孔——那么你需要在EnumFontFamiliesExProc回调中递归调用,将家庭名称作为 lfFaceName 传递给内部循环——你可以只使用传递给调用的 LOGFONT返回作为内部循环调用的参数EnumFontFamiliesEx

int CALLBACK GdiFontEnumeration::EnumFontFamiliesExCallback(
    _In_ const ENUMLOGFONTEX    *lpelfe,
    _In_ const NEWTEXTMETRICEX *lpntme,
    _In_       DWORD      dwFontType,
    _In_       LPARAM     lParam
    )
{
    // If no facename parameter was passed in the command line, then
    // lParam will be 0 the first time the callback is called for a
    // given family. We'll call EnumFontFamiliesEx again passing the 
    // LOGFONT, and that way we'll get callbacks for the variations 
    // within the given family. When making the inner-loop call, set 
    // lParam = 1 so that we don't keep recursing.

    if (lParam == 0)
    {
        LOGFONT lf = lpelfe->elfLogFont;
        HDC hdc = CreateDC(L"DISPLAY", NULL, NULL, NULL);
        int result = EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)EnumFontFamiliesExCallback, 1, 0);
    }
    else
...
于 2020-06-16T09:26:01.380 回答
0

这个小程序将列出系统上安装的所有字体。您可以通过仅查找后缀的样式将它们分开。它使用 C++17 特性,因此请记住使用正确的标准对其进行编译。

i = Italic
b = Bold
bi = Bold and Italic
...
#include <string>
#include <iostream>
#include <filesystem>

int main()
{
    std::string path = "C:\\Windows\\Fonts";
    for (const auto& entry : std::filesystem::directory_iterator(path))
        std::cout << entry.path() << std::endl;
}
于 2020-06-14T08:33:56.930 回答