January 27th, 2011

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

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.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.