The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
3 Code Libraries Source Code &nbsp

NOTE: this code has been superceded by the version at the new site.


Icon and Image List Drawing

[Icon Drawing Samples]

Download the Icon and Image List drawing project files (14kb)

This sample demonstrates how simple it is to draw disabled, colourised, selected and dithered (NT only) icons from Image Lists. The VB Image List provides a method to draw an item selected, but doesn't give you very much flexibility from there.

The secret of quickly drawing disabled, colourised or dithered icons is the GDI DrawState function. This function appears in VB's API viewer, but the parameters are named incorrectly and none of the constants you need to get it to work are provided!

Here is the correct declaration of DrawState and the flag constants which go with it:

&nbsp &nbsp Private Declare Function DrawState Lib "user32" Alias "DrawStateA" _
&nbsp &nbsp &nbsp &nbsp (ByVal hdc As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal hBrush As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal lpDrawStateProc As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal lParam As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal wParam As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal X As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal Y As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal cX As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal cY As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal fuFlags As Long) As Long

&nbsp &nbsp '/* Image type */
&nbsp &nbsp Private Const DST_COMPLEX = &H0
&nbsp &nbsp Private Const DST_TEXT = &H1
&nbsp &nbsp Private Const DST_PREFIXTEXT = &H2
&nbsp &nbsp Private Const DST_ICON = &H3
&nbsp &nbsp Private Const DST_BITMAP = &H4

&nbsp &nbsp ' /* State type */
&nbsp &nbsp Private Const DSS_NORMAL = &H0
&nbsp &nbsp Private Const DSS_UNION = &H10 ' Dither
&nbsp &nbsp Private Const DSS_DISABLED = &H20
&nbsp &nbsp Private Const DSS_MONO = &H80 ' Draw in colour of brush specified in hBrush
&nbsp &nbsp Private Const DSS_RIGHT = &H8000

With this function, you can draw text, icons or bitmaps in disabled, dithered or in a single colour with a single call. To draw an icon from an image list in its disabled state, you first need to extract a copy of the icon to work on in the DrawState function. This is achieved by the following Image List API function:

&nbsp &nbsp Private Declare Function ImageList_GetIcon Lib "COMCTL32.DLL" ( _
&nbsp &nbsp &nbsp &nbsp ByVal himl As Long, _ ' Image List handle
&nbsp &nbsp &nbsp &nbsp ByVal i As Long, _ ' Zero-based index of the image to extract
&nbsp &nbsp &nbsp &nbsp ByVal diFlags As Long _ ' Draw flags
&nbsp &nbsp ) As Long

This gives you a new icon created from the item in the image list. Since this is a new GDI object, you need to remember to delete it once you have finished with it with the DestroyIcon function.

Then, for example, to draw the a 16x16 icon on a form at position 32,32 pixels in its disabled state you do this:

&nbsp &nbsp Dim hIcon As Long
&nbsp &nbsp Dim hIml As Long

&nbsp &nbsp &nbsp &nbsp ' Get the image list handle (note we draw an item first to ensure it
&nbsp &nbsp &nbsp &nbsp ' has been initialised, otherwise the code can error):
&nbsp &nbsp &nbsp &nbsp ilsIcons.ListImages(1).Draw 0, 0, 0
&nbsp &nbsp &nbsp &nbsp himl = ilsIcons.hImageList

&nbsp &nbsp &nbsp &nbsp ' Get an icon from the Image List:
&nbsp &nbsp &nbsp &nbsp hIcon = ImageList_GetIcon(himl, 3, 0)
&nbsp &nbsp &nbsp &nbsp ' Draw it disabled at 32x32
&nbsp &nbsp &nbsp &nbsp DrawState Me.hdc, 0, 0, hIcon, 0, 32, 32, 16, 16, DST_ICON Or DSS_DISABLED)
&nbsp &nbsp &nbsp &nbsp ' Clear up the icon:
&nbsp &nbsp &nbsp &nbsp DestroyIcon hIcon

That's it. The function also works with strings and bitmaps. Note to use it with strings you have to create a new declaration so the lParam member of DrawState expects a string, and the wParam parameter takes the length of the string:

&nbsp &nbsp Private Declare Function DrawStateString Lib "user32" Alias "DrawStateA" _
&nbsp &nbsp &nbsp &nbsp (ByVal hdc As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal hBrush As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal lpDrawStateProc As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal lpString As String, _
&nbsp &nbsp &nbsp &nbsp ByVal cbStringLen As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal X As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal Y As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal cX As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal cY As Long, _
&nbsp &nbsp &nbsp &nbsp ByVal fuFlags As Long) As Long

The sample code also shows how to draw images in an image list directly using the Image List's API functions. This can be very useful when creating your own controls which interface to Image Lists, since in the control you can maintain the API handle to the ImageList (hImageList) rather than an object pointer to an ImageList. This gives you the flexibility to accept a full API level Image List as well as a VB ImageList control as the icon source. To see this in action in my controls, check out the Owner Draw Combo and List Box control and the Icon Menu control.

TopBack to top

Source Code - What We're About!Back to Source Code


AboutContributeSend FeedbackPrivacy

Copyright 1998-1999, Steve McMahon ( All Rights Reserved.
Last updated: 23 July 1998