C++/VB - CreateBitmap() & CreateCompatibleDC()

Asked By Bello
21-May-08 09:12 AM
The CreateBitmap definition in MSDN says that :

calling the SelectObject() function. However, the bitmap can only be selected
into a device context if the bitmap and the DC have the same format".


The CreateCompatibleDC definition in MSDB say that :

display surface is exactly one monochrome pixel wide and one monochrome pixel
high".


If these two statements are correct, it would be impossible to select a
bitmap different than a monochrome bitmap into a memory DC, which clearly is
not the case, since that's the usual procedure to expand a memory DC, before
painting on it.


I've done some tests, selecting bitmaps obtained with CreateBitmap() and
with different color depths (bpp). The 1 and 32 bpp bitmaps are selected
normally by the function SelectObject(). For the other cases (4, 8, 16, 24)
the function fails.


Given the above contradictions, I have some conceptual questions :

. Which of the first two statements above is true ?

. Why does (4) occurs ?

. Given that a memory DC returned by CreateCompatibleDC(hDC) is different
from hDC, what is the meaning of  the term Compatible in the function's name
? At least one would expect this funtion to return a memory DC with the same
color organization as hDC.

. A memory DC, does it really have a default bitmap, or is it just a
placeholder ?

Microsoft Visual C++ .NET   69586-335-0000007-18101
CreateCompatibleDC
(1)
SelectObject
(1)
CreateBitmap
(1)
HDC
(1)
Belloc
(1)
D870F7621531
(1)
Depths
(1)
Bitmap
(1)
  Mark Salsbery [MVP] replied...
29-Jun-08 04:41 PM
Both :)




Compatible in pixel format.  The default monochrome 1x1 bitmap is a
placeholder.
A common mistake is to create a bitmap compatible with the memory DC
instead of the original DC, thus creating a monochrome bitmap.

I'm not sure why there's no error when a 1bpp bitmap is selected into a
32bpp DC...
probably the way it's always been.

Mark

--
Mark Salsbery
Microsoft MVP - Visual C++
Create New Account
help
transparent color set to white and the rest is in black. Thanks VC MFC Discussions CreateCompatibleDC (1) DPtoLP (1) CreateCompatibleBitmap (1) DrawTransparentBitmap (1) SetBkColor (1) GetMapMode (1) SetMapMode (1) DeleteDC (1 bmSave; HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld; HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave; POINT ptSize; hdcTemp = CreateCompatibleDC(hdc); SelectObject(hdcTemp, hBitmap); / / Select the bitmap GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); ptSize.x = bm.bmWidth 1); / / Convert from device / / to logical points / / Create some DCs to hold temporary data. hdcBack = CreateCompatibleDC(hdc); hdcObject = CreateCompatibleDC(hdc); hdcMem = CreateCompatibleDC(hdc); hdcSave = CreateCompatibleDC(hdc); / / Create a bitmap for each DC. DCs are required for a number of / / GDI functions. / / Monochrome DC bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); / / Monochrome DC bmAndObject = CreateBitmap(ptSize.x, ptSize.y
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { CBitmap cBitmap; cBitmap.CreateCompatibleBitmap(pdc, m_width, m_height); CreateBitmap(cBitmap); CBitmap* pSelectedBitmap = pdc-> SelectObject(&cBitmap); m_pic.CreateFromBitmap(&cBitmap, 0, 1); m_pic.Render(pdc, rcBounds, rcBounds); } void MyControl::CreateBitmap(CBitmap& io_rBitmap) { HRESULT hr; BYTE * pBytes = NULL; / / Get a pointer to the elements of the m_pImageArray is a safearray / / Access the BITMAPINFOHEADER section BITMAPINFOHEADER * pbmih = (BITMAPINFOHEADER *)(pBytes + sizeof(BITMAPFILEHEADER)); io_rBitmap.CreateBitmap(m_width, m_height, pbmih-> biPlanes, pbmih- SafeArrayUnaccessData( m_pImageArray ); pBytes = NULL; } Any ideas??? Thanks Dominique VC MFC Discussions CBitmap (1) PBytes (1) BITMAPINFOHEADER (1) CPictureholder (1) DcMemory (1) M_pImageArray (1) CreateBitmap (1) CreateCompatibleBitmap (1) I personally have not loaded a bitmap from raw data, nor have but the colors are wrong. . . Here is what I do: / / From OnDraw() CDC dcMemory; dcMemory.CreateCompatibleDC(pdc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dcMemory, m_width, m_height); CreateBitmap(pdc-> GetSafeHdc(), bmp); if(!(HBITMAP)bmp) { / / Select the bitmap into the in-memory DC CBitmap* pOldBitmap = dcMemory.SelectObject(&bmp); / / Find a centerpoint for the bitmap in the client area CRect rect; GetClientRect(&rect
DC. I'm doing something like this: / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / rawBmp = CBitmap::FromHandle(myDeviceHBITMAP); rawBmp-> GetBitmap(&rawBitmap); rawDC.CreateCompatibleDC(NULL); rawDC.SelectObject(rawBmp); processedDc.CreateCompatibleDC(NULL); processedBmp-> CreateCompatibleBitmap(&processedDc, rawBitmap.bmWidth, rawBitmap.bmHeight); processedDc.SelectObject(processedBmp); processedDc.BitBlt(0, 0, rawBitmap.bmWidth, rawBitmap.bmHeight, &rawDC, 0, 0, SRCCOPY); / / And now bitmap that I got in processedBmp is also mono. if I create a Bitmap using CreateBitmap and passing 24 in nBitcount, then I can't select it into the processedDC. I Discussions Support (1) ProcessedBmp (1) ProcessedDc (1) DC (1) RawBitmap (1) Microsoft (1) DIB (1) CreateCompatibleDC (1) Hi Pedro, As a quick information, using DIB section should give you more control problem was on creating a 24bit bitmap that was compatible with a DC created with CreateCompatibleDC. When I tried the DIB solution it worked as expected. I first created a DIB
pIcon), pSize, _IconDATA, &dSize); / / L returns TRUE here CDC dcMEM, pDC; / / = NULL; int y = dcMEM.CreateCompatibleDC (&pDC); CBitmap _ICONBmp; dcMEM.SelectObject (&_ICONBmp); L = _ICONBmp.CreateBitmap (25, 25, 1, 1, NULL); int val = _ICONBmp.SetBitmapBits (dSize, (LPVOID) _IconDATA); pDC.BitBlt (0 but then, the images are blank. Help Plzzzzzzzz. . . . . VC MFC Discussions ICONBmp.SetBitmapBits (1) ICONBmp.CreateBitmap (1) DcMEM.CreateCompatibleDC (1) DcMEM.SelectObject (1) IconDATA (1) ICONBmp (1) PIcon.CreateBitmap (1) PIcon.GetLength (1) Assuming _IconDATA contains monochrome, 25x25, WORD aligned pixel data after the Base64Decode, this should be all you need (no DC necessary): CBitmap _ICONBmp; L = _ICONBmp.CreateBitmap (25, 25, 1, 1, _IconDATA); if (L) { / / succeeded } Mark - - Mark Salsbery Microsoft MVP - Visual C