5

I'm an absolute beginner at this but have managed to blunder my way to 93% of where I want to be. Need help for the final 7%.

I've manually created a bitmap like so:

BITMAPINFO bmpInfo = { 0 };
BITMAPINFOHEADER bmpInfoHeader = { 0 };
BITMAP ImageBitmap;
void *bits;

bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biBitCount = 32;
bmpInfoHeader.biClrImportant = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biCompression = BI_RGB;
bmpInfoHeader.biHeight = -IMAGE_DISPLAY_HEIGHT;
bmpInfoHeader.biWidth = IMAGE_DISPLAY_WIDTH;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biSizeImage = IMAGE_DISPLAY_WIDTH * IMAGE_DISPLAY_HEIGHT * 4;

ZeroMemory(&bmpInfo, sizeof(bmpInfo));
bmpInfo.bmiHeader = bmpInfoHeader;
bmpInfo.bmiColors->rgbBlue = 0;
bmpInfo.bmiColors->rgbGreen = 0;
bmpInfo.bmiColors->rgbRed = 0;
bmpInfo.bmiColors->rgbReserved = 0;

g_hImageBitmap = CreateDIBSection(hDC, &bmpInfo, DIB_RGB_COLORS, &bits, NULL, 0);
GetObject(g_hImageBitmap, sizeof(BITMAP), &ImageBitmap);

for (i = 0; i < IMAGE_DISPLAY_WIDTH; i++) {
    for (j = 0; j < IMAGE_DISPLAY_HEIGHT; j++) {
        ((unsigned char *)bits)[j*IMAGE_DISPLAY_WIDTH * 4 + i * 4] = 255;         // Blue
        ((unsigned char *)bits)[j*IMAGE_DISPLAY_WIDTH * 4 + i * 4 + 1] = 255;     // Green
        ((unsigned char *)bits)[j*IMAGE_DISPLAY_WIDTH * 4 + i * 4 + 2] = 255;     // Red
        ((unsigned char *)bits)[j*IMAGE_DISPLAY_WIDTH * 4 + i * 4 + 3] = 0;
    }
}

g_ImageBitmapPixels = bits;

and elsewhere WM_PAINT handles drawing this like so

hdc = BeginPaint(hwnd, &ps);

if (g_hImageBitmap != NULL) {
    GetObject(g_hImageBitmap, sizeof(BITMAP), &bm);
    hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, g_hImageBitmap);
    BitBlt(hdc, UPPER_LEFT_IMAGE_X, UPPER_LEFT_IMAGE_Y,
        bm.bmWidth, bm.bmHeight, hMemoryDC, 0, 0, SRCCOPY);
    SelectObject(hMemoryDC, hOldBitmap);
}

Given the global variable g_ImageBitmapPixels other parts of the program can change and manipulate individual pixels in the bitmap, and when that happens, I use

InvalidateRect(hwnd, &RECT_ImageUpdate_Window, TRUE);
UpdateWindow(hwnd);

to update just that little portion of the screen. Works great. Hooray for me.

To get to the point, my question is, if a function has ONLY the HBITMAP (g_hImageBitmap) ... is there a way to call the Windows library functions to draw lines, text, circles, filled circles, to the HBITMAP? Like these functions

MoveToEx(hDC, x1, y1, NULL);
LineTo(hDC, x2, y2 );

HBRUSH hRedBrush = CreateSolidBrush(RGB(255, 0, 0));
FillRect(hDC, &somerectangle, hRedBrush);

except instead of needing a device context, they just take the HBITMAP?

I have a pointer to the actual pixels (g_ImageBitmapPixels) so I could just write my own line drawing, circle drawing, rectangle filling functions. Indeed I have done that, but it seems a shame not to use the functions Microsoft so kindly provides. Also, I'm not smart enough to make my own text-drawing functions.

Thank you for your help.

pgg
  • 49
  • 2
  • 1
    Create a compatible device context. Select the bitmap into the device context. Draw to the context. – Captain Obvlious Jul 14 '15 at 00:54
  • https://msdn.microsoft.com/en-us/library/windows/desktop/dd145049(v=vs.85).aspx might help you with that. And ``CreateCompatibleDC()``and ``SelectObject()`` is probably the function you are looking for. – BitTickler Jul 14 '15 at 00:54
  • 1
    @Olaf The same solution applies equally to both languages and in terms of usefulness allowing this post to be picked up in both `C` and `C++` tagged queries makes the use of both tags IMHO perfectly fine. – Captain Obvlious Jul 14 '15 at 01:02
  • @Olaf Tags are correct. Winapi is common for both languages. – this Jul 14 '15 at 01:04
  • @CaptainObvlious: Fair enough. I'm just not sure about the casts for C++. Never mind! – too honest for this site Jul 14 '15 at 01:05
  • Thanks so much - I figured it would be something simple and obvious. Still figuring my way around device contexts. Not an intuitive way of thinking to me, yet. :-) – pgg Jul 14 '15 at 01:33

0 Answers0