Is it possible to add an icon to the Windows System Image List?

427 views Asked by At

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

enter image description here

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:

enter image description here

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.

1

There are 1 answers

2
Anders On

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