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

标签 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 */");
//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.

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

最佳答案

假设您为资源 ID 定义了 token IDF_MYFONT,那么您可以在 .rc 中使用类似这样的行将字体嵌入到可执行文件中(或 .rc2)脚本:

IDF_MYFONT BINARY "..\\MyFont.ttf" // Or whatever the path to your font file is.

您可以使用如下代码加载和锁定字体资源:

HANDLE hMyFont = INVALID_HANDLE_VALUE; // Here, we will (hopefully) get our font handle
HINSTANCE hInstance = ::GetModuleHandle(nullptr); // Or could even be a DLL's HINSTANCE
HRSRC  hFntRes = FindResource(hInstance, MAKEINTRESOURCE(IDF_MYFONT), L"BINARY");
if (hFntRes) { // If we have found the resource ... 
    HGLOBAL hFntMem = LoadResource(hInstance, hFntRes); // Load it
    if (hFntMem != nullptr) {
        void* FntData = LockResource(hFntMem); // Lock it into accessible memory
        DWORD nFonts = 0, len = SizeofResource(hInstance, ares);
        hMyFont = AddFontMemResourceEx(FntData, len, nullptr, &nFonts); // Fake install font!
    }
}

然后,当你使用完字体后,你可以像这样从内存中释放它:

RemoveFontMemResourceEx(hMyFont);

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

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

LOGFONT MyLogFont = { -8, 0,   0, 0, 400, FALSE, FALSE, FALSE, ANSI_CHARSET,
                       OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, 
                       VARIABLE_PITCH | FF_SWISS, L"MyFontName" };

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

关于c++ - Win32 在应用程序内使用资源字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58712918/

相关文章:

C++ 获取 64 位应用程序的模块基址

windows - 如何判断窗口是否有焦点? (Win32 API)

java - 是否可以从字体中获取 vector 形式的字符?

c++ - Mergecom 标签不按顺序 (MC_OUT_OF_ORDER_TAG) 问题

C++ - 数组指针作为函数参数,填充数组并从 UI 线程访问它

C++ - 模板中的复制赋值运算符

c++ - 如何删除正在运行程序的 Win32 桌面,并终止这些程序?

android - 确定用户字体大小选择

java - 如果文本中有阿拉伯语或波斯语字母,通过 fontmetrics 计算的字符串宽度非常慢

c++ - 发送 std::endl 到流给出内存地址