首页 > 应用开发 > C/C++ > Gdi+枚举系统字体(忽略隐藏字体)C++源码
本篇文章属于《 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/ ,如需转载,请注明出处,否则将追究法律责任。