Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SHGetImageList - SHIL_JUMBO for smaller icons (32,32)

In my code I get a list of images through the function SHGETImageList with size SHIL_JUMBO.

 IImageList iml;
 var hres = SHGetImageList(SHIL_JUMBO, ref iidImageList, out  iml);
 IntPtr hIcon = IntPtr.Zero;
 iml.GetIcon(i, ILD_TRANSPARENT |  ILD_IMAGE, ref hIcon);

 Icon ico =  (Icon)System.Drawing.Icon.FromHandle(hIcon).Clone();
 ShellAPI.DestroyIcon(hIcon);

Everything is ok, but when it has to get smaller icons (when they don't have a size for 256x256) the function GetIcon returns me an icon with the size of 256x256 but with the icon of size 32x32 in top left corner. I want to resize this icon to the new size (256 x 256).

I don't have any information how to have the system resize my icon to 256 x 256. Every function in iml (like GetImageInfo, GetImageRect) for this size returns an empty structure.

It's possible to get information that this icon is smaller and i can get icon from another source.

like image 774
arkadykl Avatar asked Jun 23 '11 17:06

arkadykl


1 Answers

Looks like, since Vista, Microsoft expects developers to rely on IShellItem and IShellItemImageFactory interfaces. Unlike IImageList implementation of the system image lists, which is badly broken (most methods fail with E_NOTIMPL, icon sizes are not reported), IShellItemImageFactory produces images exactly like they are displayed in Explorer. In case of small icons requested in "jumbo" size, they are centered and surrounded by a border (on Windows 7, at least). While it is less efficient and more memory consuming to use than IImageList, Explorer probably uses it too, so it's no big deal.

See IShellItemImageFactory::GetImage method on MSDN for more details.

There's a library for .NET which supports these interfaces: Windows® API Code Pack for Microsoft® .NET Framework.


While this doesn't exactly answer your question (there's still no reliable way to determine size of icons), I think resizing a small 32x32 icon to 256x256 is a bad idea, and Explorer way (resizing only up to 48x48, then centering) should be preffered. This will also provide a consistent behavior which is a good idea.

Considering questions like this have been posted in many places, and none have been answered for years, I'm afraid more information can only be obtained by reverse-engineering Windows Shell, and in particular standard/default IShellItemImageFactory::GetImage implementation. Geoff Chappell did quite a bit of reverse engineering of shell, so maybe it's worth trying to ask him...

like image 149
Athari Avatar answered Nov 10 '22 15:11

Athari