The easy one-stop-shopping
way to get the icon for a file is to use the
SHGetFileInfo
function with the SHGFI_ICON
flag.
One quirk of the SHGetFileInfo
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_ADDOVERLAYS
flag.
(Exercise: What is so special about the
shortcut overlay that makes it
exempt from the powers of the
SHGFI_ADDOVERLAYS
flag?
The information you need is on the MSDN page for
SHGetFileInfo
,
though you’ll have to apply some logic to the sitaution.)
I’m using SHGetFileInfo 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_LINKOVERLAY) I’d like to display the original exe icon. Is there a way to do this with SHGetFileInfo? 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 IShellLink::SetIconLocation
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 SHGetFileInfo
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
SHGetFileInfo
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 ImageList_Draw
to draw the image when necessary,
instead of creating thousands of little icons.
0 comments