GDI+、GdiPlus判断字体是否存在的C++代码源码

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

 

我在开发《518抽奖软件》(www.518cj.net)的时候,需要判断用户选的字体是否存在(比如换了电脑环境等),如果不存在就采用默认字体。如何判断字体是否存在呢,基本逻辑是,枚举系统字体,看有没有这个字体。但是,字体可以有2个名字,本地名和英文名,所以要对比2个名字。代码如下。

int CALLBACK Proc_findFont(const LOGFONT* lplf, const TEXTMETRIC* lptme, DWORD FontType, LPARAM lParam)
{
    WCHAR* rslt = (WCHAR*)lParam;

    BOOL bOk = TRUE;
    BYTE x = lplf->lfPitchAndFamily;
    if (s_bFixedPitch && g_app.get_bits(x, 1, 2) != FIXED_PITCH)  bOk = FALSE;
    if (lplf->lfCharSet != s_charset && s_charset != DEFAULT_CHARSET)  bOk = FALSE;

    if (*s_name != 0)
    {
        WCHAR name[LF_FACESIZE] = { 0 };
        FontFamily ff(s_name);
        ff.GetFamilyName(name);
// 核心:检查2个名字,中文名和英文名
        if (_wcsicmp(lplf->lfFaceName, name) != 0 &&
            _wcsicmp(lplf->lfFaceName, s_name) != 0)
        {
            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)
        {
            wcscpy(rslt, lplf->lfFaceName);
            return 0;
        }
    }
    return 1;
}

static void find_font(const WCHAR* name, unsigned int charset, BOOL bFixedPitch, WCHAR* rslt)
{
    memset(s_name, 0, sizeof(s_name));
    if (name) wcscpy(s_name, name);
    s_charset = charset;
    s_bFixedPitch = bFixedPitch;

    HDC hDc = GetDC(g_app.m_hMain);
    LOGFONT lf = { 0 };
    lf.lfCharSet = DEFAULT_CHARSET;
    EnumFontFamiliesEx(hDc, &lf, (FONTENUMPROC)Proc_findFont, (LPARAM)rslt, 0);
    ReleaseDC(g_app.m_hMain, hDc);
}