VC++ 绘图获取字符长度:避免拉伸压缩的代码实现
VC++ 绘图获取字符长度:避免拉伸压缩的代码实现
本文将提供完整代码,演示如何在 VC++ 中绘制图形并获取字符长度,同时避免在客户区域绘制时出现拉伸或压缩的问题。
代码实现
#include <windows.h>
#include <tchar.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;
// 注册窗口类
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = _T("MyWndClass");
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// 创建窗口
hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
_T("MyWndClass"),
_T("My Window"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
640,
480,
NULL,
NULL,
hInstance,
NULL);
if (hWnd == NULL)
{
MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// 显示窗口
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// 消息循环
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static TCHAR szText[] = _T("Hello, World!");
static int cxText, cyText;
HDC hdc;
PAINTSTRUCT ps;
SIZE size;
switch (msg)
{
case WM_CREATE:
// 创建内存 DC 和位图
hdc = GetDC(hWnd);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, 640, 480);
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap);
DeleteObject(hBitmapOld);
ReleaseDC(hWnd, hdc);
// 在内存 DC 上绘制文本
hdc = hdcMem;
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0, 0, 255));
HFONT hFont = CreateFont(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, _T("Segoe UI"));
HFONT hFontOld = (HFONT)SelectObject(hdc, hFont);
TextOut(hdc, 50, 50, szText, _tcslen(szText));
SelectObject(hdc, hFontOld);
DeleteObject(hFont);
DeleteDC(hdc);
// 获取文本大小
hdc = GetDC(hWnd);
hdcMem = CreateCompatibleDC(hdc);
hBitmap = CreateCompatibleBitmap(hdc, 640, 480);
hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap);
BitBlt(hdcMem, 0, 0, 640, 480, hdc, 0, 0, SRCCOPY);
GetTextExtentPoint32(hdcMem, szText, _tcslen(szText), &size);
cxText = size.cx;
cyText = size.cy;
SelectObject(hdcMem, hBitmapOld);
DeleteObject(hBitmap);
DeleteDC(hdcMem);
ReleaseDC(hWnd, hdc);
return 0;
case WM_PAINT:
// 在客户区域绘制文本
hdc = BeginPaint(hWnd, &ps);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0, 0, 255));
HFONT hFont = CreateFont(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, _T("Segoe UI"));
HFONT hFontOld = (HFONT)SelectObject(hdc, hFont);
TextOut(hdc, 50, 50, szText, _tcslen(szText));
SelectObject(hdc, hFontOld);
DeleteObject(hFont);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
代码说明:
- 代码创建了一个内存 DC 和一个位图,并将位图选入内存 DC。
- 在内存 DC 上绘制文本,并使用
GetTextExtentPoint32获取文本的大小。 - 在客户区域 (
WM_PAINT消息) 上绘制相同的文本。
关键点:
- 代码使用两个 DC 和两个位图,因为我们需要在内存 DC 上绘制文本来获取其大小,但我们不希望在客户区域上绘制文本时拉伸或压缩它。
- 通过使用内存 DC,我们可以获得文本的真实大小,并避免在客户区域绘制时出现拉伸或压缩。
总结
本文提供了一个完整的代码示例,演示如何在 VC++ 中绘制图形并获取字符长度,同时避免在客户区域绘制时出现拉伸或压缩的问题。希望本文能够帮助您理解如何在 VC++ 中进行图形绘制并获取字符长度。
注意: 本文代码仅供参考,您可能需要根据您的具体需求进行修改。
原文地址: https://www.cveoy.top/t/topic/nRub 著作权归作者所有。请勿转载和采集!