How do you obtain the icon for a shortcut without the shortcut overlay?

Raymond Chen

The easy one-stop-shopping way to get the icon for a file is to use the SHGet­File­Info function with the SHGFI_ICON flag. One quirk of the SHGet­File­Info function is that if you pass the path to a shortcut file, it will always place the shortcut overlay on the icon, regardless of whether you passed the SHGFI_ADD­OVERLAYS flag. (Exercise: What is so special about the shortcut overlay that makes it exempt from the powers of the SHGFI_ADD­OVERLAYS flag? The information you need is on the MSDN page for SHGet­File­Info, though you’ll have to apply some logic to the sitaution.)

I’m using SHGet­File­Info to get the icon of a file to display in my application. When the file is a shortcut, rather than displaying the exe icon with a link overlay (as in SHGFI_LINK­OVERLAY) I’d like to display the original exe icon. Is there a way to do this with SHGet­File­Info? Thanks,

First, correcting a minor error in the question: The icon for a shortcut is, by default, the icon for the shortcut target, but it doesn’t have to be. The IShell­Link::Set­Icon­Location method lets you set the icon for a shortcut to anything you like. (This is the method used when you click Change Icon on the shortcut property page.)

Anyway, the SHGet­File­Info function gets the icon first by asking the shell namespace for the icon index in the system imagelist, and then converting that imagelist/icon index into a HICON. If you want to change the conversion, you can just ask SHGet­File­Info to stop halfway and then finish the process the way you like.

HICON GetIconWithoutShortcutOverlay(PCTSTR pszFile)
{
 SHFILEINFO sfi;
 HIMAGELIST himl = reinterpret_cast<HIMAGELIST>(
  SHGetFileInfo(pszFile, 0, &sfi, sizeof(sfi),
                SHGFI_SYSICONINDEX));
 if (himl) {
  return ImageList_GetIcon(himl, sfi.iIcon, ILD_NORMAL);
 } else {
  return NULL;
 }
}

Of course, if you’re going to be doing this for a lot of files, you may want to just stop once you have the imagelist and the index, using Image­List_Draw to draw the image when necessary, instead of creating thousands of little icons.

0 comments

Discussion is closed.

Feedback usabilla icon