Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Retrieving shell icons

0.00/5 (No votes)
19 Jun 2002 1  
Get shell icons, even if they're customized

Sample Image - shellicon.png

Introduction

Some time ago I had to use a folder icon in one of my projects. Because I like consistent UI's, I decided to dispose the icon that is used by the Windows Explorer. As some of you may know, this icon is contained in the shell32.dll at position 3 for a closed folder, and 4 for an open folder. You can extract such icons by using ExtractIconEx. So this has been easy to implement. So far, so good.

Unfortunately, a few days later a co-worker annotated, that my code did not respect his customized shell icons. After some research, I discovered how you can change the icons used by Windows to present folders as well as some other items.

Basics

You just have to add a value to the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons. Its name is the index of the shell icon you want to change, and the value data contains the filename of the icon and its index, separated by ','. E.g. following registry value changes the icon of open folders to that icon in C:\OpenFolder.ico (for .ico files you have to set the index to 0):

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons]
"4"="C:\OpenFolder.ico,0"

Sample Image - shellicon_example.png

The Code

As a solution, I have implemented the following method:

HICON ExtractShellIcon (int nIndex,
                              bool bLargeIcons /*= false*/)
{
    HICON hIcon = NULL;

    // Shell icons can be customized by the registry:

    // HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\

    // Explorer\Shell Icons

    // "<ShellIconIndex>" = "<Filename>,<IconIndex>"

    // E.g.

    // "3" = "c:\MyFolderIcon.ico,1"

    HKEY hkeyShellIcons;
    if (RegOpenKeyEx (
        HKEY_LOCAL_MACHINE,
        _T("SOFTWARE\\Microsoft\\Windows\\
        CurrentVersion\\Explorer\\Shell Icons"),
        0,
        KEY_READ,
        &hkeyShellIcons) == ERROR_SUCCESS)
    {
        TCHAR szBuffer[ MAX_PATH * sizeof TCHAR];
        DWORD dwSize = MAX_PATH * sizeof TCHAR;

        TCHAR szIndex[6] = {0};
        _stprintf (szIndex, _T("%d"), nIndex);
        if (RegQueryValueEx (hkeyShellIcons, szIndex,
                            NULL, NULL, (LPBYTE)szBuffer,
                             &dwSize) == ERROR_SUCCESS)
        {
#ifdef _AFXDLL
            CString strFileName, strIndex;
            VERIFY (AfxExtractSubString (strFileName,
                                    szBuffer, 0, _T(',')));
            VERIFY (AfxExtractSubString (strIndex,
                                    szBuffer, 1, _T(',')));
            ExtractIconEx (
                strFileName,
                atoi(strIndex),
                bLargeIcons ? &hIcon : NULL,
                bLargeIcons ? NULL : &hIcon,
                1);
#else
            std::vector<std::tstring> ls;
            tokenize (std::back_inserter(ls),
                              szBuffer, _T(","));
            ExtractIconEx (
                ls[0].c_str(),
                atoi(ls[1].c_str()),
                bLargeIcons ? &hIcon : NULL,
                bLargeIcons ? NULL : &hIcon,
                1);
#endif
        }
        
        RegCloseKey( hkeyShellIcons );
    }

    // Not customized? Then get the original icon from

    // shell23.dll

    if (!hIcon)
        ExtractIconEx (
            _T("SHELL32.DLL"),
            nIndex, bLargeIcons ? &hIcon : NULL,
            bLargeIcons ? NULL : &hIcon,
            1);

    return hIcon;
}

Annotation

You may have noticed the tokenize function called in the non-MFC version. It's just a simple tokenizer included in the source file.

Usage

To use my method, you can just call ExtractShellIcon. The first parameter specifies, which icon you want to retrieve. I've compiled a list of icons contained in shell32.dll below. The second parameter just says whether you want a small or a large icon.

Table of available shell icons

0SI_UNKNOWNUnknown File Type
1SI_DEF_DOCUMENTDefault document
2SI_DEF_APPLICATIONDefault application
3SI_FOLDER_CLOSEDClosed folder
4SI_FOLDER_OPENOpen folder
5SI_FLOPPY_5145 1/4 floppy
6SI_FLOPPY_353 1/2 floppy
7SI_REMOVABLERemovable drive
8SI_HDDHard disk drive
9SI_NETWORKDRIVENetwork drive
10SI_NETWORKDRIVE_DISCONNECTEDnetwork drive offline
11SI_CDROMCD drive
12SI_RAMDISKRAM disk
13SI_NETWORKEntire network
14?
15SI_MYCOMPUTERMy Computer
16SI_PRINTMANAGERPrinter Manager
17SI_NETWORK_NEIGHBORHOODNetwork Neighborhood
18SI_NETWORK_WORKGROUPNetwork Workgroup
19SI_STARTMENU_PROGRAMSStart Menu Programs
20SI_STARTMENU_DOCUMENTSStart Menu Documents
21SI_STARTMENU_SETTINGSStart Menu Settings
22SI_STARTMENU_FINDStart Menu Find
23SI_STARTMENU_HELPStart Menu Help
24SI_STARTMENU_RUNStart Menu Run
25SI_STARTMENU_SUSPENDStart Menu Suspend
26SI_STARTMENU_DOCKINGStart Menu Docking
27SI_STARTMENU_SHUTDOWNStart Menu Shutdown
28SI_SHARESharing overlay (hand)
29SI_SHORTCUTShortcut overlay (small arrow)
30SI_PRINTER_DEFAULTDefault printer overlay (small tick)
31SI_RECYCLEBIN_EMPTYRecycle bin empty
32SI_RECYCLEBIN_FULLRecycle bin full
33SI_DUNDial-up Network Folder
34SI_DESKTOPDesktop
35SI_CONTROLPANELControl Panel
36SI_PROGRAMGROUPSProgram Group
37SI_PRINTERPrinter
38SI_FONTFont Folder
39SI_TASKBARTaskbar
40SI_AUDIO_CDAudio CD
41?
42?
43SI_FAVORITESIE favorites
44SI_LOGOFFStart Menu Logoff
45?
46?
47SI_LOCKLock
48SI_HIBERNATEHibernate

You might have noticed that they're a several gaps in this table. Unfortunately, I do not know currently what these icons are used for.

The demo application

The demo provided with this article simply takes the constants depicted in the table above and inserts the associated icons into two listview ctrl's, one with large icons, the other with small ones.

History

09-Jun-2002

  • Initial release/upload

10-Jun-2002

  • Added VC6 workspace and project to demo application source
  • The zipped demo executable is now VC6 build, so the MFC7 libraries are not needed anymore (not all of you might have installed VS.NET yet)
  • Some clean-up in ShellIcons.h

Epilogue

If someone knows the purpose of the missing icons, please feel free to write an appropriate comment, so I can update this article.

Revision History

20 Jun 2002 - Initial Revision
20 Jun 2002 - Reformatted Code and Text

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here