首页 > 其他分享 >MFC控件使用自己本地的字体文件

MFC控件使用自己本地的字体文件

时间:2022-12-11 23:25:56浏览次数:47  
标签:控件 MFC return hWnd CFontHelper Gdiplus 字体 logFont NULL

MFC作为一套古老的框架,加载使用本地字体流程也很复杂,网上的资料大多也都不能直接运行。在参考了一些github上现有代码和古代代码之后,实现了加载本地字体文件并显示在指定控件的功能。

首先要把字体文件加载到资源文件里,资源视图下右键-添加资源, 点击自定义,输入"OTF", "TTF"等需要加载的字体文件类型,记得要加双引号


然后点击导入,将需要加载的字体文件导入到相应的资源里:



资源导入完成后开始加代码:

CFontHelper.h

#pragma once
#include <GdiPlus.h>
using namespace Gdiplus;

class CFontHelper
{
public:
	CFontHelper();
	~CFontHelper();

public:
	// 加载字体
	BOOL LoadFont(UINT lpszResource, LPCTSTR lpszType = _T("ttf"));
	Gdiplus::Font* SetFontStyle(Gdiplus::FontStyle fontstyle = FontStyleRegular, REAL nFontSize = 14.0F);
	Gdiplus::FontFamily* FontFamily();
	HFONT FontToHFONTA(HWND hWnd);
	HFONT FontToHFONTW(HWND hWnd);
	HFONT GetSafeHFONT(HWND hWnd);

	void SetFont(HWND hWnd);

private:
	ULONG_PTR				gdiplusToken;

	void* m_pData;
	int                     m_nSize;
	DWORD					m_nFontIndex;

	// GDI+
	PrivateFontCollection* m_pFontCollection;
	Gdiplus::FontFamily* m_pFontFamily;
	Gdiplus::Font* m_Font;

	// GDI
	CString					m_strFontFile;
	HANDLE                  m_hFontRes;
};

CFontHelper.cpp

#include "pch.h"
#include "CFontHelper.h"

CFontHelper::CFontHelper() :
	m_Font(NULL),
	m_pData(NULL), m_nSize(0),
	m_nFontIndex(0), m_hFontRes(NULL)
{
	GdiplusStartupInput gdiplusStartupInput;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	m_pFontCollection = new PrivateFontCollection;
	m_pFontFamily = new Gdiplus::FontFamily;
}

CFontHelper::~CFontHelper()
{
	if (m_Font != NULL)
	{
		delete m_Font;
		m_Font = NULL;
	}

	if (m_pFontCollection != NULL)
	{
		delete m_pFontCollection;
		m_pFontCollection = NULL;
	}

	if (m_pFontFamily != NULL)
	{
		delete m_pFontFamily;
		m_pFontFamily = NULL;
	}

	if (m_hFontRes != NULL)
	{
		RemoveFontMemResourceEx(m_hFontRes);
		m_hFontRes = NULL;
	}

	if (!m_strFontFile.IsEmpty())
		RemoveFontResourceEx(m_strFontFile, FR_PRIVATE, NULL);

	GdiplusShutdown(gdiplusToken);
}

BOOL CFontHelper::LoadFont(UINT  lpszResource, LPCTSTR lpszType/* = _T("ttf")*/)
{
	HINSTANCE hInst = AfxGetResourceHandle();
	HRSRC hResrc = ::FindResource(hInst, MAKEINTRESOURCE(lpszResource), lpszType);
	if (hResrc == NULL)
		return FALSE;

	m_nSize = SizeofResource(hInst, hResrc);
	m_pData = LoadResource(hInst, hResrc);
	if (m_pData == NULL)
		return FALSE;

	// GDI
	m_nFontIndex = 0;
	m_hFontRes = AddFontMemResourceEx(
		m_pData,			// font resource
		m_nSize,			// number of bytes in font resource 
		NULL,				// Reserved. Must be 0.
		&m_nFontIndex);     // number of fonts installed
	if (m_hFontRes == NULL)
		return FALSE;

	// GDI+
	Gdiplus::Status nResults = m_pFontCollection->AddMemoryFont(m_pData, m_nSize);
	if (nResults != Gdiplus::Ok)
		return FALSE;

	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return FALSE;

	return TRUE;
}

HFONT CFontHelper::FontToHFONTA(HWND hWnd)
{
	if (m_Font == NULL || hWnd == NULL)
		return NULL;

	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return NULL;

	Graphics g(hWnd);
	LOGFONTA logFont;
	m_Font->GetLogFontA(&g, &logFont);
	logFont.lfQuality = CLEARTYPE_QUALITY;
	logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
	logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS;
	logFont.lfCharSet = DEFAULT_CHARSET;
	logFont.lfPitchAndFamily = DEFAULT_PITCH;
	return ::CreateFontIndirectA(&logFont);
}

// GDI+ -> GDI
HFONT CFontHelper::FontToHFONTW(HWND hWnd)
{
	if (m_Font == NULL || hWnd == NULL)
		return NULL;

	Graphics g(hWnd);
	LOGFONTW logFont;

	m_Font->GetLogFontW(&g, &logFont);
	logFont.lfQuality = CLEARTYPE_QUALITY;
	logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
	logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS;
	logFont.lfCharSet = DEFAULT_CHARSET;
	logFont.lfPitchAndFamily = DEFAULT_PITCH;
	return ::CreateFontIndirectW(&logFont);
}

// GDI+ -> GDI
HFONT CFontHelper::GetSafeHFONT(HWND hWnd)
{
#ifdef _UNICODE
	return FontToHFONTW(hWnd);
#else
	return FontToHFONTA(hWnd);
#endif // _UNICODE
}


// GDI+
Gdiplus::Font* CFontHelper::SetFontStyle(Gdiplus::FontStyle fontstyle/* = FontStyleRegular*/, REAL nFontSize/* = 14.0F*/)
{
	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return NULL;

	if (m_Font != NULL)
	{
		delete m_Font;
		m_Font = NULL;
	}

	m_Font = new Gdiplus::Font(m_pFontFamily, nFontSize, fontstyle, UnitPixel);
	return m_Font;
}

// GDI
Gdiplus::FontFamily* CFontHelper::FontFamily()
{
	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return NULL;

	return m_pFontFamily;
}

BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
	CFont* pFont = (CFont*)lParam;
	CWnd* pWnd = CWnd::FromHandle(hwndChild);
	pWnd->SetFont(pFont);
	return TRUE;
}

void CFontHelper::SetFont(HWND hWnd)
{
	CFont* pFont = CFont::FromHandle(GetSafeHFONT(hWnd));
	::EnumChildWindows(hWnd, EnumChildProc, (LPARAM)&pFont);
	::SendMessage(hWnd, WM_SETFONT, (WPARAM)GetSafeHFONT(hWnd), TRUE);
}

大功告成,使用的时候只要这样:

OK。 看下效果:

标签:控件,MFC,return,hWnd,CFontHelper,Gdiplus,字体,logFont,NULL
From: https://www.cnblogs.com/chaichengxun/p/16974841.html

相关文章

  • WinForm(五)控件和它的成员
    窗体无疑是WinForm的主角,每个窗体都是用一个class来承载,那么窗体的控件,就是类中的私有字段了。每个窗体有三个文件,两个.cs文件,是一个分部类,Designer.cs是自动生成的C#......
  • WinForm(五)控件和它的成员
    窗体无疑是WinForm的主角,每个窗体都是用一个class来承载,那么窗体的控件,就是类中的私有字段了。每个窗体有三个文件,两个.cs文件,是一个分部类,Designer.cs是自动生成的C#代......
  • WinForm(五)控件和它的成员
    窗体无疑是WinForm的主角,每个窗体都是用一个class来承载,那么窗体的控件,就是类中的私有字段了。每个窗体有三个文件,两个.cs文件,是一个分部类,Designer.cs是自动生成的C#......
  • 单选与多选控件的简单应用
    这里不好理解的是选择项分组,按Ctrl+D快捷键,先设置按钮Tab顺序,对编排界面的元素Tab顺序,假Tab序号为1~3的分为一组,4~6分为一组,那么设置序号1的选择项属性杂项->组=Tr......
  • TabControl控件的简单使用-添加tab
    1、首先创建一个MFC对话框框架,在对话框资源上从工具箱中添加上一个TabControl控件,根据需要修改一下属性,然后右击控件,为这个控件添加一个变量,将此控件跟一个CTabCtrl类变......
  • 为文本框控件添加滚动条-CEdit
    在VS2015环境下操作创建文本框控件设置控件属性效果......
  • 重走Android路 之 挑几个基本控件玩玩(上卷)
    LZ-Says:冬瓜嫌弃LZ这个系列,说他都能看懂,哎呦我去,这个给人气的呀~真想把冬瓜剁吧剁吧熬成粥~高考了,祝愿各位学子功成归来~!!!基本控件使用Android为我们提供了很多UI样式,但是在......
  • MFC--消息
    WM_CTLCOLORWM_CTLCOLOR消息用来完成对EDIT、STATIC、BUTTON等控件设置背景和字体颜色具体示例看:https://www.cnblogs.com/liming19680104/p/16948586.html     ......
  • MFC窗口颜色的设置
    MFC窗口颜色的设置本文主要介绍对话框背景色以及控件颜色的设置(SetDialogBkColor()不再被支持)。 对话框背景色的设置 1、重载OnPaint()函数,即WM_PAINT消息,代码如下所示: ......
  • 【Chart控件】折线图
    多Y轴显示效果: <Windowx:Class="Chart.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://sche......