书籍:《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。



6924

被折叠的 条评论
为什么被折叠?



