I display objects, some of which are files and folders in TTreeView
, TListView
and a few other custom controls.
When a folder is selected, I display its contents (files and folders) in TListView
and I use the Windows System Image List to assign an icon. I call SHGetFileInfoW
to obtain an icon index. SHGetFileInfoW
is also used to obtain the System Image List Handle:
SHFILEINFOW info ;
DWORD Flags = (SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_OVERLAYINDEX) // for instance
ImageList->Handle = SHGetFileInfoW( L"",
0,
&info,
sizeof(SHFILEINFOW),
Flags
) ;
My program also keeps its own ImageList
with icons, since it displays more than just files and folders. In TreeView
for instance a combination of 'other objects' and folder objects will be shown:
To keep folder icons consistent (same) between TreeView
and ListView
on different versions of the Windows OS, I copy the Windows System folder icon to my own ImageList
during program start.
This way both TreeView
and ListView
use the same folder icon, and the icon is that of the OS the software is running on.
This has worked well for many years across many OS, from Win2K to W11. However I'd like to try the reverse approach now IF at all possible. I'd like to use my own folder icon in both ListView
and TreeView
. For TreeView
this is not a problem, but for ListView
it is an issue in every situation where files and folders are displayed together, since I use the Windows System Image List to display the file icons and hence also folder icons.
I can think of a workaround where I create the needed registry entries to register a very unique file extension that is associated with a folder icon in my executable. I could then use that for folders. But it's a workaround that may not always work perfectly if Windows doesn't refresh immediately etc.
So, the question, is it at all possible to add an icon to the System Image List during program execution ? Is there a Windows API call that does this ? If so I could use that Index then to display folder icons in ListView
.
Yes and no.
First off, in Windows NT based systems, the system image list is per-process and is not a full copy of the real list. In Windows 95 it really was global. This means the design never intended for people to add extra HICONs on their own directly into the list.
While it is called the system image list, the only thing it stores are file type icons and the shell extension overlays, it is not a general icon list.
There are two ways to add icons to the list:
The common way is to use one of the shell functions (like
SHGetFileInfo
) to ask for information about a file path or extension.The other way is to call
Shell_GetCachedImageIndex
. This function used to be undocumented and was only documented because of the DOJ trial.My suggestion: Use your own custom imagelist with your custom images. In slot 0 place an empty icon that you draw on top of with custom draw (not owner-draw).