AddFontMemResourceEx

AddFontMemResourceEx

本文关键字:AddFontMemResourceEx      更新时间:2023-10-16

根据我发现的所有示例,下面的代码应该可以从可执行文件中存储的二进制资源加载字体到系统内存,但它不起作用。"myfont"是资源文件中与IDR_FONT相关联的ttf的名称。

    DWORD   Count ;
    HRSRC   Resource = FindResource(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_FONT),"BINARY") ;
    DWORD   Length   = SizeofResource(GetModuleHandle(NULL),Resource) ;
    HGLOBAL Address  = LoadResource(GetModuleHandle(NULL),Resource) ;
    HANDLE Handle = AddFontMemResourceEx(Address,Length,0,&Count) ;
    if(Handle==0)
    {
        MessageBox(hWnd,"Font load failed", "Error",NULL);
    }

        LOGFONT logfont; //set window font
        logfont.lfCharSet = DEFAULT_CHARSET;
        logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
        logfont.lfEscapement = 0;
        memcpy(logfont.lfFaceName, "myfont", LF_FACESIZE); 
        logfont.lfHeight = 14; 
        logfont.lfItalic = FALSE; 
        logfont.lfOrientation = 0;
        logfont.lfOutPrecision = OUT_TT_PRECIS;
        logfont.lfQuality = PROOF_QUALITY;
        logfont.lfStrikeOut = FALSE;
        logfont.lfUnderline = FALSE;
        logfont.lfWeight = FW_DONTCARE; 
        hFont = CreateFontIndirect(&logfont);

你知道我做错了什么吗?

你的代码有两个问题。

您没有检查任何API函数是否失败。对FindResource()的调用很可能失败,因为"BINARY"不是标准的资源类型。用户定义的资源应该使用RCDATA:

HRSRC Resource = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_FONT), RT_RCDATA);

或者FONT,如果它是一个实际的标准FONT资源:

HRSRC Resource = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_FONT), RT_FONT);

资源类型的实际名称取决于您用于将资源添加到可执行文件中的. rc文件的内容。

另一个更重要的问题是,您实际上并没有访问资源的原始数据,因此您可以将真正的字体数据传递给AddFontMemResourceEx()。你需要使用LockResource()

试试这样写:

HANDLE AddResourceFont(LPCTSTR ResID, DWORD *Installed)
{
    if (Installed) *Installed = 0;
    HMODULE hMod = GetModuleHandle(NULL);
    DWORD Count, ErrorCode;
    HRSRC Resource = FindResource(hMod, ResID, RT_RCDATA); // or RT_FONT or whatever your actual resource type is
    if (!Resource)
    {
        ErrorCode = GetLastError();
        //...
        return NULL;
    }
    DWORD Length = SizeofResource(hMod, Resource);
    if ((Length == 0) && (GetLastError() != 0))
    {
        ErrorCode = GetLastError();
        //...
        return NULL;
    }
    HGLOBAL Address = LoadResource(hMod, Resource);
    if (!Address)
    {
        ErrorCode = GetLastError();
        //...
        return NULL;
    }
    PVOID FontData = LockResource(Address);
    if (!FontData)
    {
        ErrorCode = GetLastError();
        //...
        return NULL;
    }
    HANDLE Handle = AddFontMemResourceEx(FontData, Length, 0, &Count);
    if (!Handle)
    {
        ErrorCode = GetLastError();
        //...
        return NULL;
    }
    if (Installed) *Installed = Count;
    return Handle;
}

.

DWORD Count = 0;
HANDLE hFont = AddResourceFont(MAKEINTRESOURCE(IDR_FONT), &Count);
if (hFont)
{
    //...
    RemoveFontMemResourceEx(hFont);
}