Извлеките иконку высокого разрешения или миниатюру для файла

Я пытаюсь получить иконку высокого разрешения или миниатюру в Windows, учитывая полный путь к этому файлу. Не нужно быть миниатюрами - хорошо выглядящая икона будет великолепной. Мне все равно, если это HICON или HBITMAP: я собираюсь поместить его в объект GDI + и отобразить его в контексте устройства.

Я пробовал использовать SHGetFileInfo (с различными вариантами флажков), но никогда не получаю больше, чем значок 32x32, который ужасно масштабируется до 128 пикселей или так, что мне нужно.

if (!SHGetFileInfoW(path, 0, &fi, sizeof(fi),
                    SHGFI_ICON | SHGFI_ICONLARGE | SHGFI_TYPENAME))
    return GetLastError();

// fi.hIcon is a valid icon here, but it 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 возвращает "" при вызове SHGFI_ICONLOCATION (который, как представляется, является известной проблемой с этим API).

Я также пытался использовать SHCreateItemFromParsingName имя с целью получить IThumbnailProvider, но BindToHandler всегда возвращает E_NOTIMPL для 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 !!!

Я действительно запускаю Microsoft Пример поставщиков эскизов и обнаружил, что он страдает от той же проблемы с BindToInterface.

Итак, какие-либо предложения о том, что еще я мог попробовать? Мне просто нужно что-то изображение, которое более или менее представляет этот файл, скажем, размером не менее 100 пикселей - всего-то лучше, чем 32x32...

Ответ 1

Если вы ориентируетесь на Vista и выше, вы можете получить значок 256x256 из списка гигантских изображений. Если вам нужно настроить таргетинг на XP, вы можете, по крайней мере, использовать список дополнительных больших изображений, который составляет 48x48 (немного лучше, чем 32x32 больших).

#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;
}

Ответ 2

Вы пробовали ExtractIconEx()?

Он имеет выделенные параметры для извлечения массивов маленьких и больших значков из исполняемых файлов, библиотек DLL или файлов значков. Оттуда вы можете выбрать размер, наиболее подходящий для ваших нужд. Вызов API доступен из Win2K и далее.