VC++ 调用私有字体文件

引言:有时候UI设计的时候,界面显示要求显示特殊字体,而这种字体在字体库中又并没有安装,那么在程序中该如何调用该字体文件呢?下面将给你讲解实现思路:

方法一、从资源文件中加载字体资源文件

方法二、从本地硬盘加载字体文件

为此,我们将所需功能封装成类库文件,方便直接调用:

类头文件定义:

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

class CFontHelper : public Singleton<CFontHelper>
{
public:
	CFontHelper();
	~CFontHelper();

public:
	// 加载字体
	BOOL LoadFont(UINT lpszResource, LPCTSTR lpszType = _T("ttf"));
	BOOL LoadFont(char* lpszFile, LPCTSTR lpszType = _T("ttf"));

	Gdiplus::Font*	Font(Gdiplus::FontStyle fontstyle = FontStyleRegular, REAL nFontSize = 14.0F);
	Gdiplus::FontFamily*	FontFamily();
	operator HFONT() const;
	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;
	BYTE*					m_lpResrc;
	DWORD					m_nFontIndex;

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

	// GDI
	HFONT                   m_hFont;
	CString					m_strFontFile;
	CFont*					m_pFont;
};

类源码实现:

#include "stdafx.h"
#include "CFontHelper.h"

_MACRO_SINGLETON_(CFontHelper)
CFontHelper::CFontHelper() : 
	m_Font(NULL), m_hFont(NULL), 
	m_pData(NULL), m_nSize(0)
{
	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_hFont != NULL)
	{
		RemoveFontMemResourceEx(m_hFont);
		m_hFont = NULL;
	}

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

	FreeResource(m_lpResrc);
	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 NULL;

	m_nSize = SizeofResource(hInst, hResrc);
	m_lpResrc = (BYTE*)LoadResource(hInst, hResrc);
	if (m_lpResrc == NULL)
		return FALSE;

	m_pData = (BYTE*)LockResource(m_lpResrc);

	// GDI
	m_nFontIndex = 0;
	HANDLE m_hFont = 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_hFont == 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;
}

BOOL CFontHelper::LoadFont(wchar_t* lpszFile, LPCTSTR lpszType/* = _T("ttf")*/)
{
	// GDI+
	Gdiplus::Status nResults = m_pFontCollection->AddFontFile(lpszFile);
	if (nResults != Gdiplus::Ok)
		return FALSE;

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

	// GDI
	if (lpszFile == NULL || lpszType == NULL)
		return FALSE;

	m_strFontFile = lpszFile;
	m_nFontIndex = AddFontResourceExA(lpszFile, FR_PRIVATE, NULL);// 返回私有字体个数
	if (m_nFontIndex <= 0)
		return FALSE;

	wchar_t wszFontName[32] = { 0 };
	m_pFontFamily->GetFamilyName(wszFontName);
	char* szFontName = Unicode2Ansi(wszFontName);

	LOGFONT logFont;
	memset(&logFont, 0x0, sizeof(logFont));
	logFont.lfHeight = 9;
	logFont.lfWeight = FW_NORMAL;// FW_NORMAL; FW_BOLD
	logFont.lfCharSet = GB2312_CHARSET;
	_tcscpy_s(logFont.lfFaceName, LF_FACESIZE, szFontName);
	logFont.lfQuality = CLEARTYPE_QUALITY;
	logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
	logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS;
	logFont.lfCharSet = DEFAULT_CHARSET;
	logFont.lfPitchAndFamily = DEFAULT_PITCH;
	m_hFont = ::CreateFontIndirectA(&logFont);
	delete szFontName;

	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 FALSE;

	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)
	{
		ATLASSERT(FALSE);
		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::Font(Gdiplus::FontStyle fontstyle/* = FontStyleRegular*/, REAL nFontSize/* = 14.0F*/)
{
	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return FALSE;

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

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

// GDI
CFontHelper::operator HFONT() const
{
	return m_hFont;
}

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)CFontHelper::getSingletonPtr()->GetSafeHFONT(hWnd), TRUE);
}

这里用到了一个安全指针类型单实例模板-Singleton<class T>,不需要的可以直接删除。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值