Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Extracting Single Images from a CImageList object

0.00/5 (No votes)
31 Jul 2003 1  
This will show you how extract an individual CBitmap from a CImageList object

Introduction

While working on a project of mine using skinned buttons, I ran into problems when I tried to use a CImageList as the source of the state images.

The CImageList does not provide any direct access to the separate images within the list. I searched, and searched and searched and search... well you get the idea... Anyway after banging my head against the keyboard for 4 days, I finally found a solution.

The GetImageFromList function

The result of my headaches is the GetImageFromList function. If you are familiar with using CDCs then you are probably already calling this an obvious solution - but then, why are you reading this article in the first place?

Here is the function I managed to come up with (with the help of sites like this):

It takes 3 parameters, and returns nothing.

  • lstImages: A pointer to the CImageList object containing all of the images.
  • nImage: The index of the image that is going to be extracted.
  • destBitmap: A pointer to the CBitmap object that is going to contain the extracted image.

The function makes a copy of the image list, and moves the requested image to the front of that list.

It then draws the requested image into the destination bitmap.

void CMyWindowClass::GetImageFromList(CImageList *lstImages, 
                             int nImage, CBitmap* destBitmap)
{    
     //First we want to create a temporary image list we can manipulate

     CImageList tmpList;
     tmpList.Create(lstImages);
     
    //Then swap the requested image to the first spot in the list 

    tmpList.Copy( 0, nImage, ILCF_SWAP );
    
    //Now we need to get som information about the image 

    IMAGEINFO lastImage;
    tmpList.GetImageInfo(0,&lastImage);
    
    //Heres where it gets fun

    //Create a Compatible Device Context using 

    //the valid DC of your calling window

    CDC dcMem; dcMem.CreateCompatibleDC (GetWindowDC()); 
    
    //This rect simply stored the size of the image we need

    CRect rect (lastImage.rcImage);
    
    //Using the bitmap passed in, Create a bitmap 

    //compatible with the window DC

    //We also know that the bitmap needs to be a certain size.

    destBitmap->CreateCompatibleBitmap (this->GetWindowDC(), 
                                      rect.Width (), rect.Height ());
    
    //Select the new destination bitmap into the DC we created above

    CBitmap* pBmpOld = dcMem.SelectObject (destBitmap);
    
    //This call apparently "draws" the bitmap from the list, 

    //onto the new destination bitmap

    tmpList.DrawIndirect (&dcMem, 0, CPoint (0, 0), 
           CSize (rect.Width (), rect.Height ()), CPoint (0, 0));
    
    
    //cleanup by reselecting the old bitmap object into the DC

    dcMem.SelectObject (pBmpOld);
}

It looks big, but remove the comments and you have a mere 12 lines of code.

Conclusion

I hope that this article can save at least one person from going through what I went through to find the answer.

Good Luck, and Happy Coding!!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here