详细介绍HFONT结构体
书籍:《Visual C++ 2017从入门到精通》的2.3.8 Win32控件编程
环境:visual studio 2022
内容:【例2.33】字体选择对话框。
说明:以下内容大部分来自腾讯元宝。
一、HFONT 的基本概念
HFONT
是 Windows 图形设备接口(GDI)中用于表示字体对象的句柄类型,其本质是一个指向 LOGFONT
结构体的指针。通过 HFONT
,开发者可以动态创建、选择和销毁字体对象,实现文本渲染的灵活控制。
二、HFONT 的核心功能
-
字体属性封装
HFONT
隐含存储了字体的所有关键属性,包括:- 字体名称(如
"Arial"
) - 字号(以逻辑单位表示)
- 字体样式(粗体、斜体等)
- 字符集(如
ANSI_CHARSET
或UNICODE_CHARSET
) - 输出精度(如抗锯齿)
- 扩展样式(如脚本方向)
- 字体名称(如
-
资源管理
- 通过
CreateFont
创建字体时,系统分配内存并初始化LOGFONT
结构体。 - 使用完毕后需调用
DeleteObject
释放资源,避免内存泄漏。
- 通过
三、HFONT 的内存布局与对齐
根据结构体对齐原则,HFONT
的内部实现需遵循以下规则:
-
指针对齐
- 在 32 位系统中,
HFONT
作为指针占 4 字节,指向的LOGFONT
结构体需按 4 字节对齐。 - 在 64 位系统中,
HFONT
指针占 8 字节,LOGFONT
结构体需按 8 字节对齐。
- 在 32 位系统中,
-
成员对齐示例
假设LOGFONT
包含以下成员(简化版):typedef struct tagLOGFONT { LONG lfHeight; // 4 字节 LONG lfWidth; // 4 字节 LONG lfEscapement; // 4 字节 LONG lfOrientation; // 4 字节 LONG lfWeight; // 4 字节 BYTE lfItalic; // 1 字节(需填充至 4 字节边界) BYTE lfUnderline; // 1 字节(需填充至 4 字节边界) BYTE lfStrikeOut; // 1 字节(需填充至 4 字节边界) BYTE lfCharSet; // 1 字节 BYTE lfOutPrecision; // 1 字节 BYTE lfClipPrecision; // 1 字节 BYTE lfQuality; // 1 字节 BYTE lfPitchAndFamily; // 1 字节 WCHAR lfFaceName[LF_FACESIZE]; // 32 字节 } LOGFONT;
- 对齐影响:
lfItalic
、lfUnderline
、lfStrikeOut
后可能填充 3 字节,使结构体总大小为 64 字节(在 32 位系统中)。- 在 64 位系统中,
LOGFONT
的总大小可能扩展至 96 字节(因指针和填充调整)。
- 对齐影响:
四、HFONT 的典型应用场景
-
动态字体配置
通过CreateFontIndirect
结合LOGFONT
结构体创建自定义字体:LOGFONT lf = {0}; wcscpy_s(lf.lfFaceName, L"Arial"); lf.lfHeight = -MulDiv(20, GetDeviceCaps(hdc, LOGPIXELSY), 72); HFONT hFont = CreateFontIndirect(&lf); SelectObject(hdc, hFont);
-
字体资源复用
多个设备上下文(DC)可共享同一HFONT
,避免重复创建相同字体对象。 -
跨设备兼容性
通过lfEscapement
和lfOrientation
控制文本方向,适配不同屏幕或打印机。
五、关键注意事项
-
对齐与性能
- 错误的对齐可能导致 CPU 多次访问内存(如 32 位系统访问未对齐的 64 位指针),降低性能。
- 使用
#pragma pack
或__declspec(align())
可显式控制结构体对齐(需谨慎测试)。
-
字符集兼容性
- 若需支持多语言,需设置
lfCharSet
为SYMBOL_CHARSET
或特定语言字符集(如GB2312_CHARSET
)。
- 若需支持多语言,需设置
-
资源释放
- 忘记调用
DeleteObject
会导致内存泄漏,建议使用 RAII 模式管理字体对象。
- 忘记调用
六、与相关概念的对比
概念 | 功能 | 适用场景 |
---|---|---|
HFONT | 表示字体对象,管理字体属性 | 动态文本渲染、界面定制 |
LOGFONT | 定义字体属性的结构体 | 配置字体参数、持久化存储 |
CreateFont | 创建字体对象 | 初始化字体资源 |
DeleteObject | 释放 GDI 对象 | 资源管理、防止泄漏 |
总结
HFONT
是 Windows GDI 中字体管理的核心抽象,其设计需严格遵循内存对齐规则以保证性能。实际开发中需结合 LOGFONT
结构体精细控制字体属性,并注意资源释放与跨平台兼容性。对于复杂场景(如自定义字体渲染),可进一步探索 GDI+
或 DirectWrite API。