问题
I'm on Windows 10 Pro and Visual Studio 2013, and I'm using SHGetFileInfoW to get an icon location (path + index) for a file type:
std::wstring wFile { L"a.bas" };
SHFILEINFOW fi {};
DWORD success = ::SHGetFileInfoW(wFile.c_str(),
FILE_ATTRIBUTE_NORMAL,
&fi,
sizeof(fi),
SHGFI_USEFILEATTRIBUTES | SHGFI_ICONLOCATION);
No matter whether wFile
refers to an existing file or is just any filename, the call returns 1 indicating success. The iIcon
member of fi
is set to a number, but szDisplayString
is empty. Not just the drive letter is overwritten with \0
(as seemed to happen here) but it is completely filled with \0
.
Microsoft recommends using IExtractIcon::
GetIconLocation as an alternative, but I need to get the icon for files which are not on a local filesystem, so I can't get an IShellInfo
object which would get me this interface pointer.
Getting an icon handle works, on the other hand. Is this function just buggy or am I doing something wrong? Is there a workaround?
回答1:
Icons can be dynamically generated and might not expose the path to its images. Icon handlers communicate this to the shell by setting the GIL_NOTFILENAME
flag in their IExtractIcon::GetIconLocation implementation. If GIL_SIMULATEDOC
is set the shell must also typically generate a icon on the fly.
If you call SHGetFileInfo
with the SHGFI_SELECTED
flag set then then function probably has to generate a new icon no matter which file type you are asking for.
If you are displaying a file list in a ListView/TreeView then you typically use SHGFI_SYSICONINDEX|SHGFI_SHELLICONSIZE|SHGFI_SMALLICON
and use the system image list.
Use SHGFI_ICON
if you need a HICON.
If SHGFI_ICONLOCATION
is specified then SHGetFileInfo
uses IExtractIcon:
Retrieve the name of the file that contains the icon representing the file specified by pszPath, as returned by the IExtractIcon::GetIconLocation method of the file's icon handler.
来源:https://stackoverflow.com/questions/42676256/i-cant-get-shgetfileinfo-to-return-an-icon-location