Extracting Single Images from a CImageList object






4.59/5 (21 votes)
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 theCImageList
object containing all of the images.nImage
: The index of the image that is going to be extracted.destBitmap
: A pointer to theCBitmap
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!!