Search code examples
bitmapmfcscopeiconsimagelist

CImageList scope vs CImageList::ExtractIcon() returned HICON scope


I have used CImageList for converting bitmap to HICON and I am wondering is HICON returned by CImageList::ExtractIcon() still valid after CImage destruction? Lets assume I have code like this:

HICON Icon;

        {
            CImageList ImageList;
            ...
            Icon = ImageList.ExtractIcon(0);
        }

Icon;//<----------- Is this still valid?

In GUI I can see that it shows correct bitmap as icon and everythig works as expected but when I checked in debugger the returned HICON by ::GetIconInfo it always returns false even when the CImageList still exists. Any ideas? Is the HICON in code above correct after closing braces or not?


Solution

  • It is absolutely safe to do it like you do. The CImageList::ExtractIcon() method calls ImageList_ExtractIcon() macro which does call the ImageList_GetIcon() function to create an icon or cursor based on an image and mask in an image list. Don't forget to call DestroyIcon() when you no longer need this icon.

    The other way of doing it is the following:

    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;
    }