需求:获取系统已经安装的中文字体的名称
工具:C++
核心方法:EnumFontFamiliesEx()
坑:用以下代码正常编译通过,运行后,出现的都是英文的字体。以为是lfFaceName显示不全,找到elfFullName,结果二者名称相同
int CALLBACK EnumFontFamExProc(
ENUMLOGFONTEX *lpelfe, //指向含有字体的逻辑属性的ENUMLOGFONTEX结构的指针
NEWTEXTMETRICEX *lpntme, //指向含有字体物理属性的结构的指针。此函数对TrueType字体使用结构,对其他字体使用结构NEWTEXTMETRICEX。
int iType, //指定字体类型,此参数可为下列值的组合。 DEVICE_FONTTYPE(设备字体), RASTER_FONTTYPE(光栅字体), TRUETYPE_FONTTYPE(真字体)
LPARAM lParam //由EnumFontFamiliesEx函数最后一个参数传递过来的值
)
{
int* iArrayCount;
iArrayCount = (int*)lParam;
if (iType & DEVICE_FONTTYPE)
{
iArrayCount[0]++;
}
else if (iType & RASTER_FONTTYPE)
{
iArrayCount[1]++;
}
else if (iType & TRUETYPE_FONTTYPE)
{
iArrayCount[2]++;
}
else
{
iArrayCount[3]++;
}
std::wcout << lpelfe->elfLogFont.lfFaceName << std::endl;
//std::wcout << lpelfe->elfFullName << std::endl;
return (iArrayCount[0] + iArrayCount[1] + iArrayCount[2] + iArrayCount[3]) ? true : false;
}
int main()
{
HDC hdc;
hdc = GetDC(NULL);
LOGFONT lf;
int iArrayCount[] = { 0,0,0,0 };
memset(&lf, 0, sizeof(LOGFONT));
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfFaceName[0] = NULL;
EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)EnumFontFamExProc, (LPARAM)iArrayCount, 0);
printf("DEVICE_FONTTYPE:%d\n", iArrayCount[0]);
printf("RASTER_FONTTYPE:%d\n", iArrayCount[1]);
printf("TRUETYPE_FONTTYPE:%d\n", iArrayCount[2]);
ReleaseDC(NULL, hdc);
return 0;
}
结论:注意代码中红色字体部分,此处指的是命令行模式下的上下文,所以打印出来的字体没有中文字体,反复查找原因,才知道跟这个有关系,用了duilib的窗口,所有中文的字体都可以正常获取了。