Visual Basic Icon Routines
SHGetFileInfo: Extracting Associated Icons for a StatusBar
Posted:   Friday December 27, 1996
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB4-32, Windows 95
OS restrictions:   None
Author:   VBnet - Randy Birch, Don Bradner


SHGetFileInfo: Extracting a 16x16 Associated Icon
SHGetFileInfo: Extracting 16x16 and 32x32 Associated Icons
Working code from the article SHGetFileInfo: Extracting 16x16 and 32x32 Associated Icons.

vbnsiconxtract16status.gif (3333 bytes)VB code to retrieve the small (16x16) and large (32x32) pixel system icon associated with a given application using SHGetFileInfo, assign the small icon to an imagelist control, and use the imagelist icon to display in a status bar panel. If the application does not have an icon associated with it, the default Windows unknown icon will be returned.

Note that extraction techniques using ExtractIcon only return the 32x32 icon.

ImageList_Draw routine adapted from code provided by Don Bradner.
 BAS Module Code
There are no changes to the code in the Bas module.

 Form Code
To the code and form created in SHGetFileInfo: Extracting 16x16 and 32x32 Associated Icons, make the following changes:
  • On the form, add 3 additional command buttons (Command3, Command4 & Command5). Add a status bar control, aligned bottom, and with the property Style = 0 - Multiple Panels. Add at least 1 panel, and set its minimum width to about 2000.
  • Add an imagelist control (ImageList1), and set its image size to 16x16 by right clicking the control and selecting properties. Don't load any image into the control, and don't assign it to the status bar.
  • Copy and paste the picturebox pixSmall, selecting No to the control array question. Name the new picturebox pixNone, and again, assure the scalemode is 1 - Twips.

Set the properties of pixNone to:

  • Appearance = 0 (flat)
  • AutoRedraw = True
  • AutoReSize = False
    BackColor = &H8000000F&
  • Borderstyle = 0 (none)
  • Height = 240 twips
  • Width = 240 twips

This should result in both the ScaleHeight and ScaleWidth of the picturebox being 240 twips (or 16 pixels). It is important that the pixNone BackColor be set to the hex value shown (the hex colour value of 3D controls).

Add the following code to the form:

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
'In the form file's general declarations 
'section, add the following variables:

  'add 2 variables to preventing re-loading of the
  'icons if the same file is chosen, or the apply
  'button is pressed with the same iconset    
   Dim CurrentIconSetFlag As Single
   Dim FileSetLoadedFlag As Single

  'add a variable to hold a keyname for
  'our required 'place holder'.   
   Dim Placeholder As String

'In the form's Form_Load sub, add: 
  'set a "blank" dummy icon variable name   
   Placeholder = "dummy" 

'In the form file's cmdLoad sub, comment 
'out the two SavePicture lines (they're not 
'required), then add the following new code
'to the end of the cmdLoad sub, just before
'the first Exit Sub statement:
  'To prevent reloading of the imagelist
  'with the icon, set the FileSetLoadedFlag
  'to some numeric variable that will have
  'changed the next time this sub is run. 
  'The value returned by the Now statement
  'works perfectly for this!   
   FileSetLoadedFlag! = Now
  'Assure no imagelist error is generated
  'by disabling the buttons if an invalid 
  'handle exists in hImgSmall.    
   Command3.Enabled = hImgSmall <> 0
   Command4.Enabled = hImgSmall <> 0
   Command5.Enabled = hImgSmall <> 0 

'Add the following new code to the form:

Private Sub Command3_Click()

   Dim pnlX As Panel
   Dim imgX As ListImage
  'If the icons in the imagelist are 
  'the same icons currently loaded, 
  'then everything's ready to go, 
  'and there's nothing here that needs
  'doing except to redisplay the loaded
  'icon. The flags set here and in the 
  'cmdLoad routine determine which code
  'to execute.   

   Select Case FileSetLoadedFlag! = CurrentIconSetFlag!
      Case True   
        'they match, so just display the icon   
         Set StatusBar1.Panels(1).Picture = _
         StatusBar1.Panels(1).Text = Info1.Caption

      Case Else   
        'Clear the image list and add code to load a
        'blank icon to image position 1 (the Placeholder).  

        'Because the user can change the 
        'colours of 3D objects via the screen
        'properties, it is unsafe to assume 
        'that gray will always be the statusbar
        'colour. This code assures that whatever
        'the user's colour, the "blank" pix will
        'always equal the background colour of
        'the 3D objects (unless, of course, the
        'user changes the 3D colour during 
        'program execution).

        'delete all icons from the imagelist,
        'add a "blank" icon to the first item
        'in the imagelist, and assign the "Placeholder"
        'picture to the first ListImage   
         pixNone.Picture = pixNone.Image
         Set imgX = ImageList1.ListImages.Add(_
                    1, _
                    Placeholder, _
        'realize the pixSmall image and
        'add it to the imagelist   
         pixSmall.Picture = pixSmall.Image
         Set imgX = ImageList1.ListImages.Add(, , _
        'set the new imagelist picture to the statusbar   
         Set StatusBar1.Panels(1).Picture = _
         StatusBar1.Panels(1).Text = Info1.Caption
        'save the current Icon to the flag   
        CurrentIconSetFlag! = FileSetLoadedFlag!

    End Select

End Sub 

Private Sub Command4_Click()
  'assign the "Placeholder" ListImage 
  'to the first Statusbar panel.   
   Set StatusBar1.Panels(1).Picture = _

End Sub 

Private Sub Command5_Click()
  'delete the icon from 
  'the statusbar control   
   Set StatusBar1.Panels(1).Picture = Nothing

End Sub
Save and run the project. Once a file has been selected and the small icon valid, the Apply, Hide and Remove buttons will become enabled. By clicking the Assign button, the icon in pixNone - an 'empty icon' the same colour as a 3D object - will be placed into the imagelist as the first icon (imagelist image #0). The icon in pixSmall will be placed into the imagelist as the second icon (imagelist image #1), and the imagelist is then bound to the status bar. The icon (image 1) from the imagelist will be displayed in the status bar panel, along with the data from the Info1 label.

Selecting the Hide button simply swaps the empty image in pixNone (imagelist position 0) for the previously displayed icon.

Pressing the Remove button sets the status bar's image property to Nothing, deleting the icon, and moving the text back against the left edge.

If the Assign button was again pressed without selecting another file, the currently-stored icon in the imagelist would be reset (through the use of the flags); if a different file was selected, the time value of the flag FileSetLoadedFlag would be different from the value in the flag CurrentIconSetFlag, causing the apply code to execute the Else portion of the Select Case statement, unbinding the imagelist, clearing the current contents, reassigning the placeholder icon to position 0, and the newly selected icon to position 1.

Don't confuse the ImageList_Draw API with the VB ImageList control. The former is the API used to draw an image to a control; the latter is the control itself. It is not necessary to have an imagelist control in a project to utilize the ImageList_Draw API, as its destination can be any control with an exposed hDC.


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter