views:

72

answers:

1

I really liked the oxygen appearance of KDE SC 4. I wrote a program to apply these icons to windows. The program is written in NSIS, and is currently nearly fully functional. However, the only way I found to make Windows aware of the icon changes is to kill explorer.exe, delete the icon cache, and respawn explorer.exe. SHChangeNotify with SHCNE_ASSOCCHANGED seems to be unable to make Windows aware of the changes to the Control Panel icon, the My Computer icon, etc. Please suggest a better, less brutal approach to make Windows aware of these changes.

EDIT:I found a program called Icon Tweaker that appears to be able to do this, but it is closed source and so I have no idea how it does this. (IconTweaker: http://www.crystalxp.net/galerie/en.id.83-icontweaker.html)

EDIT: I have this working fine, thanks to Anders' reply (see below). However, I'll just put my working NSIS code here,in case someone else needs it

ReadRegStr $0 HKCU "Control Panel\Desktop\WindowMetrics" "Shell Icon Size"
IntOp $0 $0 + 1
WriteRegStr HKCU "Control Panel\Desktop\WindowMetrics" "Shell Icon Size" $0
SendMessage 0xffff 0x001A 42 0 /TIMEOUT=100000
IntOp $0 $0 - 1
WriteRegStr HKCU "Control Panel\Desktop\WindowMetrics" "Shell Icon Size" $0
SendMessage 0xffff 0x001A 42 0 /TIMEOUT=100000

The $0 register is used to store the "Shell Icon Size" value of "HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics". We then increment the value and do a SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 100000, NULL), followed by a decrement and re-send.

+1  A: 

SystemParametersInfo() has a parameter called SPI_SETICONS that "Reloads the system icons" according to MSDN. I have never tried to use SPI_SETICONS so I don't know if it works, if you wanted to test you would use something like

System::Call 'user32::SystemParametersInfo(i 0x0058,i0,i0,i2)i' ;SPI_SETICONS

If it turns out that this is not enough, you can bring out the big undocumented hammer:

  1. Read REG_SZ value named "Shell Icon Size" in HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics (If the value is not there, either abort or use GetSystemMetrics(SM_CXICON))
  2. Subtract 1 from the number you got from step one
  3. Write the modified entry back to the registry
  4. Call SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 100000, NULL)
  5. Write the number you got from step one entry back to the registry
  6. Call SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 100000, NULL)

Note that this could re-arrange the desktop icons even if "Auto Arrange" is off and possibly other things that might annoy the user!

Anders
Thank you for replying! Unfortunately System::Call 'user32::SystemParametersInfo(i 0x0058,i0,i0,i2)i' does not work :-(. Even the icons for filetypes like .zip, .bat, etc do not reload. Thus, it appears this way is not a solution. As for "the big undocumented hammer", can you please tell me how to implement these calls in NSIS (I've not got much experience invoking system calls from NSIS via the System plugin).
Sudarshan S
@Sudarshan S: ReadRegStr,IntOp,WriteRegStr,SendMessage 0xffff 0x001A 42 0 /TIMEOUT=100000 are all built-in commands, System::Call 'user32::GetSystemMetrics(i 11)i.r0' will give you SM_CXICON size in $0
Anders
Thank You! I finally have it working :-). This causes Windows to refresh all icons in the cache, including the My Computer icon, Control Panel icon, etc. While this may have side effects, it is much less brutal than my initial method of deleting the icon cache after killing explorer.exe and then respawning explorer.exe
Sudarshan S
It appears that all the icons only changed the first time I tried. Unfortunately, not all icons change on subsequent tries. Weird
Sudarshan S
Apparently, icons under HKCR\CLSID\{XXXXXX}\DefaultIcon do not get refreshed consistently this way. All other icons get refreshed consistently this way.
Sudarshan S
This appears to be because you are expected to customize Windows only by changing CLSIDs under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer and not icons under HKCR
Sudarshan S