# Getting HBITMAP from a DC

This topic is 4003 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I thought this'd be a trivial matter, but for some reason Microsoft seems to have made this overly complicated. This is my code:
	BITMAPINFO bi;
ZeroMemory(&bi, sizeof(bi));

HBITMAP rbmp = (HBITMAP)SelectObject(rdc, (HGDIOBJ)NULL);

// 100 is an arbitrary value - I don't know the precise
// measurements of rbmp; I just want to get the size/format
GetDIBits(rdc, rbmp, 0, 100, NULL, &bi, DIB_RGB_COLORS);


I also tried replacing HBITMAP rbmp = (HBITMAP)SelectObject(rdc, (HGDIOBJ)NULL); with HBITMAP new_bmp = CreateCompatibleBitmap(rdc, 1, 1); HBITMAP rbmp = (HBITMAP)SelectObject(rdc, (HGDIOBJ)new_bmp); SelectObject() always returns NULL and bi remains unchanged. Is there a simpler way of accomplishing this? A way that works, maybe? If there is, I certainly cannot find it on MSDN. PS - I tried calling this code after and between calls to BeginPaint() / EndPaint().

##### Share on other sites
If SelectObject() returns NULL then an error occurred. Are you sure that rdc is a valid DC?

##### Share on other sites
From the MSDN for SelectObject:
Quote:
 The SelectObject function selects an object into the specified device context (DC). The new object replaces the previous object of the same type.

What type of object is NULL? Is a BITMAP, a BRUSH, a PEN, a FONT or anything else that can be selected into a DC? To get the current contents of a portion of the thing a DC is drawing on you need to do the following:
1. Create a new bitmap2. Create a new DC3. Select new bitmap into new DC4. BitBlt from DC of interest into new DC

But if all you want is the dimensions and/or the format of the thing the DC is drawing to then you need to use GetDeviceCaps (link to MSDN information).

Skizz

##### Share on other sites
Colin - yeah, as far as I can tell, the DC is valid and GetLastError() returns no error.

Skizz - erm, call GetDeviceCaps() with which arguments? As far as I can tell, the following seems to be the most reliable way:

	HWND hwnd = WindowFromDC(rdc);	RECT rc;	GetClientRect(hwnd, &rc);	int wd = rc.right - rc.left;	int ht = rc.bottom - rc.top;		HDC tDC = CreateCompatibleDC(rdc);	HBITMAP tBMP = CreateCompatibleBitmap(rdc, width, height);	SelectObject(tDC, tBMP);	BitBlt(tDC, 0, 0, width, height, rdc, x, y, SRCCOPY);	DeleteDC(tDC);	DeleteObject(tBMP);

##### Share on other sites
GetCurrentObject is what you want:
HBITMAP hBmp = GetCurrentObject(rdc, OBJ_BITMAP);

##### Share on other sites
Thanks! Unfortunately in this case, thinking about it a little, it's not really of too much use unless there's a function equivalent of GetDIBits() that'd allow me to get a subsection of rdc into a buffer (eg a width x height patch at coordinates x, y).

But it is kind of criminal that this function isn't more actively cross-referenced in MSDN as I've felt need for it before and done some quite extensive Googling and still not found it.

##### Share on other sites
Quote:
 Original post by irreversible equivalent of GetDIBits() that'd allow me to get a subsection of rdc into a buffer (eg a width x height patch at coordinates x, y).

See my previous post, i.e. BitBlt.

Skizz

##### Share on other sites
What I meant is that GetCurrentObject() would be useful if I could get a subsection of the HBITMAP returned by it as a regular data buffer without having to allocate an intermediate HDC/HBITMAP, which would mean I could skip the blitting bit altogether.

Currently I can just as well just allocate the new HDC/HBITMAP, blit the section I need directly from the other DC and then retrieve the data buffer with GetDIBits(), making the GetCurrentObject() call obsolete.

##### Share on other sites
Quote:
 Original post by irreversibleWhat I meant is that GetCurrentObject() would be useful if I could get a subsection of the HBITMAP returned by it as a regular data buffer without having to allocate an intermediate HDC/HBITMAP, which would mean I could skip the blitting bit altogether.Currently I can just as well just allocate the new HDC/HBITMAP, blit the section I need directly from the other DC and then retrieve the data buffer with GetDIBits(), making the GetCurrentObject() call obsolete.
There's nothing like this built into the Win32 API, it's a pretty specialised thing you want to do, and you can't get direct access to the bits, because they're in a device dependant format. BitBlt()int to a scratch surface seems the best choice here.

1. 1
Rutin
37
2. 2
3. 3
4. 4
5. 5

• 12
• 10
• 13
• 104
• 11
• ### Forum Statistics

• Total Topics
632983
• Total Posts
3009697
• ### Who's Online (See full list)

There are no registered users currently online

×