Marco
Marco

Reputation: 1

Working with HBitmaps

I'm trying to save some HBITMAPs into an array, and display them at a later time. Creating a HBITMAP from a DC works, but when I try to display a saved HBITMAP I seem to get the wrong one. This leads me to think that I haven't really understood how HTBIMAPs are stored in memory. I was assuming that the data type HBITMAP is essentially a pointer to the object in memory and that that's all I need, but maybe there is more to it?

Here's a sample code:

HBITMAP aBitMaps[NUM_BITMAPS];
int iNumBitMaps;

void SaveScreen(CDC *dc)
{
  if (iNumBitMaps>0)
  {
    if (iNumBitMaps>=NUM_BITMAPS)
    {
      iNumBitMaps=NUM_BITMAPS-1;
      DeleteObject(aBitMaps[iNumBitMaps]);
    }
    for (int i=iNumBitMaps;i>0;i--)
    {
      aBitMaps[i] = aBitMaps[i-1];
    }
  }
  iNumBitMaps++;
  aBitMaps[0] = CreateCompatibleBitmap(dc->m_hDC, 800, 800);
  HDC hdcMem = CreateCompatibleDC(dc->m_hDC);
  SelectObject(hdcMem, aBitMaps[0]);
  BitBlt(hdcMem, 0, 0, 800, 800, dc->m_hDC, 0, 0, SRCCOPY);
  ReleaseDC(hdcMem);
}

void RestoreScreen(CDC *dc, int i)
{
  if (i>=NUM_BITMAPS) i = NUM_BITMAPS-1;
  if (i<0) i = 0;
  HDC hdcMem = CreateCompatibleDC(dc->m_hDC);
  SelectObject(hdcMem, aBitMaps[i]);
  BitBlt(dc->m_hDC, 0, 0, 800, 800, hdcMem, 0, 0, SRCCOPY);
  ReleaseDC(hdcMem);
}

So, the idea is essentially to push the HBITMAP pointers to an array, and at a later time display any of the stored images by selecting it into a memory DC and then copying it to the actual DC. What's wrong with this?

I'm using VC++, Visual Studio 2010, no MFC.

EDIT:

I did some more tests. For debugging, I tried to display all stored bitmaps (shifted in position) by adding the following for loop to SaveScreen

...
BitBlt(hdcMem, 0, 0, 800, 800, dc->m_hDC, 0, 0, SRCCOPY);
for (int j=0; j<iNumBitMaps;j++)
{
  SelectObject(hdcMem, aBitMaps[j]);
  BitBlt(dc->m_hDC, 20*(j+1), 100*(j+1), 800+20*(j+1), 800+100*(j+1), hdcMem, 0, 0, SRCCOPY);
}
ReleaseDC(hdcMem);

This then does display iNumBitMaps times the image, but it's always the same image (namely the one I stored in aBitMaps[0]). I did verify in the debugger, that aBitMaps contains all different pointers. So, somehow I think I don't correctly load the bitmaps into the memory DC.

Upvotes: 0

Views: 157

Answers (1)

Marco
Marco

Reputation: 1

I figured it out. In my code above there were two mistakes (of which I'm aware of). First, the memory DC must be deleted after use, so ReleaseDC must be replaced by DeleteDC.

Second, one must know that an object that is selected into a DC cannot be selected into another DC. Hence it is important that after operating on an object in the memory DC, the object must be unloaded by selecting the DC's previous object. The correct contruction is thus essentially

HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, aBitMaps[0]);
BitBlt(...);
HBITMAP hbmNew = (HBITMAP)SelectObject(hdcMem, hbmOld);

where now hbmNew points to the same object as aBitMaps[0].

Upvotes: 0

Related Questions