Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

c++ - I can't get SHGetFileInfo to return an icon location

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 (as seemed to happen here) but it is completely filled with .

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...