2012-08-07 12 views
10

Estoy tratando de obtener un ícono o miniatura en alta resolución en Windows con una ruta completa a ese archivo. No es necesario que sea una miniatura; un buen ícono será genial. No me importa si es un HICON o un HBITMAP: lo pondré en un objeto GDI + y lo renderizaré en el contexto de un dispositivo.Extracto Icono o miniatura de alta resolución para el archivo

He intentado usar SHGetFileInfo (con varias variaciones en los indicadores), pero nunca obtengo más que un ícono de ~ 32x32, que se puede escalar horriblemente a los 128 píxeles que necesito.

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 vuelve "" cuando llamo con SHGFI_ICONLOCATION (que parece ser un problema conocido con esa API).

También he intentado usar SHCreateItemFromParsingName nombre con la intención de conseguir IThumbnailProvider, pero BindToHandler siempre devuelve E_NOTIMPL para 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 !!! 

De hecho, me he quedado el Microsoft Thumbnail Providers Sample y encontraron que sufre de el mismo problema con BindToInterface.

¿Alguna sugerencia sobre qué más podría probar? Solo quiero algo que represente más o menos este archivo en, digamos, al menos 100 px de tamaño, cualquier cosa mejor que 32x32 ...

+1

¿Qué sucede si los desarrolladores de archivos personalizados solo proporcionan un icono de 32x32? ¿De dónde obtienes una imagen más grande? Piensa sobre esto. – Apokal

+0

Gracias @Apokal, estoy contento con lo que sea que pueda obtener. Si una aplicación solo tiene íconos pequeños, la tomaré, pero sé que hay iconos muy grandes para cosas como archivos de texto, documentos de Office, etc. Me gustaría obtener lo mejor que puedo para esos ... – MarcWan

Respuesta

7

Si se dirige a Vista y superior, puede obtener un icono de 256x256 de la lista de imágenes jumbo. Si necesita apuntar a XP, al menos puede usar la lista de imágenes extragrandes, que es 48x48 (ligeramente mejor que 32x32 grande).

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

Hola Raymond, gracias. Esto es más o menos lo que quería. – MarcWan

+3

Un problema: si la imagen SÓLO tiene 32x32, esta función aún devolverá 256x256, solo con el icono en la esquina superior izquierda. ¿Hay alguna manera de determinar si no hay un icono jumbo y simplemente dejarme recurrir a otro código? ¡Gracias! – MarcWan

+0

Se ha intentado y, de hecho, se han aplicado superposiciones, pero los iconos son de 4 bits con fondos negros. – jnm2

1

¿Has probado ExtractIconEx()?

Tiene parámetros dedicados para extraer matrices de iconos pequeños y grandes desde ejecutables, DLL o archivos de iconos. Desde allí puede seleccionar el tamaño que mejor se adapte a sus necesidades. La llamada API está disponible desde Win2K en adelante.

+0

I Creo que ExtractIconEx solo obtiene los íconos pequeños y "grandes" estándar, de la época en que los grandes significaban 32x32. –

+0

@AdrianMcCarthy Lo intento y estás en lo cierto. 32x32 fue el más grande que pude encontrar. – U007D

+0

He estado leyendo sobre esto, pero parece que alcanza un máximo de 48x48, y no conozco el índice del ícono; solo conozco el tipo de archivo. ¿Existe algún tipo de solución integral que me dé ~ 100px imágenes con una extensión? – MarcWan

Cuestiones relacionadas