|
Icon and Image List Drawing
![[Icon Drawing Samples]](/images/iconproc.gif)
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:
    Private Declare Function DrawState Lib "user32" Alias "DrawStateA" _
        (ByVal hdc As Long, _
        ByVal hBrush As Long, _
        ByVal lpDrawStateProc As Long, _
        ByVal lParam As Long, _
        ByVal wParam As Long, _
        ByVal X As Long, _
        ByVal Y As Long, _
        ByVal cX As Long, _
        ByVal cY As Long, _
        ByVal fuFlags As Long) As Long
    '/* Image type */
    Private Const DST_COMPLEX = &H0
    Private Const DST_TEXT = &H1
    Private Const DST_PREFIXTEXT = &H2
    Private Const DST_ICON = &H3
    Private Const DST_BITMAP = &H4
    ' /* State type */
    Private Const DSS_NORMAL = &H0
    Private Const DSS_UNION = &H10 ' Dither
    Private Const DSS_DISABLED = &H20
    Private Const DSS_MONO = &H80 ' Draw in colour of brush specified in hBrush
    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:
    Private Declare Function ImageList_GetIcon Lib "COMCTL32.DLL" ( _
        ByVal himl As Long, _ ' Image List handle
        ByVal i As Long, _ ' Zero-based index of the image to extract
        ByVal diFlags As Long _ ' Draw flags
    ) 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:
    Dim hIcon As Long
    Dim hIml As Long
        ' Get the image list handle (note we draw an item first to ensure it
        ' has been initialised, otherwise the code can error):
        ilsIcons.ListImages(1).Draw 0, 0, 0
        himl = ilsIcons.hImageList
        ' Get an icon from the Image List:
        hIcon = ImageList_GetIcon(himl, 3, 0)
        ' Draw it disabled at 32x32
        DrawState Me.hdc, 0, 0, hIcon, 0, 32, 32, 16, 16, DST_ICON Or DSS_DISABLED)
        ' Clear up the icon:
        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:
    Private Declare Function DrawStateString Lib "user32" Alias "DrawStateA" _
        (ByVal hdc As Long, _
        ByVal hBrush As Long, _
        ByVal lpDrawStateProc As Long, _
        ByVal lpString As String, _
        ByVal cbStringLen As Long, _
        ByVal X As Long, _
        ByVal Y As Long, _
        ByVal cX As Long, _
        ByVal cY As Long, _
        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.
Back to top
Back to Source Code
|
  |