ITPub博客

首页 > 应用开发 > C/C++ > Gdi+枚举系统字体(忽略隐藏字体)C++源码

Gdi+枚举系统字体(忽略隐藏字体)C++源码

原创 C/C++ 作者:wsgsoft 时间:2023-10-31 11:32:57 0 删除 编辑

本篇文章属于《 518 抽奖软件开发日志》系列文章的一部分。

 

我在开发《 518 抽奖软件》( )的时候,需要枚举系统字体,让用户选择。用到 EnumFontFamiliesEx 函数,需要判断是否是隐藏字体,需要判断字体是否重复等。具体代码如下:

static void enum_fonts(HWND hCombo, BOOL bFixedPitch)
{
s_bFixedPitch = bFixedPitch;
get_inactFonts(); // 得到隐藏字体列表
HDC hDc = GetDC(g_app.m_hMain);
LOGFONT lf = { 0 };
lf.lfCharSet = DEFAULT_CHARSET;
EnumFontFamiliesEx(hDc, &lf, (FONTENUMPROC)Proc_enumFonts, (LPARAM)hCombo, 0);
ReleaseDC(g_app.m_hMain, hDc);
}
 
static int CALLBACK Proc_enumFonts(const LOGFONT* lplf, const TEXTMETRIC* lptme, DWORD FontType, LPARAM lParam)
{
HWND hCombo = (HWND)lParam;
ENUMLOGFONTEX* lplfEx = (ENUMLOGFONTEX*)lplf;
 
// 判断是否是等宽字体
BOOL bOk = TRUE;
BYTE x = lplf->lfPitchAndFamily;
if (s_bFixedPitch && g_app.get_bits(x, 1, 2) != FIXED_PITCH)
bOk = FALSE;
 
// 去掉@开头的字体名,还有符号字体
if (*(lplf->lfFaceName) != L'@' && lplf->lfCharSet != SYMBOL_CHARSET && bOk)
{
BOOL bTrueType = FontType & TRUETYPE_FONTTYPE;
BOOL bRaster = FontType & RASTER_FONTTYPE;
BOOL bDevice = FontType & DEVICE_FONTTYPE;
BOOL bVector = !(bRaster || bTrueType);
if (bTrueType)
{
int idx = SendMessage(hCombo, CB_FINDSTRINGEXACT, -1, (LPARAM)lplf->lfFaceName);
//华文仿宋:多个字符集枚举多次
//参看 EnumFontFamiliesEx 官方
if (idx < 0)
{
if (is_inactFont(lplf->lfFaceName)) { ; }
else
{
idx = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
SendMessage(hCombo, CB_SETITEMDATA, idx, (LPARAM)(DWORD)lplf->lfCharSet);
}
}
}
}
return 1;
}
 
static BOOL get_inactFonts()
{
s_inactFonts.clear();
 
int i;
DWORD tp = REG_MULTI_SZ;
WCHAR* buf = NULL;
DWORD size;
HKEY h = NULL;
wstring one;
 
LONG r = RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Font Management", 0, KEY_QUERY_VALUE, &h);
if (r != ERROR_SUCCESS) {
h = NULL;
Tfuns::open_perm(L"CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Font Management");
r = RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Font Management", 0, KEY_QUERY_VALUE, &h);
}
if (r == ERROR_FILE_NOT_FOUND) return TRUE;
if (r != ERROR_SUCCESS) goto ERR;
 
//-----------------------------------------------------
size = 0;
r = RegQueryValueEx(h, L"Inactive Fonts", 0, &tp, NULL, &size);
if (r == ERROR_FILE_NOT_FOUND) { RegCloseKey(h); return TRUE; }
if (r != ERROR_SUCCESS) goto ERR;
if (size <= 0) { RegCloseKey(h); return TRUE; }
 
buf = (WCHAR*)calloc(1, size + 8);
r = RegQueryValueEx(h, L"Inactive Fonts", 0, &tp, (LPBYTE)buf, &size);
if (r != ERROR_SUCCESS) goto ERR;
 
for (int i = 0; 1; i++)
{
if (buf[i] == NULL)
{
s_inactFonts.push_back(one);
if (buf[i + 1] == NULL)
break;
one.clear();
}
else one += buf[i];
}
 
if (buf) free(buf);
RegCloseKey(h);
return TRUE;
 
ERR:
if (buf) free(buf);
if (h) RegCloseKey(h);
return FALSE;
}
 
static BOOL is_inactFont(const WCHAR* name)
{
vector<wstring>::iterator it = s_inactFonts.begin();
while (it != s_inactFonts.end())
{
if (_wcsicmp((*it).c_str(), name) == 0)
return TRUE;
it++;
}
return FALSE;
}

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70034163/viewspace-2992053/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论
个体软件开发者:开发小工具桌面项目等。 www.518cj.net , www.518boyin.com 交流软件开发技术

注册时间:2023-10-31

  • 博文量
    1
  • 访问量
    633