Click here to Skip to main content
15,860,972 members
Articles / Desktop Programming / WTL
Article

Retrieving shell icons

Rate me:
Please Sign up or sign in to vote.
4.90/5 (13 votes)
19 Jun 2002CPOL3 min read 243.7K   5.9K   69   39
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Cloud Klabauter GmbH
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalfull icon list Pin
E|_muerte10-Feb-10 1:37
E|_muerte10-Feb-10 1:37 
Generaldear brother Pin
nenfa16-Nov-09 1:54
nenfa16-Nov-09 1:54 
QuestionHow can i get icon from IconCache.db? Pin
bingqitan28-Jun-07 21:03
bingqitan28-Jun-07 21:03 
QuestionRe: How can i get icon from IconCache.db? Pin
Thomas Freudenberg28-Jun-07 21:44
Thomas Freudenberg28-Jun-07 21:44 
Generalfinally! Pin
T1TAN9-Sep-05 15:05
T1TAN9-Sep-05 15:05 
GeneralRe: finally! Pin
Tiky Reol10-Nov-08 1:23
Tiky Reol10-Nov-08 1:23 
QuestionHow can i get other icons Pin
Mina W Alphonce12-Jul-05 0:17
Mina W Alphonce12-Jul-05 0:17 
GeneralCannot find the &quot;shell icons&quot; in my win2000's registry editor Pin
lauraliu17-Jun-04 22:33
lauraliu17-Jun-04 22:33 
GeneralRe: Cannot find the &quot;shell icons&quot; in my win2000's registry editor Pin
Thomas Freudenberg17-Jun-04 22:36
Thomas Freudenberg17-Jun-04 22:36 
GeneralRe: Cannot find the &quot;shell icons&quot; in my win2000's registry editor Pin
lauraliu17-Jun-04 22:57
lauraliu17-Jun-04 22:57 
General&quot;SHGetFileInfo&quot; with &quot;SHGFI_SYSICONINDEX&quot; flag doesn't work if called many times Pin
Tanmay Sathe25-Feb-04 12:52
Tanmay Sathe25-Feb-04 12:52 
Generalone small error Pin
bouli8-Jan-04 4:37
bouli8-Jan-04 4:37 
GeneralIE_FAVORITES Pin
alex.barylski14-Nov-03 17:18
alex.barylski14-Nov-03 17:18 
Is it safe to assume IE index will always be 43 (or was that 42 now?)

Just curious Smile | :)

The word of the day is legs, let's go back to my house and spread the word Poke tongue | ;-P
GeneralQuestion... Pin
andyj11525-Sep-03 4:23
andyj11525-Sep-03 4:23 
GeneralRe: Question... Pin
Thomas Freudenberg25-Sep-03 4:41
Thomas Freudenberg25-Sep-03 4:41 
GeneralMore Icons Pin
deane_kennedy4-Sep-03 16:47
deane_kennedy4-Sep-03 16:47 
GeneralRe: More Icons Pin
Thomas Freudenberg4-Sep-03 23:26
Thomas Freudenberg4-Sep-03 23:26 
GeneralRe: More Icons Pin
deane_kennedy5-Sep-03 15:22
deane_kennedy5-Sep-03 15:22 
GeneralDefault MyComputer Icon not loaded from Shell32.dll Pin
Hosed28-Jan-03 0:23
Hosed28-Jan-03 0:23 
GeneralSweet! Pin
Swinefeaster14-Jul-02 22:37
Swinefeaster14-Jul-02 22:37 
GeneralVery Useful Pin
Brian Delahunty20-Jun-02 5:12
Brian Delahunty20-Jun-02 5:12 
GeneralRe: Very Useful Pin
Thomas Freudenberg20-Jun-02 5:15
Thomas Freudenberg20-Jun-02 5:15 
GeneralRe: Very Useful Pin
Brian Delahunty20-Jun-02 5:25
Brian Delahunty20-Jun-02 5:25 
GeneralRe: Very Useful Pin
Thomas Freudenberg20-Jun-02 5:31
Thomas Freudenberg20-Jun-02 5:31 
GeneralRe: Very Useful Pin
Brian Delahunty20-Jun-02 5:52
Brian Delahunty20-Jun-02 5:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.