An image list is like a roll of bitmap images.
Time Saver: Image lists can also be used outside these new controls, and they provide an easy way to store a series of bitmaps, because you must handle only a single image-list object instead of separate objects for each bitmap.
If you want to display bitmaps in tree views or list views, you must use an image list. If your program needs to manage several different bitmapped images, a single image list is easier to use than a series of bitmaps. Accessing and displaying multiple images from an image list is much easier than handling multiple CBitmap objects. Windows Explorer has a much richer user interface than the older File Manager used in Windows 3.1. Much of this richness is achieved through the use of image lists, which offer an easy way to store and manage bitmaps.
In addition, image lists offer two features that are difficult to duplicate with regular bitmaps:
A transparent image is difficult to achieve using a normal bitmap. In the simplest cases, about twice as many lines of code are required to draw a bitmap transparently as are required to draw it as an opaque image against a drawing surface. Using an image list, drawing a transparent bitmap is almost effortless, requiring little more than parameters that are set correctly.
New Term: An overlaid image is created by combining two images to form a single, combined image.
An overlaid image is useful when showing special attributes for items represented by images stored in an image list. For example, when a shared directory is shown in the Explorer, a server "hand" is superimposed over the directory's folder. This is an overlaid image.
Image lists often are used to provide item images for the CListCtrl class that is covered in Section 18, and the CTreeCtrl class that is covered in Section 19. However, you can also use an image list as a collection of bitmaps, which you will do in this chapter. Using image lists in this way helps show off the different things you can do with image lists before they are used with the common controls.
As an example of using image lists, create an SDI project named ImageList. This project uses an image list to display a series of bitmaps in the program's client area.
The bitmaps used in the ImageList example are all the same size.
Create the three bitmaps, and name them as shown in Table 17.1.
| ID | Description |
| IDB_CROSS | Cross mark |
| IDB_CHECK | Check mark |
| IDB_BANG | Exclamation point |
Storing a bitmap image in an image list consists of three steps:
2. Create a new image index in the image list that contains a copy of the bitmap.
3. Delete the bitmap object.
BOOL CImageListView::AddBitmapToImageList( UINT nResourceID )
{
BOOL bReturn;
CBitmap bmp;
bReturn = bmp.LoadBitmap( nResourceID );
if( bReturn != FALSE )
{
int nReturn = m_imageList.Add( &bmp, RGB(255,255,255) );
bmp.DeleteObject();
}
return bReturn;
} The AddBitmapToImageList function
is used because three bitmap resources are added to the image list. Adding
the bitmaps using a new member function reduces the amount of code you
must write and helps reduce the chance of errors, because every bitmap
is loaded using the same function.
The CImageList::Add member function is used to add an image to the image list. The version of Add used in Listing 17.1 takes two parameters:
Time Saver: The background color is used when drawing transparent images using masked bitmaps. If you aren't using a masked image list, the COLORREF value is ignored.
After adding the member function to the ImageListView.cpp file, add the source code from Listing 17.2 to the CImageListView class, found in the file ImageListView.h. Add the source code in the class implementation section, which is marked by the // Implementation comment. After the comment, there is a protected: label inserted by AppWizard for user- supplied variables and functions.
protected: BOOL AddBitmapToImageList( UINT nResourceID );CImageList m_imageList; The actual work of creating the image list is done when the view is constructed. The image list can be built at any time; however, it is costly to create an image list in terms of computing power. Creating the image list in the constructor lets you build it once, rather than each time it is used. Add the source code from Listing 17.3 to the constructor for CImageViewList.
CImageListView::CImageListView()
{
m_imageList.Create( 32, 32, TRUE, 3, 1 );
AddBitmapToImageList( IDB_CROSS );
AddBitmapToImageList( IDB_CHECK );
AddBitmapToImageList( IDB_BANG );
} The image list is created using one of the
CImageList::Create functions. This version of Create
is useful when an image list is used as a bitmap collection; I use other
versions of Create in the following chapters. This version of
Create has five parameters:
void CImageListView::OnDraw(CDC* pDC)
{
CPoint ptImage( 0, 0 );
for( int nImage = 0; nImage < 3; nImage++ )
{
m_imageList.Draw( pDC, nImage, ptImage, ILD_NORMAL );
ptImage.x += 50;
}
} The Draw member function has four
parameters:
Using ILD_NORMAL to display the contents of the image list.
There are eight different types of drawing operations:
Image list items mask drawn using ILD_MASK.
The individual image bitmaps stored in an image list can also be extracted as icons using the ExtractIcon member function:
HICON hicon = m_imageList.ExtractIcon( nImage );The only parameter needed for ExtractIcon is the image index. You can then use the icon extracted just like any icon handle. Icons were discussed in Section 14, "Icons and Cursors."
void CImageListView::OnDraw(CDC* pDC)
{
m_imageList.SetBkColor( RGB(0,255,0) );
CPoint ptImage( 0, 0 );
for( int nImage = 0; nImage < 3; nImage++ )
{
m_imageList.Draw( pDC, nImage, ptImage, ILD_NORMAL);
ptImage.x += 50;
}
} If you compile and run the ImageList project,
the background of the images will be set to green. By changing the RGB
COLORREF value passed to the CImageList::SetBkColor function,
you can match any background color.
m_imageList.SetOverlayImage( 0, 1 );The SetOverlayImage function takes two parameters: the image index used as the overlay, and the overlay index used to identify the overlay.
Just a Minute: Just to make things more interesting, unlike almost every other index used in Windows, the overlay index starts at one instead of zero.
To use an overlaid image, the CImageList::Draw function is used as in previous examples, except that the ILD_OVERLAYMASK flag is used. The INDEXTOOVERLAYMASK macro is combined with the ILD_OVERLAYMASK flag to specify the overlay image index to be combined with the base image. Listing 17.6 is a new version of OnDraw that displays an overlaid image using an image list.
void CImageListView::OnDraw(CDC* pDC)
{
m_imageList.SetBkColor( CLR_NONE );
CPoint ptOverlay( 50, 80 );
m_imageList.SetOverlayImage( 0, 1 );
m_imageList.Draw( pDC,
2,
ptOverlay,
INDEXTOOVERLAYMASK(1) );
}
A Use the bitmap image mask instead of the color mask. One version of the CImageList::Add member function allows you to add two bitmaps to the image list:
nReturn = m_imageList.Add( &bmpImage, &bmpMask );
Q How can I store an icon image in an image list?
A A version of the CImageList::Add member function accepts an icon handle:
nReturn = m_imageList.Add( hIcon );
2. Why would you want to have a "grow-by" parameter greater than one when creating an image list?
3. What is a transparent image?
4. The color mask is passed as a parameter when adding a bitmap image to the image list. What is the color mask used for?
5. What drawing style is used to draw the mask for a transparent image?
6. What are the drawing styles that begin with ILD_BLEND used for?
7. After a bitmap has been added to the image list, are you required to destroy the bitmap object or will the image list destroy it for you?
8. What is an overlapped image?
2. Experiment by using the Draw function with the ILD_BLENDxx values to see how the system highlight color is combined with different types of images.
Download Sample Programs - ImageList.zip
|
|
|
|