简体   繁体   English

如何列出系统上安装的唯一字体名称?

[英]How to list uniquely font names installed on system?

I'm setting lf.lfFaceName[0] = '\0';我正在设置lf.lfFaceName[0] = '\0'; and lf.lfCharSet = DEFAULT_CHARSET;lf.lfCharSet = DEFAULT_CHARSET; to enumerate uniquely font names installed on system but I'm still getting duplicates.枚举系统上安装的唯一字体名称,但我仍然得到重复。 What am I missing?我错过了什么? I'm getting duplicates like this:我得到这样的重复:

font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]

I'm enumerating like this:我这样枚举:

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "UxTheme.lib")
#pragma comment(lib, "Comdlg32.lib")

#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
        WPARAM wParam, LPARAM lParam);

int CALLBACK enumFontsCallback(const LOGFONT *lpelfe, 
                               const TEXTMETRIC *lpntme,
                               DWORD      FontType,
                               LPARAM     lParam)
{
    wprintf(L"font-name: [%s]\r\n", lpelfe->lfFaceName);
    return 1;
}

void list()
{
    LOGFONT lf = {0};
    lf.lfWeight = FW_DONTCARE;
    lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
    lf.lfQuality = DEFAULT_QUALITY;
    lf.lfCharSet = DEFAULT_CHARSET;
    lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    lf.lfPitchAndFamily = FF_DONTCARE;
    lf.lfFaceName[0] = '\0';

    HDC dc = GetDC(NULL);
    EnumFontFamiliesEx(dc, &lf, (FONTENUMPROC)enumFontsCallback, 0, 0);
    ReleaseDC(NULL, dc);
}

int main()
{
    list();
    return 0;
}

The reason for the duplications is given in the docs under remarks : " EnumFontFamiliesEx will enumerate the same font as many times as there are distinct character sets in the font. [...] To avoid this, an application should filter the list of fonts ".重复的原因在注释下的文档中给出:“ EnumFontFamiliesEx将枚举相同的字体,因为字体中有不同的字符集。[...] 为避免这种情况,应用程序应过滤 fonts 的列表”。

To filter the list down to unique font names, the LPARAM of the callback can be used to build a running list of previously encountered font names, and skip over duplicates.要将列表过滤到唯一的字体名称,回调的LPARAM可用于构建以前遇到的字体名称的运行列表,并跳过重复项。

  • The EnumFontFamiliesEx call would need to be changed to something like the following.需要将EnumFontFamiliesEx调用更改为以下内容。

     unordered_set<wstring> wsFonts; EnumFontFamiliesEx(dc, &lf, (FONTENUMPROC)enumFontsCallback, (LPARAM)&wsFonts, 0);
  • The callback could then check the current font name against the list.然后回调可以根据列表检查当前字体名称。

     wstring wsFont = lpelfe->lfFaceName; if(((unordered_set<wstring> *)lParam)->insert(wsFont).second) wcout << L"font-name: " << wsFont << endl;

The above assumes C++ for the convenience of std::unordered_set , but could of course be written into plain C using a handcrafted list of unique strings.为了方便std::unordered_set ,上面假设 C++ ,但当然可以使用手工制作的唯一字符串列表写入普通的 C 。

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

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