Enabling output buffering in windows.h's WM_PAINT

-1

EDIT: I am aware this is the slowest way to draw a square, but I do need to set pixels individually for a separate purpose.


I'm pretty sure what I'm trying to do is create a Frame Buffer. I have the following code:

... /* Other Unrelated (<- I promise) Code */

    switch(message)
{
    /*  Window is being created*/
    case WM_CREATE: 
        return 0;
        break;
    /*  Window is closing*/
    case WM_CLOSE: 
        PostQuitMessage(0);
        return 0;
        break;
    /*  Window needs update*/
    case WM_PAINT: 
        hDC = BeginPaint(hwnd,&paintStruct);
        /*  Draw a Red Square pixel by pixel*/
        for (int x=100;x<300;x++) {
            for (int y = 300;y>100;y--) {
                SetPixel(hDC, x, y, 0x000000FF);
            }
        }

        EndPaint(hwnd, &paintStruct);
        return 0;
        break;
    default:
        break;
}

... /* Other Unrelated (<- I promise) Code*/

The desired result

A red square that doesn't show each pixel being drawn, but rather, just a red square being drawn instantaneously. To break it down, I want the memory to fill up before releasing it to video memory rather than going 1 by 1 to video memory (I hope I'm using the right words here...)


The problem

The opposite of the desired result, I am getting a quick drawing of the square from left right as each pixel is being set.


What I'm looking for

A command to enable output buffering to my window or a function to store pixels then draw them all at once, or any other method that would get me the desired result.

Thank you in advance. I think it would be helpful to say that I have only been programming in the C++ language for 5 days, and that any breaking down or direct answer would be greatly appreciated.

c++
windows
winapi
wm-paint
asked on Stack Overflow Jan 23, 2018 by Corpus Shmorpus • edited Jan 23, 2018 by Corpus Shmorpus

1 Answer

1

You need to create a memory HDC, and a bitmap, select the bitmap in to memory, draw on memory, then BitBlt the memory dc on to the final HDC. Example:

case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);

    HDC memdc = CreateCompatibleDC(hdc);
    HBITMAP bitmap = CreateCompatibleBitmap(hdc, 300, 300);
    HBITMAP oldbmp = (HBITMAP)SelectObject(memdc, bitmap);

    for(int x = 100; x<300; x++)
        for(int y = 300; y>100; y--)
            SetPixelV(memdc, x, y, 0x000000FF);
    BitBlt(hdc, 0, 0, w, h, memdc, 0, 0, SRCCOPY);

    //cleanup:
    SelectObject(memdc, oldbmp);
    DeleteDC(memdc);
    DeleteObject(bitmap);
    EndPaint(hWnd, &ps);
    return 0;
}

Note that you have access to all GDI functions. In this example you can use FillRect instead:

RECT rc{ 100, 100, 300, 300 };
SetDCBrushColor(memdc, RGB(255, 0, 0));
FillRect(memdc, &rc, (HBRUSH)GetStockObject(DC_BRUSH));

Or use GetDIBits to manipulate the bitmap.

answered on Stack Overflow Jan 24, 2018 by Barmak Shemirani • edited Jan 24, 2018 by Barmak Shemirani

User contributions licensed under CC BY-SA 3.0