书籍:《Visual C++ 2017从入门到精通》的2.3.8 Win32控件编程

环境:visual studio 2022

内容:【例2.33】字体选择对话框

说明:以下内容大部分来自腾讯元宝。

根据检索结果,您提到的 ​CHOOSEFONT 结构体属于 Windows API 中的 ​公用对话框库​(Common Dialog Box Library),用于配置和显示字体选择对话框。以下从结构定义、成员功能及使用场景三个维度进行详细分析:


一、结构定义与核心成员

CHOOSEFONT 结构体 用于初始化字体选择对话框的参数,其定义如下(基于 Windows API 常规规范,具体字段可能因系统版本略有差异):

typedef struct tagCHOOSEFONT {
    DWORD      lStructSize;      // 结构体大小,需设置为 sizeof(CHOOSEFONT)
    HWND       hwndOwner;         // 父窗口句柄
    HDC        hDC;               // 设备上下文句柄(通常为当前设备上下文)
    LPLOGFONT  lpLogFont;         // 指向 LOGFONT 结构体的指针,用于存储用户选择的字体属性
    LPCTSTR    lpCaption;         // 对话框标题
    DWORD      Flags;             // 选项标志(如 CF_SCREENFONTS、CF_EFFECTS 等)
    LPARAM     lCustData;         // 自定义数据,传递给钩子函数
    LPOFNHOOKPROC lpfnHook;      // 钩子函数指针,用于自定义对话框行为
    LPCTSTR    lpTemplateName;    // 自定义模板资源名称(通常为 NULL)
    DWORD      rgbColors;         // 颜色选择(仅在支持颜色选择时使用)
} CHOOSEFONT, *LPCHOOSEFONT;

关键成员说明

  1. lpLogFont:指向 LOGFONT 结构体,用于接收用户选择的字体属性(如字体名称、字号、样式等)。
  2. Flags:控制对话框行为的标志位,常用值包括:
    • CF_SCREENFONTS:仅显示屏幕字体。
    • CF_EFFECTS:允许选择字体效果(如斜体、下划线)。
  3. lpfnHook:自定义钩子函数,用于扩展对话框功能(如添加额外控件)。

二、典型应用场景

1. ​基础字体选择

通过 ChooseFont 函数调用对话框,示例代码如下:

CHOOSEFONT cf = {0};
LOGFONT lf = {/* 初始化字体属性 */};
cf.lStructSize = sizeof(CHOOSEFONT);
cf.hwndOwner = hWnd;          // 父窗口句柄
cf.lpLogFont = &lf;           // 指向 LOGFONT 结构体
cf.Flags = CF_SCREENFONTS | CF_EFFECTS; // 启用屏幕字体和效果选择

if (ChooseFont(&cf)) {
    // 用户选择了字体,可通过 cf.lpLogFont 获取属性
    DrawText(hdc, "测试文本", -1, &rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
}
2. ​动态字体属性绑定

结合 LOGFONT 结构体,可实现动态字体调整:

LOGFONT lf = {0};
lf.lfHeight = 20;            // 字号
lf.lfWeight = FW_NORMAL;     // 字体粗细
wcscpy_s(lf.lfFaceName, L"Arial"); // 字体名称

CHOOSEFONT cf;
cf.lpLogFont = &lf;
cf.Flags = CF_INITTOLOGFONTSTRUCT; // 初始化时绑定 LOGFONT

if (ChooseFont(&cf)) {
    // 更新控件字体
    SendMessage(hWndEdit, WM_SETFONT, (WPARAM)cf.lpLogFont->lfFaceName, TRUE);
}
3. ​高级自定义扩展

通过钩子函数 lpfnHook 实现自定义对话框行为:

INT_PTR CALLBACK FontHookProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
    if (msg == WM_INITDIALOG) {
        // 添加自定义控件或逻辑
        AddFontStyleButton(hwndDlg);
    }
    return 0;
}

CHOOSEFONT cf;
cf.lpfnHook = FontHookProc; // 设置钩子函数

三、与公用对话框库的关联

  1. 统一接口设计
    CHOOSEFONT 与 OPENFILENAME(文件对话框)、CHOOSECOLOR(颜色对话框)等结构体遵循相似的设计模式,均通过初始化结构体字段并传递指针给 API 函数(如 ChooseFont)来配置对话框行为。
  2. 动态数组支持
    在支持动态数组的 Windows 版本中,CHOOSEFONT 可处理复杂参数组合,例如同时选择字体和颜色(需结合 CHOOSECOLOR)。

四、注意事项

  1. 兼容性
    • 部分旧版系统可能不支持 CF_EFFECTS 等标志,需通过 CommDlgExtendedError 函数检查错误代码。
    • Unicode 编译时需使用 LPTSTR 类型,确保字符串兼容性。
  2. 性能优化
    • 避免频繁创建 CHOOSEFONT 实例,建议重用结构体以减少内存分配开销。
    • 使用 CF_INITTOLOGFONTSTRUCT 标志可减少初始化时间。

总结

CHOOSEFONT 结构体 是 Windows API 中实现字体选择功能的核心组件,其设计理念与 OPENFILENAME 等结构体一致,均通过参数化配置简化对话框操作。实际开发中需注意版本兼容性和性能优化,复杂场景可结合钩子函数实现高度定制化。如需完整定义,建议查阅微软官方网页或通过 Windows.h 头文件确认。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐