Question

I must be doing something wrong or have missed something because all I actually want to is render a rectangle into a bitmap, so that I can CreateWindowEx() on it. Does anyone know what I'm missing?

HDC hdc = GetDC(hWnd);

// Create Pen and brush for the rectangle
HPEN pn = CreatePen(style, stroke, pen);
HBRUSH br = CreateSolidBrush(brush);

// Create a compatible bitmap and DC from the window DC with the correct dimensions
HDC bm_hdc = CreateCompatibleDC(hdc);
HBITMAP hImage = CreateCompatibleBitmap(bm_hdc, sz.x, sz.y);

// Select the bitmap, pen, brush into the DC
HGDIOBJ bm_obj = SelectObject(bm_hdc, hImage);
HGDIOBJ pn_obj = SelectObject(bm_hdc, pn);
HGDIOBJ br_obj = SelectObject(bm_hdc, br);

// Draw the rectangle into the compatible DC with the bitmap selected
::Rectangle(bm_hdc, xPos, yPos, xPos + xSize, yPos + ySize);

// Restore the old selections
SelectObject(bm_hdc, br_obj);
SelectObject(bm_hdc, pn_obj);
SelectObject(bm_hdc, bm_obj);

// Delete the not needed DC, pen and brush
DeleteDC(bm_hdc);
DeleteObject(br);
DeleteObject(pn);
ReleaseDC(hWnd, hdc);

// Create the window and send a message to set the static image
HWND win = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | SS_BITMAP | WS_VISIBLE, pos.x, pos.y, sz.x, sz.y, hWnd, NULL, hInst, NULL)));
HGDIOBJ obj = (HGDIOBJ)SendMessage(win, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);

// Delete the old image
if (obj)
    DeleteObject(hImage);

Hummmm... but this doesn't work... All I get is a completely black area and not the rectangle that I have drawn. Any ideas why? Do I need to create another DC and BitBlt() between device contexts?

Was it helpful?

Solution

Thanks for all the help everyone, but I've actually solved it myself and it was SUCH a silly mistake too... Consider this line...:-

::Rectangle(bm_hdc, xPos, yPos, xPos + xSize, yPos + ySize);

Nothing wrong with that at first glance, right? WRONG! If you look at my code, I create a compatible bitmap of the required size to contain my rectangle and try to render the rectangle into this bitmap (which is selected into the DC).

But... WHERE in the bitmap am I rendering? xPos and yPos are window positions of the rectangle, but I'm not rendering to the Window DC am I?!? d'oh! That's right, xPos and yPos should both be 0 because I'm rendering into a bitmap of the correct size and it's when the Window is displayed that xPos and yPos should contain screen coordinates!

Wow... what a dumb mistake and thanks for the nice spot on the HDC from the Window rather than from the compatible DC. I did know that a memory DC has a 1bit depth, but still made that classic blunder. Thanks everyone.

OTHER TIPS

Try changing this line HBITMAP hImage = CreateCompatibleBitmap(bm_hdc, sz.x, sz.y); into this :

HBITMAP hImage = CreateCompatibleBitmap(hdc, sz.x, sz.y);

Paul Watt wrote excellent articles for GDI and image composition with MsImage32.dll.

I am reffering you to this article because it addresses your problem, and here are the relevant quotes and code snippets:

The memory DC is initialized with a mono-chromatic 1x1 pixel bitmap by default.

Avoid a Common Mistake

Before we get too far away from code where I showed you what you need to start running, I want to make sure you are holding this new pair of scissors safely. Do not use a Memory DC with a call to CreateCompatibleBitmap.

...
// You may be tempted to do this; DON'T:
HDC     hMemDC = ::CreateCompatibleDC(hDC);
                                     // DON'T DO THIS
                                     //       |
                                     //       V
HBITMAP hBmp   = ::CreateCompatibleBitmap(hMemDC, width, height);
...
// TIP: Try to use the same DC to create
//      the Bitmap which you used to create the memory DC.

Remember the part about how The memory DC is initialized with a mono-chromatic 1x1 pixel bitmap by default?!

As for the remarks of member Raymond Chen I believe he is also right, but since you said that your actual code is different this is the only thing I can see as a mistake.

Hopefully this helps.

Best regards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top