GUI 窗口在我最小化时不断关闭

问题描述 投票:0回答:1

我创建了一个窗口并在其上制作了一个矩形。当我最小化窗口时,程序崩溃了。我知道这是因为当我最小化缓冲区时,用于创建矩形的函数正在访问缓冲区外部的内存,这就是它不断崩溃的原因。

所以我尝试使用名为 limit() 的钳位函数来将限制保留在缓冲区内。但无论我如何尝试,当我最小化窗口时它仍然会崩溃。我复制了下面的代码,我认为主要问题来自 limit() 和 draw_rect() 函数中的某个地方。当我不运行draw_rect()函数而只运行render_background()时,我的窗口工作正常并且最小化时不会崩溃。

#include <windows.h>
#include <Memoryapi.h>
#include <stdio.h>
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "onecore.lib")

//global variables
bool run = true;
int width, height, buffer_memory_size;
void *memory;
BITMAPINFO BMINFO;

//function used to color background
void render_background()
{
     unsigned int *ptr = (unsigned int *)memory;

     for (int y = 0; y < height; y++)
     {
        for (int x = 0; x < width; x++)
        {
            *ptr = 0xff5500;

            ptr++;
        }
     }
}

//function used to keep draw_rect inside buffer 
void draw_rect(int x0, int y0, int x1, int y1, unsigned int color)
{   
    for (int y = limit(0,height - 1,y0); y <= limit(0,height - 1,y1); y++)
    {
        unsigned int *ptr = (unsigned int *)memory + y * width;

        for (int x = limit(0,width - 1,x0); x <= limit(0,width - 1,x1); x++)
        {
            ptr[x] = color;
        }
    }
}

//function used to draw rectangle
void draw_rect(int x0, int y0, int x1, int y1, unsigned int color)
{   
    for (int y = limit(0,height - 1,y0); y <= limit(0,height - 1,y1); y++)
    {
        unsigned int *ptr = (unsigned int *)memory + y * width;

        for (int x = limit(0,width - 1,x0); x <= limit(0,width - 1,x1); x++)
        {
            ptr[x] = color;
        }
    }
}

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        run = false;
        return 0;

    case WM_SIZE:
        //obtain the new size of the window and the memory size of new needed buffer
        RECT R;
        GetClientRect(hwnd,&R);

        width = R.right - R.left;
        height = R.bottom - R.top;
        buffer_memory_size = width*height*sizeof(unsigned int); //buffer memory size in terms of bytes

        //allocate memory in the heap for new buffer
        if (memory != NULL)
        {
            VirtualFree(memory,0,MEM_RELEASE);
        }

        memory = VirtualAlloc(0, buffer_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

        //update BMINFO with updated class members
        BMINFO.bmiHeader.biSize = sizeof(BMINFO.bmiHeader);
        BMINFO.bmiHeader.biWidth = width;
        BMINFO.bmiHeader.biHeight = height;
        BMINFO.bmiHeader.biPlanes = 1;
        BMINFO.bmiHeader.biBitCount = 32;
        BMINFO.bmiHeader.biCompression = BI_RGB;

        return 0;
    }
    
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    //create window class
    const wchar_t name[] = L"window class";

    WNDCLASS wc = {};

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpszClassName = name;
    wc.lpfnWndProc = MainWndProc;

    //register window class
    RegisterClass(&wc);

    //create window and display window
    HWND H = CreateWindowExW(0, name, L"First Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, 0, 0, hInstance, 0);
    HDC hdc = GetDC(H);


    //game loop
    while (run)
    {   
        MSG msg;

        //input
        while (PeekMessage(&msg, H, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        //logic
        render_background();

        //drawing rectangle x0 = 400, x1 = 700, y0 = 300, y1 = 500  
        draw_rect(400,300,700,500,0xff00ff);


        //rendering
        StretchDIBits(hdc,0,0,width,height,0,0,width,height,memory,&BMINFO,DIB_RGB_COLORS,SRCCOPY);
    }

    return 0;
}
c++ winapi buffer clamp
1个回答
0
投票

最小化时,

GetClientRect
返回
{0,0,0,0}
,其大小为0,分配零大小的缓冲区失败并返回nullptr

如果您勾选了GetClientRect备注。

为了符合 RECT 结构的约定,返回的矩形的右下坐标是不包括的。换句话说,(右、下)处的像素紧邻矩形外部。

换句话说,Windows API 中几乎所有的绘图和坐标都假定 end 是互斥的,您应该在代码中遵循此约定以避免类似的错误,因此以下代码是错误的

for (int y = y0; y <= y1; y++)

并且应该是

for (int y = y0; y < y1; y++)
© www.soinside.com 2019 - 2024. All rights reserved.