Article ID: 192055
Article Last Modified on 7/11/2005
HIMAGELIST himl;
SHFILEINFO sfi;
himl = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi,
sizeof(SHFILEINFO), SHGFI_SYSICONINDEX);
On Windows 95 and Windows 98, this function returns the handle of the
actual system image list. However, on Windows NT version 4.0 this function
returns a handle to a copy of the system image. Each process gets its own
copy of the system image list. Windows NT does this to maintain security
requirements so that one application cannot destroy the system image list.
The proper images are added to the process' copy of the system image list
whenever a call to SHGetFileInfo is made to retrieve the icon index for a
specific item type.
/********************************************************************
GetSystemImageList()
********************************************************************/
HIMAGELIST GetSystemImageList(BOOL fSmall)
{
HIMAGELIST himl;
SHFILEINFO sfi;
himl = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi,
sizeof(SHFILEINFO), SHGFI_SYSICONINDEX |
(fSmall ? SHGFI_SMALLICON : SHGFI_LARGEICON));
/*
Do a version check first because you only need to use this code on
Windows NT version 4.0.
*/
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
GetVersionEx(&vi);
if(VER_PLATFORM_WIN32_WINDOWS == vi.dwPlatformId)
return himl;
/*
You need to create a temporary, empty .lnk file that you can use to
pass to IShellIconOverlay::GetOverlayIndex. You could just enumerate
down from the Start Menu folder to find an existing .lnk file, but
there is a very remote chance that you will not find one. By creating
your own, you know this code will always work.
*/
HRESULT hr;
IShellFolder *psfDesktop = NULL;
IShellFolder *psfTempDir = NULL;
IMalloc *pMalloc = NULL;
LPITEMIDLIST pidlTempDir = NULL;
LPITEMIDLIST pidlTempFile = NULL;
TCHAR szTempDir[MAX_PATH];
TCHAR szTempFile[MAX_PATH] = TEXT("");
TCHAR szFile[MAX_PATH];
HANDLE hFile;
int i;
OLECHAR szOle[MAX_PATH];
DWORD dwAttributes;
DWORD dwEaten;
IShellIconOverlay *psio = NULL;
int nIndex;
// Get the desktop folder.
hr = SHGetDesktopFolder(&psfDesktop);
if(FAILED(hr))
goto exit;
// Get the shell's allocator.
hr = SHGetMalloc(&pMalloc);
if(FAILED(hr))
goto exit;
// Get the TEMP directory.
if(!GetTempPath(MAX_PATH, szTempDir))
{
/*
There might not be a TEMP directory. If this is the case, use the
Windows directory.
*/
if(!GetWindowsDirectory(szTempDir, MAX_PATH))
{
hr = E_FAIL;
goto exit;
}
}
// Create a temporary .lnk file.
if(szTempDir[lstrlen(szTempDir) - 1] != '\\')
lstrcat(szTempDir, TEXT("\\"));
for(i = 0, hFile = INVALID_HANDLE_VALUE;
INVALID_HANDLE_VALUE == hFile;
i++)
{
lstrcpy(szTempFile, szTempDir);
wsprintf(szFile, TEXT("temp%d.lnk"), i);
lstrcat(szTempFile, szFile);
hFile = CreateFile( szTempFile,
GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Do not try this more than 100 times.
if(i > 100)
{
hr = E_FAIL;
goto exit;
}
}
// Close the file you just created.
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
// Get the PIDL for the directory.
LocalToWideChar(szOle, szTempDir, MAX_PATH);
hr = psfDesktop->ParseDisplayName( NULL,
NULL,
szOle,
&dwEaten,
&pidlTempDir,
&dwAttributes);
if(FAILED(hr))
goto exit;
// Get the IShellFolder for the TEMP directory.
hr = psfDesktop->BindToObject( pidlTempDir,
NULL,
IID_IShellFolder,
(LPVOID*)&psfTempDir);
if(FAILED(hr))
goto exit;
/*
Get the IShellIconOverlay interface for this folder. If this fails,
it could indicate that you are running on a pre-Internet Explorer 4.0
shell, which doesn't support this interface. If this is the case, the
overlay icons are already in the system image list.
*/
hr = psfTempDir->QueryInterface(IID_IShellIconOverlay, (LPVOID*)&psio);
if(FAILED(hr))
goto exit;
// Get the PIDL for the temporary .lnk file.
LocalToWideChar(szOle, szFile, MAX_PATH);
hr = psfTempDir->ParseDisplayName( NULL,
NULL,
szOle,
&dwEaten,
&pidlTempFile,
&dwAttributes);
if(FAILED(hr))
goto exit;
/*
Get the overlay icon for the .lnk file. This causes the shell
to put all of the standard overlay icons into your copy of the system
image list.
*/
hr = psio->GetOverlayIndex(pidlTempFile, &nIndex);
exit:
// Delete the temporary file.
DeleteFile(szTempFile);
if(psio)
psio->Release();
if(INVALID_HANDLE_VALUE != hFile)
CloseHandle(hFile);
if(psfTempDir)
psfTempDir->Release();
if(pMalloc)
{
if(pidlTempFile)
pMalloc->Free(pidlTempFile);
if(pidlTempDir)
pMalloc->Free(pidlTempDir);
pMalloc->Release();
}
if(psfDesktop)
psfDesktop->Release();
return himl;
}
Keywords: kbshell kbprb KB192055