views:

86

answers:

4

I'm writing an unmanaged Win32 C++ function that gets a handle to a bitmap, and I need to draw on it.

My problem is that to draw I need to get a device context, but when I do GetDC (NULL), it gives me a device context for the WINDOW! The parameter for GetDC () is a window handle (HWND), but I don't have a window; just a bitmap handle.

How can I draw on this bitmap? Thanks!

+1  A: 

CreateCompatibleDC() and SelectObject() your bitmap into it.

However, not every bitmap can be selected into any DC. You might have to play with mapping mode and other options of memory DCs.

Pavel Radzivilovsky
But CreateCompatibleDC () takes an HDC as a parameter. If I had an HDC, I wouldn't need to create one! (Is there something I'm overlooking?)
`CreateCompatibleDC` can take NULL as a parameter and will create a memory DC compatible with the application screen. You can then either SelectObject your bitmap in it, as Pavel said, you you can CreateCompatibleBitmap() and then BitBlt() your original one into the DC.
Franci Penov
I'm trying to draw on an 8bpp bitmap. This is of course not compatible with the application screen. Is it possible to draw on such a bitmap?
Yes. There's other API to create a memory DC. I think it's called CreateDC. You may wish to review all DC API in win32.
Pavel Radzivilovsky
Hmm... CreateDC requires parameters I don't have, like device, driver, port, and device mode. Is there any other way?
I honestly don't know. What you want is create a memory DC compatible with a given bitmap.
Pavel Radzivilovsky
@alankdkd: it seems like you're just looking at function signatures and not actually reading the documentation...
Cogwheel - Matthew Orlando
A: 

In addition to Pavel's answer, the "compatible with the screen" always bugged me too, but, since CreateCompatibleDC(NULL) is universally used for that purpose, I assume it is correct.

I think that the "compatible" thing is related just to DDB (the DC is set up to write on the correct DDB type for the current screen), but does not affect read/writes on DIBs.

So, to be safe, always use DIBs and not DDBs if you need to work on bitmaps that doesn't just have to go temporarily onscreen, nowadays the difference in performance is negligible. See here for more info about DIBs and DDBs.

Matteo Italia
A: 

The basic win32 paradigm for drawing on a bitmap is that you select the bitmap onto a device context, after which, all drawing operations on that device context are stored in the bitmap. You then use one of the various 'blit' operations (e.g. StretchBlt) to transfer this to a display surface, which is just the device context of a window client area.

Others have provided better detail, this is just the high-level view.

JustJeff
Thanks for the reply, but I need to store 8bpp images, which aren't compatible with the display. This is the source (no pun intended) of the problem.
@alankdkd: well, nothing says you have to display a bitmap, but you can still use GDI operations to draw on them this way. You might want to look at CreateDIBitmap() or CreateDIBSection() if you need to get unusual pixel organizations.
JustJeff
A: 

Well, this is a bit outside the box.. I guess.. But I do know that Graphics can return a HDC, and Graphics take a Bitmap as an argument to its ctor . A Bitmap in turn can be created from a HBITMAP and a HPALETTE. The only problem here is that I do not know if the HPALETTE argument can be NULL.

Graphics* g;
Bitmap* bitmap;
HBITMAP _bitmap;   // <- this one is yours

bitmap = Bitmap::FromHBITMAP(_bitmap, NULL);
g = new Graphics(bitmap);

HDC hdc = g->GetHDC();

// when done, call g->ReleaseHDC(hdc);

However, I would urge you to receive the HDC as an argument to your function as well.. I do not think that anyone will have a BITMAP and NOT have the DC to it.
If you're having these issues with finding a HDC to a HBITMAP, so will everyone else.

Default
Thanks for the suggestion, but this has to be in unmanaged Win32, which (unfortunately) doesn't have the Graphics class.