最近更新于 2024-05-05 14:18
环境
Windows 11 专业工作站版 22H2
Visual Studio 2022 专业版
使用 Unicode 字符集,C17 标准编译,64 位编译
文字绘制(颜色、背景透明、背景色)
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps = {0};
HDC hdc = BeginPaint(hWnd, &ps);
COLORREF oldColor = SetTextColor(hdc, RGB(255, 0, 0)); // 文字颜色设为红色,并保存原来的颜色
// 文字绘制方式 1
// DC 句柄
// 文字行左上角坐标 x
// 文字行左上角坐标 y
// 显示文字内容
// 文字内容的长度
TextOut(hdc, 200, 50, L"你好啊!", wcslen(L"你好啊!"));
RECT rect1 = {10, 10, 50, 200}; // 矩形结构,左上角坐标和右下角坐标
SetBkMode(hdc, TRANSPARENT); // 设置文字显示背景透明,透明状态下,设置文字背景色无效,不透明是默认状态
// 文字绘制方式 2
// DC 句柄
// 显示文字内容
// 文字内容长度
// 绘制文字的矩形区域
// 文字显示格式,比如这里 DT_LEFT 靠左,DT_WORDBREAK 在行显示满时支持换行继续显示,DT_NOCLIP 支持在行显示单词超出矩形区域时依然完整显示,不剪裁
DrawText(hdc, L"DrawText ABC 文字输出", wcslen(L"DrawText ABC 文字输出"), &rect1, DT_LEFT | DT_WORDBREAK | DT_NOCLIP);
RECT rect2 = {100, 100, 140, 200};
SetTextColor(hdc, oldColor); // 改回默认的字体颜色
SetBkMode(hdc, OPAQUE); // 设置文字显示背景不透明
SetBkColor(hdc, RGB(0, 0, 255)); // 背景色设为蓝色
DrawText(hdc, L"DrawText ABC 文字输出", wcslen(L"DrawText ABC 文字输出"), &rect2, DT_LEFT | DT_WORDBREAK);
EndPaint(hWnd, &ps);
break;
}
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
return 0;
}
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
PCWSTR szClassName = L"Desktop";
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpszClassName = szClassName;
wc.lpfnWndProc = WndProc;
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"注册窗口失败!", L"错误", MB_OK);
return 1;
}
HWND hWnd = CreateWindowEx(0, szClassName, L"简单程序", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
MessageBox(NULL, L"创建窗口失败!", L"错误", MB_OK);
return 1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
字体
系统字体保存在 C:\Windows\Fonts
使用字体时要用到字体的名字,注意字体的名字并不一定是文件名
需要将字体文件直接打开,预览页面上会显示字体的名字
比如这个文件名叫新宋体,但是字体的名字就叫宋体
#include <Windows.h>
HFONT g_hFont = {0}; // 字体句柄。
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps = {0};
HDC hdc = BeginPaint(hWnd, &ps);
HGDIOBJ hOldFont = SelectObject(hdc, g_hFont); // 切换使用加载的字体
TextOut(hdc, 70, 120, L"你好啊 ABC 123", wcslen( L"你好啊 ABC 123"));
SelectObject(hdc, hOldFont); // 换回默认的字体
EndPaint(hWnd, &ps);
break;
}
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
DeleteObject(g_hFont); // 销毁字体资源
break;
}
default:
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
return 0;
}
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
// 创建字体句柄 - 字体比较大放到窗口过程的话,一直调用消耗资源大,放到全局变量只用加载一次
g_hFont = CreateFont(0, // 字体高度,指定 0 按照默认处理
0, // 字体宽度,指定 0 按照默认处理
300, // 转义向量与设备的 x 轴之间的角度(单位为 0.1°,下同),转义向量与文本行的基线并行
0, // 每个字符的基线与设备的 x 轴之间的角度
FW_NORMAL, // 字体粗细,取值 0~100,400 正常,700 为粗体,设 0 为默认(FW_NORMAL)。有定义宏,可以参考开发文档
FALSE, // 是否斜体
TRUE, // 是否有下划线
FALSE, // 是否有删除线
GB2312_CHARSET, // 字符集 - 这里使用 GB2312_CHARSET(Windows 中文使用的字符集)
OUT_CHARACTER_PRECIS, // 输出精度,OUT_CHARACTER_PRECIS 未使用
CLIP_CHARACTER_PRECIS, // 剪裁精度, CLIP_CHARACTER_PRECIS 未使用
CLEARTYPE_QUALITY, // 输出质量,比如 CLEARTYPE_QUALITY 尽可能使用 ClearType 抗锯齿方法,NONANTIALIASED_QUALITY 不抗锯齿,不平滑字体
DEFAULT_PITCH | FF_DONTCARE, // 字体的音调和系列,DEFAULT_PITCH | FF_DONTCARE 都默认
L"华文琥珀"); // 字体名字
PCWSTR szClassName = L"Desktop";
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpszClassName = szClassName;
wc.lpfnWndProc = WndProc;
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"注册窗口失败!", L"错误", MB_OK);
return 1;
}
HWND hWnd = CreateWindowEx(0, szClassName, L"简单程序", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
MessageBox(NULL, L"创建窗口失败!", L"错误", MB_OK);
return 1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
桌面程序文字绘制 – Windows API