繁体   English   中英

如何获取 Windows 上已安装 fonts 的列表,包括使用 c++ 的字体样式

[英]How can I get a list of installed fonts on Windows including font style using c++

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

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

例如:对于字体:“Verdana”

在此处输入图像描述

有四种不同的 styles,但我只得到一种 - 常规的。 我的问题是:如何获得包括所有 styles 在内的 fonts 列表?

我的代码:

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 - 包含字体。 但我没有得到所有不同的 styles

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

// 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" );

所以我不确定我应该做什么,我需要为所有已安装的 fonts 获取所有 styles。

先感谢您

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

如果设置为空字符串,则 function 会在每个可用字体名称中枚举一种字体。 如果设置为有效的字体名称,则 function 将枚举所有具有指定名称的 fonts。

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

这个小程序将列出您系统上安装的所有 fonts。 您可以通过仅查找后缀的样式将它们分开。 它使用 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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM