0
votes

I am currently using the method in this post to get the icon of a file and it worked.

The only problem is, I can only get the 16x16, 32x32, 48x48 and 256x256 version of the icon set. Using the jumbo version is not a good idea since the icon looks awful after being scaled. I believe that there should be a way to get the icon of a certain size since the icon file has more than the four sizes. But how?

P.S. I prefer not to use a external library.

1
If a 64x64 icon doesn't exist you won't be able to get it. Are you sure that it actually exists?ChrisF
See this : creativefreedom.co.uk/icon-designers-blog/windows-7-icon-sizes - 64x64 is not required, so may not be therePaulF
If you are using SHGetImageList, the docs for that say you need to use SHIL_SYSSMALL and These images are the size specified by GetSystemMetrics called with SM_CXSMICON and GetSystemMetrics called with SM_CYSMICON.DavidG
Have you looked at the System.Drawing.Icon classPaulF
@PaulF: What does that have to do with retrieving the application's icon? Have you read the question?Ken White

1 Answers

2
votes

The system maintains four differently sized image lists; small (16x16), large (32x32), extra large (48x48) and jumbo (256x256).

But note that the sizes are only the typical standard ones. If the system is set to a different DPI scaling factor, the sizes can change (e.g. on a 200% DPI system, the large image list will be 64x64).

When the system adds an icon to the system image list, it picks the closest size from the icon resource to avoid scaling as much as possible. That means that, if a program contains a 64x64 pixel icon, it MIGHT get used for the extra large image, it MIGHT get used for the large image, it MIGHT even get used for the small image (on a 400% DPI scaled system) - but there are no guarantees.

The only way to definitively extract an icon of a specific size from an executable is to load it yourself.

Instead of using SHGetFileInfo to retrieve the icon (or icon index) for you, instead you can ask it to tell you where the icon comes from (that is, the executable containing the icon resource and the resource index). To do this, use the SHGFI_ICONLOCATION flag. This will return you the executable path that contains the icon in szDisplayName, and the icon's index in iIcon.

You can then pass that information to the SHDefExtractIcon function, using its nIconSize parameter to request an icon of a specific size.

Psuedo-code:

// find icon location for .txt file icons
SHFILEINFO sfi{};
SHGetFileInfo(L".txt", FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_USEFILEATTRIBUTES | SHGFI_ICONLOCATION);

// extract the 64x64 pixel icon
HICON hIcon;
SHDefExtractIcon(sfi.szDisplayName, sfi.iIcon, 0, nullptr, &hIcon, MAKELONG(0, 64));