调整窗口大小以适应 WM_PAINT 之后的内容

Posted

技术标签:

【中文标题】调整窗口大小以适应 WM_PAINT 之后的内容【英文标题】:Resize window to fit content after 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;

【问题讨论】:

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

在屏幕外缓冲区中绘制。

这允许您调整窗口大小。

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

【讨论】:

你好,有代码示例吗?它叫什么技术?我对 win32 gui 完全陌生 有些人称之为双缓冲。我想你可以很容易地找到样品。如果没有,则 CreateBitmap、CreateDC 等等。 这要求您能够创建宽度和高度的上限。如果你能做到这一点,那么精确计算它们的大小可能很容易。此时不需要离屏。 绘制到缓冲区后在哪里调整窗口大小?

以上是关于调整窗口大小以适应 WM_PAINT 之后的内容的主要内容,如果未能解决你的问题,请参考以下文章

win32自动调整父窗口大小以适合其内容

调整弹出窗口大小以适应图像大小

PyQt5 中当窗口大小改变时,如何去调整控件的位置以适应窗口大小改变的思考

如何调整 UITableViewCell 的大小以适应其内容?

调整 UIScrollView 的大小以适应其内容……不起作用

UIView - 调整大小以适应内容