I'm struggling to figure out the proper way of dumping an array of plain RGBA values into the client area of a Win32 window during WM_PAINT. I have the following code but it already seems convoluted and I'm not even finished:
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
{
PAINTSTRUCT paintInfo{};
HDC device = BeginPaint(window, &paintInfo);
if (device == nullptr)
throw runtime_error(RG_LOCATION());
ScopeExit endPaint([&] { EndPaint(window, &paintInfo); });
HDC offscreenDevice = CreateCompatibleDC(device);
ScopeExit deleteOffscreenDevice([&] { DeleteDC(offscreenDevice); });
HBITMAP offscreenBitmap = CreateCompatibleBitmap(device, Distance(paintInfo.rcPaint.left, paintInfo.rcPaint.right),
Distance(paintInfo.rcPaint.top, paintInfo.rcPaint.bottom));
ScopeExit deleteOffscreenBitmap([&] { DeleteObject(offscreenBitmap); });
HBITMAP previousBitmap = reinterpret_cast<HBITMAP>(SelectObject(offscreenDevice, offscreenBitmap));
// now I need to blit the available pixel data...
vector<array<uint8_t, 4>> mypixels;
// ...onto the client area of the window.
// What do I do next?
// CreateDIBSection ?
// BitBlt ?
return 0;
}
I have some wiggle room with regards to the source "image" memory format so I can make that match whatever the target requires.
Am I doing this correctly? Is there a better way?
P.S.: Obviously I would be storing and not recreating most of the objects each time a WM_PAINT comes along. This is just an example/WIP.
Edit: Added handling of WM_ERASEBKGND.
Edit 2: Ok, it seems I need to be more specific. I am not looking for actual issues with the code I posted. It is only an example of what I have so far in terms of workflow. That means I have the window HDC, an offscreen HDC, an offscreen HBITMAP and a pointer to my pixels which are in, let's say, a hypothetical R8G8B8A8 memory layout. What do I do with these objects? Do I create another HBITMAP via CreateDIBSection and write my pixels into that? What do I do with it after?
Edit 3: See answer from Barmak Shemirani for proper solution (my example code has issues). Check also Paul Sanders' answer for some modern WinAPI tips.
Thanks all!