An image list is a collection of images of the same size, each of which can be referred to by its index. Image lists are used to efficiently manage large sets of icons or bitmaps. All images in an image list are contained in a single, wide bitmap in screen device format. An image list can also include a monochrome bitmap that contains masks used to draw images transparently (icon style).
The Microsoft® Win32® application programming interface (API) provides image list functions that enable you to create and destroy image lists, add and remove images, replace and merge images, draw images, and drag images.
To use the image list functions, include the common control header file in
your source code files and link with the common control export library. In
addition, before calling any image list function, use the
There are two types of image lists: nonmasked and masked. A nonmasked image list consists of a color bitmap that contains one or more images. A masked image list consists of two bitmaps of equal size. The first is a color bitmap that contains the images, and the second is a monochrome bitmap that contains a series of masks—one for each image in the first bitmap.
When a nonmasked image is drawn, it is simply copied into the target device context; that is, it is drawn over the existing background color of the device context. When a masked image is drawn, the bits of the image are combined with the bits of the mask, typically producing transparent areas in the bitmap where the background color of the target device context shows through. There are several drawing styles that you can specify when drawing a masked image. For example, you can specify that the image be dithered to indicate a selected object.
You create an image list by calling the
In ImageList_Create, you specify the initial number of images that will be in an image list as well as the number of images by which the list can grow. So if you attempt to add more images than you initially specified, the image list automatically grows to accommodate the new images.
If ImageList_Create succeeds, it returns a handle to the HIMAGELIST
type. You use this handle in other image list functions to access the image list
and manage the images. You can add and remove images, copy images from one image
list to another, and merge images from two different image lists. When you no
longer need an image list, you can destroy it by specifying its handle in a call
to the
The following example creates a masked image list and uses the
// AddIconsToImageList - creates a masked image list and adds some
// icons to it.
// Returns the handle to the new image list.
// hinst - handle to the application instance.
//
// Global variables and constants
// g_nBird and g_nTree - indexes of the images.
// cx_icon and cy_icon - width and height of the icon.
// num_icons - number of icons to add to the image list.
extern int g_nBird, g_nTree;
#define CX_ICON 32
#define CY_ICON 32
#define NUM_ICONS 3
HIMAGELIST AddIconsToImageList(HINSTANCE hinst)
{
HIMAGELIST himlIcons; // handle to new image list
HICON hicon; // handle to icon
// Ensure that the common control DLL is loaded.
InitCommonControls();
// Create a masked image list large enough to hold the icons.
himlIcons = ImageList_Create(CX_ICON, CY_ICON, ILC_MASK, NUM_ICONS, 0);
// Load the icon resources, and add the icons to the image list.
hicon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_BIRD));
g_nBird = ImageList_AddIcon(himlIcons, hicon);
hicon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_TREE));
g_nTree = ImageList_AddIcon(himlIcons, hicon);
return himlIcons;
}
You can add bitmapped images, icons, or cursors to an image list. You add
bitmapped images by specifying the handles to two bitmaps in a call to the
The
The ImageList_AddIcon function adds an icon or cursor to an image list. If the image list is masked, ImageList_AddIcon adds the mask provided with the icon or cursor to the mask bitmap. If the image list is nonmasked, the mask for the icon or cursor is not used when drawing the image.
You can create an icon based on an image and mask in an image list by using
the
ImageList_Add, ImageList_AddMasked, and ImageList_AddIcon assign an index to each image as it is added to an image list. The indexes are zero-based; that is, the first image in the list has an index of zero, the next has an index of one, and so on. After adding a single image, the functions return the index of the image. When more than one image is added at a time, the functions return the index of the first image.
The
The
The
To draw an image, you use the
When you specify the ILD_TRANSPARENT style, ImageList_Draw or ImageList_DrawEx uses a two-step process to draw a masked image. First, it performs a logical AND operation on the bits of the image and the bits of the mask. Then it performs a logical XOR operation on the results of the first operation and the background bits of the destination device context. This process creates transparent areas in the resulting image; that is, each white bit in the mask causes the corresponding bit in the resulting image to be transparent.
Before drawing a masked image on a solid color background, you should use the
You can set the background color for a masked image list at any time so that
it draws correctly on any solid background. Setting the background color to
CLR_NONE causes images to be drawn transparently by default. To retrieve the
background color of an image list, use the
The ILD_BLEND25 and ILD_BLEND50 styles dither the image with the system highlight color. These styles are useful if you use a masked image to represent an object that the user can select. For example, you can use the ILD_BLEND50 style to draw the image when the user selects it.
A nonmasked image is copied to the destination device context using the SRCCOPY raster operation. The colors in the image appear the same regardless of the background color of the device context. The drawing styles specified in ImageList_Draw or ImageList_DrawEx also have no effect on the appearance of a nonmasked image.
The following function draws an image and saves the client coordinates of the image's bounding rectangle. A subsequent function uses the bounding rectangle to determine whether the user has clicked the image.
// DrawTheImage - draws an image transparently and saves
// the bounding rectangle of the drawn image.
// Returns TRUE if successful, or FALSE otherwise.
// hwnd - handle to the window in which to draw the image.
// himl - handle to the image list that contains the image.
// cx and cy - client coordinates for the upper-left corner of the image.
//
// Global variables and constants
// g_nImage - index of the image to draw.
// g_rcImage - bounding rectangle of the image.
// CX_IMAGE and CY_IMAGE - width and height of the image.
extern int g_nImage;
extern RECT g_rcImage;
#define CX_IMAGE 32
#define CY_IMAGE 32
BOOL DrawTheImage(HWND hwnd, HIMAGELIST himl, int cx, int cy)
{
HDC hdc;
if ((hdc = GetDC(hwnd)) == NULL)
return FALSE;
if (!ImageList_Draw(himl, g_nImage, hdc, cx, cy, ILD_TRANSPARENT))
return FALSE;
ReleaseDC(hwnd, hdc);
SetRect(&g_rcImage, cx, cy, CX_IMAGE + cx, CY_IMAGE + cy);
return TRUE;
}
The Win32 API includes functions for dragging an image on the screen. The dragging functions move an image smoothly, in color, and without any flashing of the cursor. Both masked and unmasked images can be dragged.
The
The
ImageList_DragEnter locks all other updates to the given window during
the drag operation. If you need to do any drawing during a drag operation, such
as highlighting the target of the operation, you can temporarily hide the
dragged image by using the
The
When an application calls ImageList_BeginDrag, the system creates a
temporary, internal image list and then copies the specified drag image to the
internal list. You can retrieve the handle to the temporary drag image list by
using the
The following function is intended to be called in response to a mouse
button-down message, such as
// StartDragging - begins dragging a bitmap.
// Returns TRUE if successful, or FALSE otherwise.
// hwnd - handle to the window in which the bitmap is dragged.
// ptCur - coordinates of the cursor.
// himl - handle to the image list.
//
// Global variables
// g_rcImage - bounding rectangle of the image to drag.
// g_nImage - index of the image.
// g_ptHotSpot - location of the image's hot spot.
// g_cxBorder and g_cyBorder - width and height of border.
// g_cyCaption and g_cyMenu - height of title bar and menu bar.
extern RECT g_rcImage;
extern int g_nImage;
extern POINT g_ptHotSpot;
BOOL StartDragging(HWND hwnd, POINT ptCur, HIMAGELIST himl)
{
// Return if the cursor is not in the bounding rectangle of
// the image.
if (!PtInRect(&g_rcImage, ptCur))
return FALSE;
// Capture the mouse input.
SetCapture(hwnd);
// Erase the image from the client area.
InvalidateRect(hwnd, &g_rcImage, TRUE);
UpdateWindow(hwnd);
// Calculate the location of the hot spot, and save it.
g_ptHotSpot.x = ptCur.x - g_rcImage.left;
g_ptHotSpot.y = ptCur.y - g_rcImage.top;
// Begin the drag operation.
if (!ImageList_BeginDrag(himl, g_nImage,
g_ptHotSpot.x, g_ptHotSpot.y))
return FALSE;
// Set the initial location of the image, and make it visible.
// Because the ImageList_DragEnter function expects coordinates to
// be relative to the upper-left corner of the given window, the
// width of the border, title bar, and menu bar need to be taken
// into account.
ImageList_DragEnter(hwnd, ptCur.x + g_cxBorder,
ptCur.y + g_cyBorder + g_cyCaption + g_cyMenu);
g_fDragging = TRUE;
return TRUE;
}
The following function, which drags the image to a new location, is intended
to be called in response to the
// MoveTheImage - drags an image to the specified coordinates.
// Returns TRUE if successful, or FALSE otherwise.
// ptCur - new coordinates for the image.
BOOL MoveTheImage(POINT ptCur)
{
if (!ImageList_DragMove(ptCur.x, ptCur.y))
return FALSE;
return TRUE;
}
The following function ends the drag operation and draws the image in its final location. It also releases the mouse capture.
// StopDragging - ends a drag operation and draws the image
// at its final location.
// Returns TRUE if successful, or FALSE otherwise.
// hwnd - handle to the window in which the bitmap is dragged.
// himl - handle to the image list.
// ptCur - coordinates of the cursor.
//
// Global variable
// g_ptHotSpot - location of the image's hot spot.
extern POINT g_ptHotSpot;
BOOL StopDragging(HWND hwnd, HIMAGELIST himl, POINT ptCur)
{
ImageList_EndDrag();
ImageList_DragLeave(hwnd)
g_fDragging = FALSE;
DrawTheImage(hwnd, himl, ptCur.x - g_ptHotSpot.x,
ptCur.y - g_ptHotSpot.y);
ReleaseCapture();
return TRUE;
}
There are a number of functions that retrieve information from an image list.
The
Every image list includes a list of indexes to use as overlays. An overlay is an image that is drawn transparently over another image. Any image currently in the image list can be used as an overlay. You can specify up to four overlays per image list. This limit has been expanded to 15 in version 4.71.
You add the index of an image to the list of overlays by using the
You specify an overlay when drawing an image with the ImageList_Draw
or ImageList_DrawEx function. The overlay is specified by performing a
logical OR operation between the desired drawing flags and the result of the
ImageList_SetOverlayImage(himl, 0, 3); ImageList_Draw(himl, 1, hdc, 0, 0, ILD_MASK | INDEXTOOVERLAYMASK(3));
This will draw image 1 and then overlay that image with image 0. Because 3 is the overlay index that you specified in the ImageList_SetOverlayImage call, 3 is placed in the INDEXTOOVERLAYMASK macro.
The following features were added to the image list by Microsoft Internet Explorer.
| Copying Images | Copy or swap images within an image list using the |
| Duplicating Image Lists | Take an existing image list and duplicate all of its parameters and
contents into a new image list using the |
| Dynamic Resizing of Image Lists | Modify the number of images in an image list on the fly using the |
| Extended Drawing of Images | You now have more control over the drawing of images with the |