Click here to Skip to main content
13,792,845 members
Click here to Skip to main content


66 bookmarked
Posted 8 Jun 2002
Licenced CPOL

Retrieving shell icons

, 19 Jun 2002
Get shell icons, even if they're customized
#include "stdafx.h"
#include "ShellIcons.h"

#ifndef _AFXDLL

#include <vector>
#include <string>

namespace std
#ifdef _UNICODE
	typedef wstring tstring;
	typedef string tstring;

namespace {

*	Yet another tokenizer
*	\param	x			Output iterator
*	\param	in			The string to tokenize
*	\param	delimiters	A string containing token separators
*	\par Original take from
*	""
*	The Standard C (and C++) function strtok() leaves a lot to be desired in terms of user-friendliness.
*	It's unintuitive, it destroys the character string on which it operates, and it requires you to handle
*	all the memory problems. But it does let the client code decide what to use to break the string into
*	pieces; it allows you to choose the "whitespace," so to speak. 
*	A C++ implementation lets us keep the good things and fix those annoyances. The implementation here is
*	more intuitive (you only call it once, not in a loop with varying argument), it does not affect the
*	original string at all, and all the memory allocation is handled for you. 
*	It's called tokenize, and it's a template function. It's given in this file in a less-portable for
*	than it could be, to keep this example simple (for example, see the comments on what kind of string it
*	will accept). The author uses a more general (but less readable) form of it for parsing command
*	strings and the like. If you compiled and ran this code using it: 
*	\code
   std::list<std::string>  ls;
   utl::tokenize (std::back_inserter(ls), " this  \t is\t\n  a test  ");
   for (std::list<std::string>::const_iterator it = ls.begin(); it != ls.end(); ++it)
       std::cerr << ':' << (*it) << ":\n";
*	You would see this as output: 
*	<pre>
*	with all the whitespace removed. The original \a s is still available for use, \a ls will clean up
*	after itself, and \a ls.size() will return how many tokens there were. 
	template <typename outit>
	void tokenize (outit x, const std::tstring &in, const TCHAR * delimiters = _T(" \t\n"))
		const std::tstring::size_type len = in.length();
		std::tstring::size_type i = 0;

		while ( i < len )
			// eat leading whitespace
			i = in.find_first_not_of (delimiters, i);
			if (i == std::tstring::npos)
				return;   // nothing left but white space

			// find the end of the token
			std::tstring::size_type j = in.find_first_of (delimiters, i);

			// push token
			if (j == std::tstring::npos) {
				*x = in.substr(i);
			} else {
				*x = in.substr(i, j-i);

			// set up for next loop
			i = j + 1;
} // anonymous namespace

#endif // _AFXDLL

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);
			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);

		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;

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Thomas Freudenberg
Technical Lead Cubeware GmbH
Germany Germany
No Biography provided

You may also be interested in...

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.181207.3 | Last Updated 20 Jun 2002
Article Copyright 2002 by Thomas Freudenberg
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid