BITMAPINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
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);
Getting HBITMAP from a DC
I thought this'd be a trivial matter, but for some reason Microsoft seems to have made this overly complicated.
This is my code:
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().
If SelectObject() returns NULL then an error occurred. Are you sure that rdc is a valid DC?
From the MSDN for SelectObject:
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:
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
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
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:
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);
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.
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.
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
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.
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.
Quote:Original post by irreversibleThere'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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement