最近更新于 2023-03-05 16:20

环境

Windows SDK 10.0(Windows 11)
平台工具集:Visual Studio 2022 v143
C 语言标准:C17
字符集:Unicode

示例

基本使用示例

#include <Windows.h>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{

    CHOOSEFONT cf = {0}; // 字体选择对话框结构
    static LOGFONT lf; // 逻辑字体结构 - 选中的字体的返回值

    cf.lStructSize = sizeof (cf);
    cf.hwndOwner = NULL; // 所属窗口
    cf.lpLogFont = &lf;
    cf.rgbColors = RGB(0, 0, 255); // 初始字体颜色
    cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT; // Windows Vista 和 Windows XP/2000: 使对话框仅列出系统支持的屏幕字体 | rgbColors 指定初始文本颜色 | lpLogFont 初始化字体信息

    if (ChooseFont(&cf)==TRUE)
    {
        // cf.lpLogFont 逻辑字体特征
        // cf.rgbColors 字体颜色
    }
}

file

应用示例

#define _CRT_SECURE_NO_WARNINGS // 关闭不使用安全函数的警告
#include <Windows.h>

#define ID_EDIT         100
#define ID_BUTTON       101

LRESULT CALLBACK wndProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
    static CHOOSEFONT cf; // 字体选择对话框结构
    static LOGFONT lf; // 逻辑字体结构
    static HFONT hf; // 字体

    switch (msg)
    {
        case WM_CREATE:
        {
            // 编辑框和按钮绘制
            CreateWindowEx(0, L"EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_WANTRETURN,
                                       0, 0, 650, 600, wnd, (HMENU)ID_EDIT, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            CreateWindowEx(0, L"BUTTON", L"设置字体", WS_CHILD | WS_VISIBLE, 680, 280, 70, 20, wnd,
                           (HMENU)ID_BUTTON, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);

            // 初始字体信息
            lf.lfHeight = 0; // 默认高度
            lf.lfWidth = 0; // 自动匹配宽度
            lf.lfEscapement = 0; // 转义向量与设备的 x 轴之间的角度(以0.1度为单位)。 转义向量与文本行的基线并行
            lf.lfOrientation = 0; // 每个字符的基线与设备的 x 轴之间的角度(以度为单位)
            lf.lfWeight = 0; // 0 到 1000 范围内的字体粗细。 例如,400 是正常的,700 是粗体。 如果此值为零,则使用默认权重
            lf.lfItalic = FALSE; // 斜体
            lf.lfUnderline = FALSE; // 下划线
            lf.lfStrikeOut = FALSE; // 删除线
            lf.lfCharSet = DEFAULT_CHARSET; // 字符集。默认字符集跟随系统区域设置
            lf.lfOutPrecision = OUT_CHARACTER_PRECIS; // 输出精度。输出精度定义输出必须与所请求字体的高度、宽度、字符方向、转义、音调、音调和字体类型相匹配的方式。 这里不使用
            lf.lfClipPrecision = CLIP_CHARACTER_PRECIS; // 剪辑精度。 剪裁精度定义如何剪裁部分超出剪裁区域的字符。这里不使用
            lf.lfQuality = DEFAULT_QUALITY; // 输出质量。 输出质量定义图形设备界面 (GDI) 必须尝试将逻辑字体属性与实际物理字体的属性匹配的方式。这里设置的字体外观并不重要
            lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; // 字体的音调和系列。默认
            PCWSTR faceName = L"宋体";
            wcsncpy(lf.lfFaceName, faceName, wcslen(faceName)); // 字体

            // 初始化字体选择对话框结构体
            cf.lStructSize = sizeof(cf);
            cf.hwndOwner = wnd;
            cf.lpLogFont = &lf;
            cf.rgbColors = RGB(255, 0, 0); // 初始字体颜色
            cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT;

            // 按前面设置的初始字体信息创建字体实例
            hf = CreateFontIndirect(&lf);

            // 编辑框初始显示内容
            PCWSTR s = L"你好,世界!\r\n123 ABC abc";
            SetDlgItemText(wnd, ID_EDIT, s);

            break;
        }
        case WM_CTLCOLOREDIT: // 即将绘制编辑框时收到该消息,在这里设置字体颜色
        {
            if (GetDlgItem(wnd, ID_EDIT) == (HWND)lp)
            {
                SetTextColor((HDC)wp, cf.rgbColors);
            }
            break;
        }
        case WM_COMMAND:
        {
            if (LOWORD(wp) == ID_BUTTON && HIWORD(wp) == BN_CLICKED)
            {
                if (ChooseFont(&cf))
                {
                    DeleteObject(hf); // 删除旧字体实例
                    hf = CreateFontIndirect(&lf); // 用选择的字体信息创建字体实例
                    SendMessage(GetDlgItem(wnd, ID_EDIT), WM_SETFONT, (WPARAM)hf, TRUE); // 设置字体
                }
            }
            break;
        }
        case WM_CLOSE:
        {
            DestroyWindow(wnd);
            break;
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }
        default:
        {
            return DefWindowProc(wnd, msg, wp, lp);
        }
    }
    return 0;
}

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    PCWSTR className = L"desktopAPP";
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpszClassName = className;
    wc.lpfnWndProc = wndProc;
    if (!RegisterClassEx(&wc))
    {
        return 11;
    }

    HWND wnd = CreateWindowEx(0, className, L"通用字体对话框使用", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 800, 600, NULL, NULL, hInstance, NULL);
    if (!wnd)
    {
        return 12;
    }

    ShowWindow(wnd, nCmdShow);
    UpdateWindow(wnd);

    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
        TranslateMessage(&msg);
    }

    return (int)msg.wParam;
}

file
file

作者 IYATT-yx