Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Force rebuild of system imagelist

199 views
Skip to first unread message

Timo Kunze

unread,
Mar 20, 2008, 7:39:05 AM3/20/08
to
Hi,

my app uses icons and overlays from the system imagelist. When I use
TweakUI to change the overlay icon for shortcuts from e. g. normal to
light arrow, my app receives a SHCNE_UPDATEIMAGE notification. The image
index provided by this notification is -1, which means I should do a
complete refresh. So I retrieve the system imagelist again (I use
SHGetImageList for this task) and reload all icons and overlays I'm
displaying.
However, I still get the old shortcut overlay. I also tried calling
FileIconInit(FALSE) before calling SHGetImageList. It doesn't change
anything.

How can I force a rebuild of the system imagelist?
We're talking about Windows XP SP2 here, but I guess the problem exists
on Windows 2000, 2003 and maybe Vista/2008 as well.

Thanks in advance
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."

Jim

unread,
Mar 20, 2008, 8:40:44 AM3/20/08
to

> How can I force a rebuild of the system imagelist?
> We're talking about Windows XP SP2 here, but I guess the problem
> exists on Windows 2000, 2003 and maybe Vista/2008 as well.

Raymond Chen had a blog about this sometime ago. All you can do is
increase the size of the default images by a pixel then return them to
their original size. This will unfortunately sometimes reorder the
icons on the desktop.

Something like this:

Reg.RootKey := HKEY_CURRENT_USER;
if Reg.OpenKey('\Control Panel\Desktop\WindowMetrics', False)
then
begin
FlushImageLists; // Here I just release the handles to the
system imagelist I have
{ Flush the Icon Cache by changing the size of the icons }
if Reg.ValueExists('Shell Icon Size') then
LargeIconSize := StrToInt(Reg.ReadString('Shell Icon Size'))
else
LargeIconSize := GetSystemMetrics(SM_CXICON);
Reg.WriteString('Shell Icon Size', IntToStr(LargeIconSize +
1));
SendMessage(Handle, WM_SETTINGCHANGE,
SPI_SETNONCLIENTMETRICS, Integer(PChar('WindowMetrics')));
FileIconInit(True); // Flush the cached Icons
Reg.WriteString('Shell Icon Size', IntToStr(LargeIconSize));
SendMessage(Handle, WM_SETTINGCHANGE,
SPI_SETNONCLIENTMETRICS, Integer(PChar('WindowMetrics')));
FileIconInit(True); // Flush the cached Icons
end;

Jim
--
www.mustangpeak.net

Timo Kunze

unread,
Mar 20, 2008, 10:42:10 AM3/20/08
to
Thanks Jim. This way it works.
I wonder why this code should reorder the desktop icons. Doesn't each
process use its own copy of the system imagelist? I would expect
FileIconInit to flush this copy only.
However, changing the shortcut overlay with TweakUI reorders the desktop
icons anyway, so I can blame TweakUI if anyone complains. *g*

Jim Barry

unread,
Mar 20, 2008, 12:29:26 PM3/20/08
to
Timo Kunze wrote:
> I wonder why this code should reorder the desktop icons. Doesn't each
> process use its own copy of the system imagelist? I would expect
> FileIconInit to flush this copy only.

Yes, FileIconInit only affects the system image list of the calling process. Broadcasting WM_SETTINGCHANGE with SPI_SETNONCLIENTMETRICS in wParam or "WindowMetrics" in lParam will cause Explorer to reload its copy (as well as any other application that is listening).

--
Jim Barry, Microsoft MVP

Timo Kunze

unread,
Mar 20, 2008, 12:48:20 PM3/20/08
to
Ah, that's nice, because I don't send WM_SETTINGCHANGE. It also works
without it.
0 new messages