Gdi+列舉系統字型(忽略隱藏字型)C++原始碼

wsgsoft發表於2023-10-31

本篇文章屬於《 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部落格 ” ,連結:http://blog.itpub.net/70034163/viewspace-2992053/,如需轉載,請註明出處,否則將追究法律責任。

相關文章