Search code examples
c++mfcstatusbar

Converting a CBitmap to HICON and using it on a status bar


I found this link that shows you how to convert a CBitmap into a HICON:

HICON HICONFromCBitmap(CBitmap& bitmap)
{
   BITMAP bmp;
   bitmap.GetBitmap(&bmp);

   HBITMAP hbmMask = ::CreateCompatibleBitmap(::GetDC(NULL), 
                                              bmp.bmWidth, bmp.bmHeight);

   ICONINFO ii = {0};
   ii.fIcon    = TRUE;
   ii.hbmColor = bitmap;
   ii.hbmMask  = hbmMask;

   HICON hIcon = ::CreateIconIndirect(&ii);
   ::DeleteObject(hbmMask);

   return hIcon;
}

So I have tried this in my application:

HICON hIcon = HICONFromCBitmap(m_mapMenuBitmap[5]);
VERIFY(hIcon);
m_StatusBar.GetStatusBarCtrl().SetIcon(paneProgressOrZoomFactor, hIcon);

It works:

Status Bar

Does hIcon need to be alive for the duration of my window? And do I have to free it?

For your clarification, my m_mapMeniBitmaps is a map of CBitmap objects and they do remain alive.


Solution

  • Does hIcon need to be alive for the duration of my window? And do I have to free it?

    Yes and yes! From the documentation for CreateIconIndirect (bolding mine):

    When you are finished using the icon, destroy it using the DestroyIcon function.

    My m_mapMenuBitmaps is a map of CBitmap objects and they do remain alive.

    You can free those CBitmap objects once you've created the icon(s) but, as you correctly note, they remain 'alive', so you should always 'kill' them when you no longer need them. From the same M/S document:

    The system copies the bitmaps in the ICONINFO structure before creating the icon or cursor.
    ...
    The application must continue to manage the original bitmaps and delete them when they are no longer necessary.