Render Buffer on Screen in Windows

Go To StackoverFlow.com

4

I'm searching for a way rendering a char buffer onto the content-area of a window. This is just pseudo but intended to demonstrate what I actually want to do:

char buffer[300][200][3];    // 300px x 200px x RGB bytes
// ... render stuff into buffer
FancyWindowsFunctionToRenderBufferOnWindow(my_hwnd, buffer, 300, 200, offset_x, offset_y);

Is there a way to do something similar?

2012-04-05 21:49
by Niklas R
This question is very broad, maybe you want winapi DrawText - Jesse Good 2012-04-05 22:02
Are you drawing the text onto your own window or another program's window - chris 2012-04-05 22:11
@Jesse,chris How do you guys come to the conclusion that I want to draw Text on a Window?`^ - Niklas R 2012-04-07 09:17


7

I think you need to create a device independent bitmap (DIB). If you already have an array of pixels that is ready to be put on an application window, you may need to copy the whole array to the buffer allocated by the CreateDIBSection API and call BitBlt to transfer the DIB to the window. This is the only way I know to show a mere array of pixels as a visible picture on the computer screen on Win32 platform and it is highly complicated and difficult to understand.

Here are the steps I used to take to test things similar to what you want to do:

Creating DIB:

BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = /* Width of your image buffer */
bmi.bmiHeader.biHeight = - /* Height of your image buffer */
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;

HDC hDesktopDC = GetDC(GetDesktopWindow());
HBITMAP hDib = CreateDIBSection(hDesktopDC, &bmi, DIB_RGB_COLORS, (void **)&buffer, 0, 0);
if (buffer == NULL) { /* ERROR */ }
HDC hDibDC = CreateCompatibleDC(hDesktopDC);
HGDIOBJ hOldObj = SelectObject(hDibDC, hDib);

/* Copy your array of pixels to buffer allocated above. */

ReleaseDC(GetDesktopWindow(), hDesktopDC);

Implementing WM_PAINT event handler (the hWnd variable holds the window handle below):

case WM_PAINT:
    PAINTSTRUCT paint;
    HDC hWndDc = BeginPaint(hWnd, &paint);
    BitBlt(hWndDC, 0, 0, /* Width of DIB */, /* Height of DIB */,
           /* HDC of DIB (hDibDC in the above) */, 0, 0, SRCCOPY);
    EndPaint(hWnd, &paint);
    break;

I don't really expect the above code snippets would directly help you. If you are determined to use GDI functions like ones in the above snippets, I recommend you to read very carefully their API documents on MSDN. Because it is very tricky to properly release or delete DCs or GDI objects acquired during using the APIs.

2012-04-07 12:44
by M. Shiina


5

It sounds like you have an image (raster) stored as an array of chars (which is an odd choice, since you'd usually want an array of unsigned chars for raw bitmap images).

If you meet certain alignment constraints, you can display your bitmap pretty directly with SetDIBits. You fill out a BITMAPINFO structure that describes the pixel format and image dimensions, and then you pass that along with your data to SetDIBits. It'll paint them to a DC. It can be a little tricky to get all the parameters right.

The alignment requirement is that each scanline must begin on a 4-byte boundary. If you don't meet that requirement, you'll get garbage similar to having the wrong stride. You can make a copy of the data with the correct alignment if necessary.

2012-04-05 22:57
by Adrian McCarthy
Thank you, I will check it out! You're right, you usually use unsigned char for RGB values, didn't remember that while writing the question - Niklas R 2012-04-07 09:24
Ads