2011-06-23 16 views
15

En mi código consigo una lista de imágenes a través de la función SHGETImageList con el tamaño SHIL_JUMBO.SHGetImageList - SHIL_JUMBO para iconos más pequeños (32,32)

IImageList iml; 
var hres = SHGetImageList(SHIL_JUMBO, ref iidImageList, out iml); 
IntPtr hIcon = IntPtr.Zero; 
iml.GetIcon(i, ILD_TRANSPARENT | ILD_IMAGE, ref hIcon); 

Icon ico = (Icon)System.Drawing.Icon.FromHandle(hIcon).Clone(); 
ShellAPI.DestroyIcon(hIcon); 

todo está bien, pero cuando se tiene que conseguir iconos más pequeños (cuando no tienen un tamaño de 256x256) la función GetIcon me devuelve un icono con el tamaño de 256x256, pero con el icono de tamaño 32x32 en la esquina superior izquierda. Quiero cambiar el tamaño de este icono al nuevo tamaño (256 x 256).

No tengo ninguna información sobre cómo hacer para que el sistema cambie el tamaño de mi icono a 256 x 256. Todas las funciones en iml (como GetImageInfo, GetImageRect) para este tamaño devuelven una estructura vacía.

Es posible obtener información de que este ícono es más pequeño y que puedo obtener ícono de otra fuente.

+0

Estoy teniendo exactamente el mismo problema. Me vuelve loco. Atacando el problema desde la otra dirección: ¿Hay alguna forma de detectar si hay un icono Jumbo o no? – MarcWan

+0

¿Qué valor de i te da esto? ¿Estás seguro de que no es porque son simplemente imágenes superpuestas? –

Respuesta

0

sea posible ejecutar un código para identificar las mediciones de la imagen y utilizar el siguiente cuando sea necesario:

var hres = SHGetImageList(SHIL_LARGE, ref iidImageList, out iml);

SHIL_LARGE es de 32x32.

El tipo de puntero IImageList, como el que se devuelve en el parámetro ppv, se puede convertir como HIMAGELIST según sea necesario; por ejemplo, para usar en una vista de lista. Por el contrario, un HIMAGELIST se puede convertir como un puntero a un IImageList. A partir de Windows Vista, SHIL_SMALL, SHIL_LARGE, y SHIL_EXTRALARGE escala con puntos por pulgada (ppp) si el proceso está marcado como ppp-conscientes. Para configurar estos tipos para que sean compatibles con dpi, llame a SetProcessDPIAware. SHIL_JUMBO se fija en 256 píxeles, independientemente de la configuración de reconocimiento de ppp.

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185(v=vs.85).aspx

-1

he ejecutar su ejemplo usando

const string IID_IImageList = "46EB5926-582E-4017-9FDF-E8998DAA0950"; 
const string IID_IImageList2 = "192B9D83-50FC-457B-90A0-2B82A8B5DAE1"; 

definido en CommonControls.h durante la marcha:

 IEnumerable<int> shils = new int[]{ 
      ShellAPI.SHIL_EXTRALARGE, 
      ShellAPI.SHIL_JUMBO, 
      ShellAPI.SHIL_SYSSMALL, 
      ShellAPI.SHIL_LARGE, 
      ShellAPI.SHIL_SMALL, 
      ShellAPI.SHIL_LAST 
     }; 
     ShellAPI.IImageList ppv = null; 
     Guid guil = new Guid(IID_IImageList2);//or IID_IImageList 
     foreach (int iil in shils) 
     { 
      ShellAPI.SHGetImageList(iil, ref guil, ref ppv); 
      int noImages = 0; 
      ppv.GetImageCount(ref noImages); 
      //... 
     } 

las imágenes cuentan permanece constante. Por lo tanto, debo estar en desacuerdo con

cuando no tienen un tamaño de 256x256

Para cada tipo de lista de imágenes que hay un número constante de imágenes, por lo que no hay iconos que faltan para el ajuste de Jumbo.

He persistido todos los iconos encontrados con todas las resoluciones (16x16,32x32,48x48,256x256). La relación de aspecto es idéntica entre todos los diferentes tamaños del mismo icono (el mismo índice de lista de imágenes/diferente resolución). La relación de aspecto significa que la versión de 256x256 no es la versión de 48x48 pegada en una esquina, y el resto del relleno de fondo negro.

Por otra parte, todos los iconos

con el tamaño de 256x256, pero con el icono del tamaño de 32x32 en esquina izquierda superior son en realidad imágenes de superposición, como se puede comprobar:

int currentImageListIndex; //loop by noImages above 
int idx0Based=0; 
ppv.GetOverlayImage(currentImageListIndex+1, ref idx0Based); 
degradación

calidad se puede encontrar fácilmente usando IImageAList :: GetItemFlags y comprobar el parámetro de salida para dwFlags ILIF_LOWQUALITY, MSDN siguiente cita

Windows Vista y posterior. Indica que el elemento en la lista de imágenes se genera a través de una función StretchBlt, en consecuencia, la calidad de imagen puede haberse degradado

2

Parece que, desde Vista, Microsoft espera que los desarrolladores confían en IShellItem y IShellItemImageFactory interfaces. A diferencia de la implementación de IImageList de las listas de imágenes del sistema, que está muy estropeada (la mayoría de los métodos fallan con E_NOTIMPL, no se informan los tamaños de los iconos), IShellItemImageFactory produce imágenes exactamente como se muestran en el Explorador. En el caso de iconos pequeños solicitados en tamaño "jumbo", están centrados y rodeados por un borde (en Windows 7, al menos). Si bien es menos eficiente y consume más memoria que el IImageList, Explorer probablemente también lo use, por lo que no es gran cosa.

Consulte IShellItemImageFactory::GetImage method en MSDN para obtener más información.

Hay una biblioteca para .NET que admite estas interfaces: Windows® API Code Pack for Microsoft® .NET Framework.


Si bien esto no responde exactamente a su pregunta (todavía no hay manera confiable para determinar el tamaño de los iconos), creo que el cambio de tamaño de un pequeño icono de 32x32 a 256x256 es una mala idea, y la forma en Explorer (cambio de tamaño sólo hasta a 48x48, luego centrar) debe ser preffered. Esto también proporcionará un comportamiento constante que es una buena idea.

Considerando que preguntas como esta han sido publicadas en muchos lugares, y ninguna ha sido respondida por años, me temo que solo se puede obtener más información mediante la ingeniería inversa de Windows Shell y, en particular, la implementación estándar/predeterminada IShellItemImageFactory::GetImage. Geoff Chappell hizo un poco de ingeniería inversa de shell, por lo que tal vez vale la pena intentar preguntarle ...

+0

Esta respuesta tiene un buen contenedor para el método GetImage: http://stackoverflow.com/a/21752100/242451 –

Cuestiones relacionadas