Home Articles Books Downloads FAQs Tips

Q: Display the same icons that Windows uses.

Answer: This FAQ could also be called how to display the same icons that Windows uses. The icons for drives, folders, documents, explorer, the network neighborhood, and so on, are all located in a system ImageList. Most of the icons reside in SHELL32.DLL, but others are appended to the system ImageList by the operating system. To display the same icons that the system displays, all you need to do is get the handle of the system ImageList.

Step 1: Add a #include statement for the file SHELLAPI.H

    #include <vcl\vcl.h>
    #pragma hdrstop

    #include "MAINFORM.h"
    #include <win32\shellapi.h>

Step 2: The API SHGetFileInfo function allows you to retrieve the system ImageList. Add an Image control and an ImageList control to the main form of your program. Don't add any icons to the ImageList. Add this code to your form's constructor to bind the ImageList to the system ImageList.

  // Argument description:
  // 1st arg -> ""           : filename, not needed
  // 2nd arg -> 0            : file attributes flag, not needed because the last
  //                           arg does not contain SHGFI_USEFILEATTRIBUTES
  // 3rd arg -> &info        : this argument is always the address of a
  //                           SHFILEINFO structure.
  // 4th arg -> sizeof(info) : this arg is always sizeof(SHFILEINFO)
  // 5th arg -> flags        : (see notes below)
  SHFILEINFO info;
  DWORD ImageHandle = SHGetFileInfo("",
                                    0,
                                    &info,
                                    sizeof(info),
                                    SHGFI_ICON |
                                    SHGFI_SHELLICONSIZE |
                                    SHGFI_SYSICONINDEX);

  // if the function succeeds, assign the returned handle to the TImageList
  // member. Note that the TImageList control appears to adjust its height
  // and width when you assign its handle. Also note that ShareImages is true to
  // prevent TImageList from attempting to deleting the underlying system
  // imagelist (although the shell blocks this attempt).
  if (ImageHandle != 0)
  {
    ImageList1->Handle = ImageHandle;
    ImageList1->ShareImages = true;
  }

  // If everything has gone according to plan,
  // display the first icon in an Image control
  if(ImageList1->Count > 0)
    ImageList1->GetIcon(0,Image1->Picture->Icon);  // 0 is the icon's index

Notes: The return value from SHGetFileInfo takes on a different meaning based on the last argument to the function. If the last arg contains either the SHGFI_ICON or the SHGFI_SYSICONINDEX flags, then the return value is the handle to the system imagelist.

Here is a description of th flags for the last argument to SHGetFileInfo:

      SHGFI_ICON :         specifies that the result will be the handle to the
                           system imagelist (somewhat redundant). Also affects
                           how the info structure will be filled in.

      SHGFI_SHELLICONSIZE: tells the function to use the shell icon size instead
                           of the system icon size. Recall that there are four
                           classes of icons in win95 (system large, system
                           small, shell large and shell small). This parameter
                           isn't "necessary" but it makes sense to use the shell
                           sizes since the imagelist will represent shell items.

      SHGFI_SMALLICON:     tells the function to return the handle of the small
                           icon imagelist. Their are two system image lists; one
                           for small icons and one for large icons. The two are
                           not quite identical. The large icons are sometimes
                           fancier. The large icons for the floppy drives
                           contain little pictures of disks, but the small icons
                           don't. To my knowledge, both the small and large
                           imagelists contain the same number of icons. Omit
                           this parameter to use large icons instead of small
                           icons.

      SHGFI_SYSICONINDEX:  specifies that the return value is the handle of the
                           system image list (redundant with SHGFI_ICON). Of
                           greater importance, it also specifies that info.iIcon
                           will contain the proper image list index for the file
                           name. This is used later on for the drives.


Copyright © 1997-2000 by Harold Howe.
All rights reserved.