【问题标题】:Resize window to fit content after WM_PAINT调整窗口大小以适应 WM_PAINT 之后的内容
【发布时间】:2015-03-10 06:11:46
【问题描述】:

有没有办法在所有 WM_PAINT 调用完成后调整大小?这样我就可以自动调整窗口大小以适应我绘制的任何内容,因为最初我的窗口大小被定义为某个大小,可能会有未绘制的剩余空间,我如何删除这些剩余空间? 正如您从下面的屏幕截图中看到的那样,空白是剩余的空间。

#include <windows.h>
#include "resource.h"
#include "loadFromTextFile.h"

const char g_szClassName[] = "myWindowClass";
const int recLength = 3;
const int wndHeight = 700;
const int wndWidth = 700;
PAINTSTRUCT ps;
HDC            hdc;
HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0));
HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
HPEN myPen = CreatePen(PS_NULL, 1, RGB(0, 0, 0));

//load from text
string FILE_PATH = ("10x10.txt");
loadFromTextFile loaded = loadFromTextFile(FILE_PATH);
int mazeWidth = loaded.getColumns() * recLength;
int mazeHeight = loaded.getRows() * recLength;
void paintMaze(HWND hwnd, vector<vector<string> > grid){
    hdc = ::BeginPaint(hwnd, &ps);
    SelectObject(hdc, myPen);

    for (int r = 0; r < loaded.getRows(); r++){
        for (int c = 0; c < loaded.getColumns(); c++){

            RECT rect;
            rect.left = c*recLength;//x upper left
            rect.top = r*recLength;//y upper left
            rect.right = (c + 1)*recLength;//x lower right corner
            rect.bottom = (r + 1)*recLength;//y lower right corner

            if (grid[r][c] == "1"){//1 path

                FillRect(hdc, &rect, blackBrush);
            }
            else if (grid[r][c] == "0"){//wall

                FillRect(hdc, &rect, whiteBrush);
            }
            if (r == 50 && c == 50){
                FillRect(hdc, &rect, redBrush);
            }
        }
    }
    DeleteObject(blackBrush);
    DeleteObject(whiteBrush);
    DeleteObject(redBrush);
    DeleteObject(myPen);
    EndPaint(hwnd, &ps);
}
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case ID_FILE_EXIT:
            PostMessage(hwnd, WM_CLOSE, 0, 0);
            break;
        case ID_ABOUT:
            SetWindowPos(hwnd, 0, 0, 0, mazeWidth, mazeHeight, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
            break;
        }
        break;
    case WM_PAINT:

        {
            paintMaze(hwnd, loaded.getNodeGrid());
        }

        break;


    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    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 = MAKEINTRESOURCE(IDR_MENU1);;
    wc.lpszClassName = g_szClassName;
    wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
    wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, 0);

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        " Maze",
        WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU,//prevent resize
        CW_USEDEFAULT, CW_USEDEFAULT, wndWidth, wndHeight,
        NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while (GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

【问题讨论】:

  • "... 调整我的窗口大小以适应我绘制的任何内容," 当你绘制内容时,你应该知道它的范围。只需使用后者来调整窗口大小。

标签: c++ c winapi


【解决方案1】:

在屏幕外缓冲区中绘制。

这允许您调整窗口大小。

通过复制缓冲区来绘制窗口。

【讨论】:

  • 你好,有代码示例吗?它叫什么技术?我对 win32 gui 完全陌生
  • 有些人称之为双缓冲。我想你可以很容易地找到样品。如果没有,则 CreateBitmap、CreateDC 等等。
  • 这要求您能够创建宽度和高度的上限。如果你能做到这一点,那么精确计算它们的大小可能很容易。此时不需要离屏。
  • 绘制到缓冲区后在哪里调整窗口大小?
猜你喜欢
  • 2011-10-22
  • 1970-01-01
  • 2021-12-17
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 2014-07-04
  • 2020-06-07
  • 1970-01-01
相关资源
最近更新 更多