Force rebuild of system imagelist

Showing 1-5 of 5 messages
Force rebuild of system imagelist Timo Kunze 3/20/08 4:39 AM
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."

Re: Force rebuild of system imagelist Jim 3/20/08 5:40 AM

> 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

Re: Force rebuild of system imagelist Timo Kunze 3/20/08 7:42 AM
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*
Re: Force rebuild of system imagelist Jim Barry 3/20/08 9:29 AM
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

Re: Force rebuild of system imagelist Timo Kunze 3/20/08 9:48 AM
Ah, that's nice, because I don't send WM_SETTINGCHANGE. It also works
without it.