简体   繁体   中英

Scaling a CBitmap - what am I doing wrong?

I've written the following code, which attempts to take a 32x32 bitmap (loaded through MFC's Resource system) and turn it into a 16x16 bitmap, so they can be used as the big and small CImageLists for a CListCtrl. However, when I open the CListCtrl, all the icons are black (in both small and large view). Before I started playing with resizing, everything worked perfectly in Large View.

What am I doing wrong?

 // Create the CImageLists
 if (!m_imageListL.Create(32,32,ILC_COLOR24, 1, 1))
 {
  throw std::exception("Failed to create CImageList");
 }
 if (!m_imageListS.Create(16,16,ILC_COLOR24, 1, 1))
 {
  throw std::exception("Failed to create CImageList");
 }

 // Fill the CImageLists with items loaded from ResourceIDs
 int i = 0;
 for (std::vector<UINT>::iterator it = vec.begin(); it != vec.end(); it++, i++)
 {
  CBitmap* bmpBig = new CBitmap();
  bmpBig->LoadBitmap(*it);
  CDC bigDC;
  bigDC.CreateCompatibleDC(m_itemList.GetDC());
  bigDC.SelectObject(bmpBig);

  CBitmap* bmpSmall = new CBitmap();
  bmpSmall->CreateBitmap(16, 16, 1, 24, 0);
  CDC smallDC;
  smallDC.CreateCompatibleDC(&bigDC);
  smallDC.SelectObject(bmpSmall);
  smallDC.StretchBlt(0, 0, 32, 32, &bigDC, 0, 0, 16, 16, SRCCOPY);

  m_imageListL.Add(bmpBig, RGB(0,0,0));
  m_imageListS.Add(bmpSmall, RGB(0,0,0));
 }

 m_itemList.SetImageList(&m_imageListS, LVSIL_SMALL);
 m_itemList.SetImageList(&m_imageListL, LVSIL_NORMAL);

Need to create a compatibleDC for bigDC. ie obtain the DC of the current window first and do something like

bigDC.CreateCompatibleDC(&myWindowHdc);

You are adding a reference to the local CBitmap object into the list. The reference would no longer be valid once you are out of loop. Try creating the object on heap.

Try using CreateCompatibleBitmap() rather than CreateBitmap() - the two bitmaps need to be the same for BitBlt/StretchBlt to work.

Also, www.gdiwatch.com can be useful when debugging issues like this. It looks abandoned but the version for download can be made to work with VS2008, too.

Make sure you deselect the CBitmaps after using them:

// Select the objects
CBitmap* ret1 = bigDC.SelectObject(bmpBig);
CBitmap* ret2 = smallDC.SelectObject(bmpSmall);
...
// Do the painting
...
// Deselect
bigDC.SelectObject(ret1);
smallDC.SelectObject(ret2);

您需要进行更改:

bmpSmall->CreateBitmap(16, 16, 1, 32, 0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM