Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Win32 - determine if path has jumbo icon available

I have some code to get jumbo icons from a file:

// Get the image list index of the icon
SHFILEINFO sfi;
if (!SHGetFileInfo(pszPath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX)) return NULL;

// Get the jumbo image list
IImageList *piml;
if (FAILED(SHGetImageList(SHIL_JUMBO, IID_PPV_ARGS(&piml)))) return NULL;

// Extract an icon
HICON hico;
piml->GetIcon(sfi.iIcon, ILD_SCALE|ILD_TRANSPARENT, &hico);

Now, the problem is, if the path doesn't have a 256x256 icon associated with it, I don't want the icon returned by the ImageList. (It will helpfully take the 32x32 and put it in a 256x256 icon, which I cannot use).

So, is there a way to find out, if the icon that is (would be) associated with a path has a jumbo icon for it, or is indeed just going to be a scaled 32x32? If not, I'll just get the regular system icon.

NOTE:

Final solution inspired by Jonathan below:

HBITMAP hbitmapForFile(LPCWSTR path, int w, int h)
{
    IShellItemImageFactory *pif;    
    HBITMAP hbm;

    SIZE sz = { w, h };
    SHCreateItemFromParsingName(path, NULL, IID_PPV_ARGS(&pif));
    pif->GetImage(sz, SIIGBF_RESIZETOFIT, &hbm);
    pif->Release();
    return hbm;
}

I took the resulting HBITMAP and put it into a STATIC control with SS_BITMAP.

One important thing I learned: You cannot use the IShellItemImageFactory from within a HookProc. Known Windows limitation; I had to PostMessage to the window and then use it.

like image 566
MarcWan Avatar asked Nov 12 '22 22:11

MarcWan


1 Answers

I believe the proper way to do this is to not use SHGetFileInfo but instead to use the IShellItemImageFactory::GetImage method with the SIIGBF_THUMBNAILONLY flag.

like image 79
Jonathan Potter Avatar answered Nov 15 '22 12:11

Jonathan Potter