ImageList Class

An image list is a object used to efficiently manage large sets of images. Either icons or bitmaps. In an image list, all images are the same size and are accessed by a zero-based index. The images are in screen device format. Optionally, each image in the list can have a matching monochrome bitmap that is used as a mask to draw the image transparently.

The .ImageList object acts as an interface to the underlying operating system Image List, which Microsoft calls a control. Although Microsoft calls the Image List a control and documents it with the other dialog controls, it is not a control in the same sense as button, edit, or list-view controls. It is not a window, all dialog controls are windows. It does not send or recieve window messages. Use the MSDN library documentation to get more information on exactly how Image Lists work.

When an image list is no longer needed, it can be released. This frees up the system resources used for the images and the image list. The programmer releases an image list by using the release() method. Once an image list is released it can no longer be used. It is an error to inovke any method on the released object, except for the isNull() method. The isNull() method can be invoked any time to test if an image list is valid or not. It should go without saying that a programmer should not release an image list that is in use.

Future versions of the .ImageList are intended to provide a complete interface to the underlying Image List control. At this time not all functionality is implemented.

Requires:

The ImageList class requires the class definition file ooDialog.cls:

::requires "ooDialog.cls"

Methods:

Instances of the ImageList class implement the methods listed in the following table:

Table 25-3. Image Instance Methods

Method......description page
create (Class method)id
new (Class method)new
addadd
addMaskedaddMasked
addIconaddIcon
addImagesaddImages
getCountgetCount
getImageSizegetImageSize
duplicateduplicate
removeremove
removeAllremoveAll
releaserelease
handlehandle
isNullisNull

new (Class method)

Currently it is not intended for the ooDialog programmer to instantiate an image list object directly using the new method. This may change in the future and will be documented at that time, if the intention changes. .ImageList objects are instantiated using the create() method.

create (Class method)

>>--create(--+--------+-+---------+-+--------+-+-------+-----------><
             +--size--+ +-,-flags-+ +-,count-+ +-,grow-+

Creates a new empty image list of the type specified.

Details

Raises syntax errors when incorrect arguments are detected.

Provides an interface to the ImageList_Create() API. Use the MSDN library documentation to get more information on the arguments to this method.

The ILC_MIRROR and ILC_PERITEMMIRROR flags require Common Control Library version 6.0 or later. If necessary use the comCtl32Version() method to determine the current version of the library.

Arguments:

The arguments are:

size

A .Size object that specifies the size of a single image in the image list. All images in an image list. have the same size.

If this argument is omitted the system default size for an icon is used. This size can vary depending on which version of Windows is running and whether the user has selected to use large icons or not. A typical size is 32 x 32 (in pixels.)

flags

The flags that specify the type of image list to create. The flags are one or more of the following symbols, but can include only one ILC_COLOR value. You can use .Image~toID() to get the correct numeric value for any of the following symbols. The or method of the .DlgUtil class can be used to combine the symbols.

ILC_MASKILC_COLOR24
ILC_COLORILC_COLOR32
ILC_COLORDDBILC_PALETTE
ILC_COLOR4ILC_MIRROR
ILC_COLOR8ILC_PERITEMMIRROR
ILC_COLOR16 

Return value:

A new, empty, image list is returned.

Note: It is theoretical possible for this method to fail and the returned image list to be null. However, in practice, it is virtually impossible to cause a failure. Using a size of 0 x 0 seems about the only way.

Example:
  
  -- We set the flags to create a 24 bit color, masked image list.
  flags = .DlgUtil~or(.Image~toID(ILC_COLOR24), .Image~toID(ILC_MASK))

  -- Create an empty .ImageList object:
  imageList = .ImageList~create(.Size~new(61, 46), flags, 10, 10);
  
  

add

>>--add(--image-+---------+--)-----------------------------><
                +-,-mask--+

Adds a bitmap image or images to the image list. The number of images is inferred from the width of the added bitmap. Optionally adds the mask for the bitmap(s). If the image list does not use a mask, the mask argument is ignored, even if it is present.

Internally the image list makes a copy of the bitmap. After the method returns, the original image can be released if it is not needed anymore.

Details

Raises syntax errors when incorrect arguments are detected or if the image list is null.

Provides an interface to the ImageList_Add() API. The MSDN library documentation can provide more information on this method.

Arguments:

The arguments are:

image

The .Image object that represents the image to add. This must be a bitmap image. The width of the image determines the number of images added. (Remember all images in a image list are the same size.)

mask

The mask(s) to use with the image(s). This must be a bitmap image.

Return value:

On success, the index of the first image added is returned, otherwise -1 is returned.

Example:

This example sets the image list for a list-view control. The images are loaded from psdemolv.bmp which is a bitmap 16 pixels high by 64 pixels wide, containing 4 individual images. Since the image list is created with a size of 16 x 16, when the add() method is used, the image list infers that the bitmap is 4 images.

      
      -- Set the images for the items in the list-view.
      image = .Image~getImage("bmp\psdemolv.bmp")
      imageList = .ImageList~create(.Size~new(16, 16), .Image~toID(ILC_COLOR8), 4, 0)
      if \image~isNull,  \imageList~isNull then do
         imageList~add(image)
         lc~setImageList(imageList, .Image~toID(LVSIL_SMALL))

         -- The image list makes a copy of the bitmap, so we can release it now.
         image~release
      end
      
      

addMasked

>>--addMasked(--image-,-cRef--)----------------------------------><

Adds a bitmap image, or images, to the image list. The COLOREF cRef is used to generate the mask.

Internally the image list makes a copy of the bitmap. After the method returns, the original image can be released if it is not needed anymore.

Details

Raises syntax errors when incorrect arguments are detected or if the image list is null.

Provides an interface to the ImageList_AddMasked() API. The MSDN library documentation can provide more information on this method.

Arguments:

The arguments are:

image

The .Image object that represents the image to add. This must be a bitmap image. The width of the image determines the number of images added. (Remember all images in a image list are the same size.)

cRef

The color to use to generate the mask. In the added image, each pixel that matches this color is changed to black, and the corresponding bit in the mask is set to 1.

Return value:

On success, the index of the first added image is returned, otherwise -1 is returned.

Example:

This example comes from a dialog with a Tab control. An image list is used to set an icon for each tab. Each icon is a colored letter on a white background. Using a white color to generate the mask causes the image to be drawn tranparently. The colored letter itself shows, and the rest of the image lets the underlying color show through.

      
      -- Add all the tabs, including the index into the image list for an icon for
      -- each tab.
      tc~AddFullSeq("Red", 0, ,"Green", 1, , "Moss", 2, , "Blue", 3, ,   -
                    "Purple", 4, ,  "Cyan", 5, , "Gray", 6)

      -- Create a COLORREF (pure white) and load our bitmap.
      cRef = .Image~colorRef(255, 255, 255)
      image = .Image~getImage("bmp\psdemoTab.bmp")

      -- Create our image list, as a masked image list.
      imageList = .ImageList~create(.Size~new(16, 16),                   -
                                    .DlgUtil~or(.Image~toID(ILC_COLOR24),  -
                                    .Image~toID(ILC_MASK)),                -
                                     10, 0)

      if \image~isNull,  \imageList~isNull then do
         imageList~addMasked(image, cRef)
         tc~setImageList(imageList)

         image~release
      end

      
      

addIcon

>>--addIcon(--image--)-----------------------------------------><

Adds an icon or cursor image to the image list. If the image list is masked, then both the image and mask bitmaps of the icon or cursor are copied. If it is not masked, then only the image bitmap is copied.

Internally the image list makes a copy of the bitmap. After the method returns, the original image can be released if it is not needed anymore.

Details

Raises syntax errors when incorrect arguments are detected or if the image list is null.

Provides an interface to the ImageList_AddIcon() API. The MSDN library documentation can provide more information on this method.

Arguments:

The only argument is:

image

The .Image object that represents the image to add. This must be an icon or cursor image.

y

yyy,

Return value:

This method returns the index of the added icon or cursor on success, otherwise -1 is returned.

Example:

Here the system icon images are loaded and then displayed in a list-view. Each icon will show in the list-view with the text for the icon being its numeric resource ID. Since the system icons are shared, the icon images are not released after they are added to the image list.

 
      ids = .array~new() ids[ 1] = .Image~toID(IDI_APPLICATION)
      ids[ 2] = .Image~toID(IDI_HAND) ids[ 3] = .Image~toID(IDI_QUESTION)
      ids[ 4] = .Image~toID(IDI_EXCLAMATION) ids[ 5] = .Image~toID(IDI_ASTERISK)
      ids[ 6] = .Image~toID(IDI_WINLOGO)

      flags = .DlgUtil~or(.Image~toID(ILC_COLOR8), .Image~toID(ILC_MASK))

      imageList = .ImageList~create(.Size~new(32, 32), flags, 20, 10)

      do i = 1 to ids~items
        image = .Image~getImage(ids[i], .Image~toID(IMAGE_ICON))
        imageList~addIcon(image)
      end

      list~setImageList(imageList, .Image~toID(LVSIL_NORMAL))

      do i = 1 to ids~items
        list~add(ids[i], i - 1)
      end
      
      

addImages

>>--addImages(--images--+---------+--)---------------------------><
                        +-,-cRef--+

Adds a number of images to the image list. The images are supplied in a non-sparse array and must all be of the same type.

The images are added to the image list in the same order as they exist in the array. If an error occurs in the middle of processing the images, the method returns at that point. This means that images prior to the error will exist in the image list, but no images in the array after the error will be placed in the image list. Which images were placed in the image list can be determined by the return value of this method.

Details

Raises syntax errors when incorrect arguments are detected or if the image list is null.

Arguments:

The arguments are:

images

An array of non-null .Image objects. The array must not be sparse, that is each index in the array must contain an .Image ojbect. The images can be bitmaps, icons, or cursors, but each image in the array must be the same type. (Remember that curors are icons, so that the array can contain a mixture of icons and cursors.) Bitmaps can not be mixed with icons or cursors.

cRef

A COLORREF that is used to generate the mask if the image list is a masked image list. See the addMasked() method for more details on this argument. This argument is ignored if the images are not bitmaps, or if the image list is not masked.

Return value:

This method returns the image list index of the last successfully added image, or -1 if no images were added.

Example:

This example creates an image list from a number icons and then displays them in a list-view control in a dialog.

      
      list  = self~getListControl(IDC_LV_IMAGES)

      files1 = .array~new()
      files1[ 1] = "Bee.ico"
      files1[ 2] = "Camera.ico"
      files1[ 3] = "Camera1.ico"
      files1[ 4] = "Default.ico"
      files1[ 5] = "Disabled.ico"
      files1[ 6] = "Hot.ico"
      files1[ 7] = "Lamp.ico"
      files1[ 8] = "Mountain.ico"
      files1[ 9] = "Normal.ico"
      files1[10] = "Penquin.ico"
      files1[11] = "Picture.ico"
      files1[12] = "Pushed.ico"
      files1[13] = "Question32.ico"
      files1[14] = "Search32.ico"
      files1[15] = "Skull.ico"
      files1[16] = "Stolen.ico"
      files1[17] = "Window.ico"

      size = .Size~new(32, 32)

      images = .Image~fromFiles(files1, .Image~toID(IMAGE_ICON), size)
      if images~items <> files1~items then do
        say 'Error loading images.'
        say '  System error:' .SystemErrorCode
        say '  Message:     ' SysGetErrorText(.SystemErrorCode)
        return
      end

      count = images~items
      flags = .DlgUtil~or(.Image~toID(ILC_COLOR24), .Image~toID(ILC_MASK))

      imageList = .ImageList~create(size, flags, 20, 10);

      lastAdded = imageList~addImages(images)
      if lastAdded <> (count - 1) then do
        -- Not all images were added.  We just ignore this and display
        -- in the list-view what was added.
      end

      -- Set the image list for the list-view's normal icons.
      list~setImageList(imageList, .Image~toID(LVSIL_NORMAL))

      -- Add an item to the list-view for each image.  The
      -- text for each item will be the icon file name and
      -- the icon will be the image we loaded.
      do i = 0 to lastAdded
        list~add(files1[i + 1], i)
      end
      
      

getCount

>>--getCount----------------------------------------------------><

Determines the number of images in the image list.

Details

Raises a syntax error if the image list is null.

Provides an interface to the ImageList_ImageCount() API. The MSDN library documentation can provide more information on this method.

Arguments:

There are no arguments.

Return value:

Returns the number of images currently in the image list.

Example:
    
    ::method displayImageListCount private
      use strict arg imageList
      say 'Image list:' imageList~handle 'has' imagelist~getCount 'images.'

      /*
        Possible output on a Windows 64-bit system:

        Image list: 0x00000000000ED420 has 17 images.
      */
    
    

getImageSize

>>--getImageSize----------------------------------------------------><

Determines the size of the images in the image list. All images in any single image list have the same size.

Details

Raises a syntax error if the image list is null.

Provides an interface to the ImageList_IconSize() API. The MSDN library documentation can provide more information on this method.

Arguments:

There are no arguments.

Return value:

The size of the images in the image list is returned in a .Size object.

Example:
    
    ::method displayImageListSize private
      use strict arg imageList
      s = imageList~getImageSize
      h = s~height 'pixels high'
      w = s~width 'pixels wide'
      say 'Image list:' imageList~handle 'contains images' h 'by' w

      /*
        Possible output on a Windows 64-bit system:

        Image list: 0x00000000000DCB20 contains images 32 pixels high by 32 pixels wide
      */

    
    

duplicate

>>--duplicate----------------------------------------------------><

Creates a duplicate image list. All information in the original image list is copied to the new image list. (Overlay images are not copied, but ooDialog does not have support for image list overlay images at this time.) The two image lists are independent. Adding, or removing, images from one image list has no effect on the other.

Details

Raises a syntax error if the image list is null.

Provides an interface to the ImageList_Duplcate() API. The MSDN library documentation can provide more information on this method.

Arguments:

There are no arguments.

Return value:

The return is a copy of the image list.

Example:

This fictious example is from a point-of-sale application for a restaurant. The customer is presented with a list-view of menu items, each list-view item has a colorful icon depicting the selection. The customers place their orders through the application and wait-people then bring them their meal when it is ready. The dinner menu has all the items that the lunch menu does, plus some more. The customer can choose whether to order from the lunch menu or the dinner menu, so the lunch menu image list has to remain unchanged.

      
      ::method getDinnerImageList private
        use strict arg lunchImageList

        dinnerList = lunchImageList~duplicate
        fileArray = self~getDinnerImageFiles
        dinnerList~addImages(fileArray)

      return dinnerList
      
      

remove

>>--remove(--index--)-----------------------------------------><

Removes the image at index from the image list. When the image is removed, all the indexes in the list are adjusted. I.e., if the image at index 2 is removed, the image at index 3 becomes index 2, the image at index 4 becomes index 3, etc..

Details

Raises syntax errors when incorrect arguments are detected or if the image list is null.

Provides an interface to the ImageList_Remove() API. The MSDN library documentation can provide more information on this method.

Arguments:

The single argument is:

index

The index of the image to remove.

Return value:

This method returns true on success, otherwise false.

Example:

This example comes from the fictious point-of-sale application for a restaurant. Sometimes the chef runs out of a menu item and the item is then removed from the list-view so that the customers can no longer order it. (Rigorous error checking is not done because the application was written by one of the waiters.)

      
      ::method removeFromMenu private
        use strict arg index

        menu = self~getListControl(IDC_LV_MENU)

        bigIcons = menu~getImageList(.Image~toID(LVSIL_NORMAL))
        bigIcons~remove(index)

        smallIcons = menu~getImageList(.Image~toID(LVSIL_SMALL))
        smallIcons~remove(index)

        stateIcons = menu~getImageList(.Image~toID(LVSIL_STATE))
        stateIcons~remove(index)

        menu~delete(index)

      return 0
      
      

removeAll

>>--removeAll----------------------------------------------------><

Removes all images from the image list.

Details

Raises a syntax error if the image list is null.

Provides an interface to the ImageList_RemoveAll() API. The MSDN library documentation can provide more information on this method.

Arguments:

There are no arguments to this method.

Return value:

The method returns true on success, false otherwise.

Example:

This example is a continuation of the fictious restaurant point-of-sale application. The waiter that wrote the application did not like to work past the normal closing time. The application has a feature that removes all the menu items as it gets near closing time to prevent customers from ordering something they do not have time to finish eating. (However, the waiter noticed that he often got huge tips from customers that had drinks after their meal.)

      
      ::method stopOrders private

        menu = self~getListControl(IDC_LV_MENU)

        bigIcons = menu~getImageList(.Image~toID(LVSIL_NORMAL))
        bigIcons~removeAll

        smallIcons = menu~getImageList(.Image~toID(LVSIL_SMALL))
        smallIcons~removeAll

        stateIcons = menu~getImageList(.Image~toID(LVSIL_STATE))
        stateIcons~removeAll

        menu~deleteAll

        self~addAfterDinnerDrinks(menu)

      return 0

      
      

release

>>--release----------------------------------------------------><

Releases the image list allowing the operating system to reclaim the resources used by the image list. Once the image list has been released, it can no longer be used.

Arguments:

There are no arguments to this method.

Return value:

This method always returns 0.

Example:

This example comes from a program that runs continuously. During the life-cycle of the application it displays and then closes a dialog that creates some image lists. The image lists are always different depending on the state of things. Each time the dialog closes, it releases the image lists it created to free up the operating system resources.

      
      ::method ok
        self~cleanUp
        return self~ok:super

      ::method cancel
        self~cleanUp
        return self~cancel:super

      ::method cleanUp private
        expose coolTempImages warningImages buidingStatusImages

        if coolTempImages \== .nil then coolTempImages~release
        if warningImages \== .nil then warningImages~release
        if buildingStatusImages \== .nil then buildStatusImages~release

      
      

handle

>>--handle----------------------------------------------------><

Returns the Windows system handle to the image list this object represents. It is an error to invoke this method if the image list is null, or after the image has been released.

At this time, the handle is only useful for display. In the ooDialog framework, methods that use image lists for arguments, use the .ImageList object, not the image list handle.

Arguments:

There is no argument to this method.

Return value:

The return is the image list handle.

Example:
    
    ::method displayImageList private
      use strict arg imageList
      say 'Currently using this image list:' imageList~handle

      /*
        Possible output on a Windows 64-bit system:

        Currently using this image list: 0x00000000000DCB20
      */
    
    

isNull

>>--isNull----------------------------------------------------><

Used to check if an image list is valid. This method can be invoked on any image list, even after it has been released. An image list will always be null after it has been released. It is conceivable that, if an error occurs during an image list creation, the returned image list might be null. However, this is extemely unlikely. Therefor, for all practical purposes, an image list will only be null after it has been released.

Arguments:

There are no arguments to this method.

Return value:

This method returns true if the image list is null, otherwise false.

Example:

This example comes from some test code.

      
      -- See if we can create an image list with no size.
      imageList = .ImageList~create(.Size~new(0, 0), .Image~toID(ILC_COLOR24),  20, 10)
      if imageList~isNull then do
        say 'Can not create a 0 x 0 image list.'
        return .false
      end

      return .true

      /*
        Output will be:

        Can not create a 0 x 0 image list.

      */