Win32 Используйте шрифт ресурса внутри приложения - PullRequest
2 голосов
/ 05 ноября 2019

У меня есть приложение, и я импортировал некоторые шрифты в ресурс.

Теперь я хочу использовать эти ресурсы в приложении, без установки их на компьютер, на котором он запущен.

Я хочу использовать ресурсы шрифта , для которого я хочу установить шрифт метки для ресурса, отправив 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.

Но сейчас я не хочу устанавливать шрифт таким способом, потому что это работает только тогда, когда указанныйшрифт уже установлен на компьютере. У меня есть файл шрифта MY OWN с форматом .ttf , импортированный как ресурс . Я хочу установить шрифт метки на ЭТОТ .ttf шрифт.

Большое спасибо вам, кто нашел ваше драгоценное время, чтобы помочь мне ответить на этот вопрос.

Приветствуются любые предложения и критика.

Ответы [ 2 ]

3 голосов
/ 05 ноября 2019

Если у вас есть токен 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" };

Не стесняйтесь просить дальнейших разъяснений и / или объяснений.

1 голос
/ 05 ноября 2019

Забавно, я только что имел дело с этой проблемой вчера вечером ...

Чтобы решить ее, значения, переданные в 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.

...