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);
    }
}

代码说明:

  1. 代码创建了一个内存 DC 和一个位图,并将位图选入内存 DC。
  2. 在内存 DC 上绘制文本,并使用 GetTextExtentPoint32 获取文本的大小。
  3. 在客户区域 (WM_PAINT 消息) 上绘制相同的文本。

关键点:

  • 代码使用两个 DC 和两个位图,因为我们需要在内存 DC 上绘制文本来获取其大小,但我们不希望在客户区域上绘制文本时拉伸或压缩它。
  • 通过使用内存 DC,我们可以获得文本的真实大小,并避免在客户区域绘制时出现拉伸或压缩。

总结

本文提供了一个完整的代码示例,演示如何在 VC++ 中绘制图形并获取字符长度,同时避免在客户区域绘制时出现拉伸或压缩的问题。希望本文能够帮助您理解如何在 VC++ 中进行图形绘制并获取字符长度。

注意: 本文代码仅供参考,您可能需要根据您的具体需求进行修改。

VC++ 绘图获取字符长度:避免拉伸压缩的代码实现

原文地址: https://www.cveoy.top/t/topic/nRub 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录