C++ Win32在应用程序内使用资源字体

C++ Win32在应用程序内使用资源字体,c++,winapi,fonts,resources,hwnd,C++,Winapi,Fonts,Resources,Hwnd,我有一个应用程序,我将一些字体导入到资源中 现在,我想在应用程序中使用这些资源丰富的字体,而不用将它们安装到运行它的计算机上 我希望使用字体资源的方式是通过向标签发送WM_SETFONT消息,将标签的字体设置为资源字体 通常,如果计算机上已安装字体,我将使用以下代码: HDC hdc = GetDC(hwnd); //here hwnd is the handle to the window. const TCHAR* fontName = TEXT("/* THE FONT NAME *

我有一个应用程序,我将一些字体导入到资源中

现在,我想在应用程序中使用这些资源丰富的字体,而不用将它们安装到运行它的计算机上

我希望使用字体资源的方式是通过向标签发送
WM_SETFONT
消息,将标签的字体设置为资源字体


通常,如果计算机上已安装字体,我将使用以下代码:

HDC hdc = GetDC(hwnd);
//here hwnd is the handle to the window.

const TCHAR* fontName = TEXT("/* THE FONT NAME */");
//this is where I'd enter the font name, but it only works when the font is already installed on the computer.

const long nFontSize = NFONTSIZE(7);
//this is where I set the font size.

LOGFONT logFont = {0};
logFont.lfHeight = -MulDiv(nFontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
logFont.lfWeight = FW_SEMIBOLD;
_tcscpy_s(logFont.lfFaceName, fontName);

HFONT font = CreateFontIndirect(&logFont); //get the font handle
一旦我获得
HFONT
句柄,就可以通过以下方式将
WM_SETFONT
消息发送到标签:

SendMessage(hwnd, WM_SETFONT, (WPARAM)font, static_cast<LPARAM>(MAKELONG(TRUE, 0)));
//here hwnd is the handle of the static label.
SendMessage(hwnd,WM_SETFONT,(WPARAM)字体,static_cast(MAKELONG(TRUE,0));
//这里hwnd是静态标签的句柄。


但是现在,我不想用这种方式设置字体,因为只有在计算机上已经安装了指定的字体时,这种方式才有效。我有我自己的字体文件,带有
.ttf
格式作为资源导入。我想将标签的字体设置为THIS
.ttf
字体。

假设您有一个为资源ID定义的标记
IDF\u MYFONT
,那么您可以在
.rc
(或
.rc2
)脚本中这样一行将字体嵌入可执行文件:

IDF\u MYFONT BINARY.。\\MYFONT.ttf”//或字体文件的任何路径。
可以使用如下代码加载和锁定字体资源:

HANDLE hMyFont=无效的句柄值;//在这里,我们将(希望)得到我们的字体句柄
HINSTANCE HINSTANCE=::GetModuleHandle(nullptr);//甚至可能是DLL的链接
HRSRC hFntRes=FindResource(hInstance,MAKEINTRESOURCE(IDF_MYFONT),L“BINARY”);
如果(hFntRes){//如果我们找到了资源。。。
HGLOBAL hFntMem=LoadResource(hInstance,hFntRes);//加载它
if(hFntMem!=空PTR){
void*FntData=LockResource(hFntMem);//将其锁定到可访问内存中
DWORD nFonts=0,len=SizeofResource(hInstance,ares);
hMyFont=AddFontMemResourceEx(FntData、len、nullptr和&nFonts);//假安装字体!
}
}
然后,当您使用完字体后,您可以像这样从内存中释放它:

RemoveFontMemResourceEx(hMyFont);
我已经对系统调用的返回值进行了一些检查,但是您可以添加其他检查。您需要能够处理其中任何一种失败的情况(例如,提供默认字体)

在内存中加载/锁定字体时,您可以像在系统上安装一样使用它:例如,在
LOGFONT
结构中使用其名称:

LOGFONT MyLogFont={-8,0,0,0,400,FALSE,FALSE,FALSE,ANSI_字符集,
输出精度、剪辑精度、默认精度、清晰类型精度、,
可变音高| FF |瑞士,L“MyFontName”};

请随时要求进一步澄清和/或解释。

有趣的是,我昨天晚上刚刚处理了这个问题

要解决此问题,传入
FindResourceW
的值必须与资源类型匹配:

        const auto resourceHandle{ FindResourceW(nullptr, MAKEINTRESOURCE(IDR_FONT1), RT_FONT) };
        const auto resourceLoad{ LoadResource(nullptr, resourceHandle) };
        const auto pResource{ LockResource(resourceLoad) };

        //do something with the resource pointer here...

        FreeResource(resourceLoad);
这将为您提供一个指向资源的指针,然后您可以通过创建一个新文件提取字体,并使用
WriteFile写入该文件。
要获取资源的大小,请使用
SizeofResource

或者,您可以通过将资源指针传入
AddFontMemResourceEx来创建字体。