I'm trying to get a high resolution icon or thumbnail in Windows given a full path to that file. Doesn't need to be a thumbnail — a good looking Icon will be great. I Don't care if it's an HICON
or an HBITMAP
: I'm going to put it in a GDI+ object and render it into a device context.
I've tried using SHGetFileInfo
(with various variations on flags), but never get more than a ~32x32 icon back, which scales horribly to the 128 pixels or so that I need.
if (!SHGetFileInfoW(path, 0, &fi, sizeof(fi),
SHGFI_ICON | SHGFI_ICONLARGE | SHGFI_TYPENAME))
return GetLastError();
// fi.hIcon is a valid icon here, but it's horrible quality with
// a black mask on it. I want higher quality, and dare I dream of
// alpha channel? Mask is acceptable, i suppose.
SHGetFileInfo
returns ""
when I call with SHGFI_ICONLOCATION
(which appears to be a known problem with that API).
I've also tried using SHCreateItemFromParsingName
name with the intention of getting IThumbnailProvider
, but BindToHandler
always returns E_NOTIMPL
for BHID_ThumbnailHandler
...
IShellItem *psi;
hr = SHCreateItemFromParsingName(path, NULL, IID_PPV_ARGS(&psi));
if (SUCCEEDED(hr))
{
IThumbnailProvider *pThumbProvider;
hr = psi->BindToHandler(NULL, BHID_ThumbnailHandler,
IID_PPV_ARGS(&pThumbProvider));
if (SUCCEEDED(hr))
{
// never get here because hr == E_NOTIMPL !!!
I've actually run the Microsoft Thumbnail Providers Sample and found that it suffers from the same problem with BindToInterface
.
So, any suggestions on what else I could try? I just want something picture-y that more or less represents this file at, say, at least 100px size — just anything better than 32x32 ...
Right-click the EXE file for the software you want to extract an icon from and select Properties. Click the Icons tab shown directly below. Select an icon to extract there. Choose a size and color option on the Device images menu.
Here's a quick way to do that: If you have access to a shortcut that points to the application, right-click it and select “Properties.” Then click “Open File Location” in the “Shortcut” tab, and you'll be taken directly to the EXE's location in File Explorer.
If you are targeting Vista and higher, you can get a 256x256 icon from the jumbo image list. If you need to target XP, you can at least use the extra large image list, which is 48x48 (slightly better than 32x32 large).
#include <commoncontrols.h>
#include <shellapi.h>
HICON GetHighResolutionIcon(LPTSTR pszPath)
{
// 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_TRANSPARENT, &hico);
// Clean up
piml->Release();
// Return the icon
return hico;
}
Have you tried ExtractIconEx()?
It has dedicated parameters to extract arrays of both small and large icons from executables, DLLs, or icon files. From there you can select the size best suited to your needs. The API call is available from Win2K onwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With