2009-04-01 10 views
6

(estoy usando Visual Studio 2008, aunque recuerdo haber tenido problemas similares con versiones anteriores también.)Problemas con el establecimiento de icono de la aplicación

He intentado varios métodos diferentes (muchos de ellos se menciona en this other question), pero todavía estoy teniendo algunos problemas extraños:

  1. Cuando se incluye un icono como un recurso, lo hace aparecer como el icono del archivo ejecutable de inmediato, pero para el icono aparezca en la barra de tareas, tengo que reiniciar el ordenador. Hasta entonces, continúa apareciendo como cualquier icono anterior. Limpiar la solución, reiniciar VS, no tiene ningún efecto. No es realmente un gran problema, ya que no afectará a un ejecutable liberado, pero sería bueno saber dónde se guarda el antiguo icono en la memoria caché y cómo deshacerse de él.

  2. No importa lo que haga, el ícono que se muestra cuando alt-tabbing es el icono predeterminado de la aplicación (cuadrado y blanco y genérico). Esto incluye insertar el icono en el ejecutable, así como configurar ICON_BIG con WM_SETICON.

En cuanto a la segunda cuestión, mi código es algo como:

hIcon = (HICON)(
     LoadImage(NULL, szFilename, IMAGE_ICON, 32, 32, LR_LOADFROMFILE)); 
    if(hIcon) 
     SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 

Sin embargo, después de enviar WM_SETICON, GetLastError() retornos 6, "El identificador no es válido.". hWnd es un identificador de ventana válido y hIcon parece ser un identificador de icono válido. Intenté buscar las razones por las cuales WM_SETICON podría causar ese error y, como mínimo, para averiguar QUÉ manejar, piensa que no es válido, pero aún no tiene suerte. Borré el código de error inmediatamente antes de llamar al SendMessage(), por lo que debe establecerse en algún lugar del procesamiento del mensaje.

he intentado un método alternativo, cargando el icono del ejecutable, en sí, donde el identificador del recurso es 101 (que es el primer y único recurso incluidos):

hIcon = (HICON)(
     LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(101), 
     IMAGE_ICON, 48, 48, 0)); 
    if(hIcon) 
     SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 

... pero la misma cosa sucede; después de llamar al SendMessage(), GetLastError() da el mismo estado de error.

He intentado diferentes dimensiones (como 48x48, todas las cuales están presentes en el archivo de icono), pero para ningún efecto diferente. Sé que definitivamente está buscando y cargando las imágenes, porque si especifico un tamaño que no existe o una identificación de recurso no válida o un nombre de archivo incorrecto (dependiendo de cómo lo estoy cargando), falla mucho antes de SendMessage().

Curiosamente, si especifico ICON_SMALL en lugar de ICON_BIG, la llamada se realiza correctamente sin estado de error, pero a partir de the docs, necesito utilizar ICON_BIG para establecer el icono utilizado mientras alt-tabulación. Además, si uso ICON_BIG pero cargo el icono de 16x16, no obtengo ningún estado de error, pero nada cambia.

¿Alguna idea sobre qué podría estar causando que WM_SETICON fallara? ¿Hay algo terriblemente mal con el código que he publicado (aparte de los problemas de formato/estilo/casting, ya que está simplificado a solo lo básico)?

Respuesta

3

He vuelto a visitar esto para ver si puedo cerrar mi pregunta. No he podido mostrar el ícono de la aplicación en la lista de alt-tab solo al insertarlo en el ejecutable; aparecerá en la barra de tareas, como el ícono del archivo en el Explorador y en cualquier otro lugar, muy bien.

que pensé que iba a tratar algo más sencillo para configurar manualmente el icono, y fue con LoadIcon() lugar, como el código de muestra:

HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)); 
if(hIcon) 
{ 
    SendMessage(GetHandle(), WM_SETICON, ICON_BIG, (LPARAM)hIcon); 
    DestroyIcon(hIcon); 
} 
// ... Same for ICON_SMALL 

Esto parece haber hecho el truco. Realmente no sé por qué, pero hasta ahora es el único cambio que tuvo algún efecto. Realmente no es un problema en el que debería pasar más tiempo, así que simplemente voy con esto.

+0

Me encuentro con el mismo problema hoy. Lamentablemente, esto no funciona para mí. Tengo que buscar en internet otras soluciones. – Lothar

+0

El método 'LoadImage' funciona bien para mostrar el ícono en el menú' alt' + 'Tab' Tuve el problema de que no estaba configurando' LoadImage' de 'BIG_ICON' en 32x32, una vez que lo hice trabajado como un encanto. Ver: http://stackoverflow.com/a/24029664/1828637 – Noitidart

2

He utilizado un único archivo .ico con múltiples resoluciones 16x16, 32x32, 48x48, 96x96 sin problemas, como icono de la aplicación. Entonces las ventanas tomarán el tamaño correcto.

El shell de Windows tiene un icon cache, hay un trick para reiniciarlo sin reiniciar o cerrar sesión en la sesión actual, o matar a explorer.exe del administrador de tareas.

0

Si encontré la solución para mí. Creé una ventana de aplicación CFrameWnd invisible y luego algunas otras ventanas principales (que son ventanas de diálogo). La regla mágica no documentada es: tienes que cambiar el ícono grande en el primer CFrameWnd creado. Si bien cada ventana conserva su propia instancia ICON_BIG, no las usa. Por lo tanto, parece que no es posible mostrar diferentes iconos de la barra de tareas para diferentes ventanas dentro de una aplicación.

2

OK, esto funcionaba un lujo para mí:

HICON hIconSmall =(HICON)LoadImage(handleToYourApplicationInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON,16, 16, 0); 

HICON hIconLarge =(HICON)LoadImage(handleToYourApplicationInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON,256, 256, 0); // Big for task bar, small loaded otherwise. 

SendMessage(yourWindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall) ; 

SendMessage(yourWindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIconLarge) ; 
0

Para cualquiera que venga a esta misma dificultad si se va a cambiar ICON_BIG primero deberá enviar WM_SETICON con ICON_SMALL y luego proceder a ICON_BIG.

Por ejemplo:

SetLastError(0); 
SendMessage(windowHandle, WM_SETICON, ICON_SMALL, (LPARAM)iconsmallHandle); 
[do error handling] 
SetLastError(0); 
SendMessage(windowHandle, WM_SETICON, ICON_BIG, (LPARAM)iconbigHandle); 
[do error handling] 

Usted tendrá que utilizar SetLastError después de la primera SendMessage para borrar cualquier error devuelto.

Si solo está configurando ICON_SMALL puede ignorar ICON_BIG. Por alguna razón, en todas mis pruebas debe establecer ICON_SMALL independientemente de si ese icono necesita cambiar o no, antes de intentar cambiar ICON_BIG, de lo contrario siempre obtendrá el código de error 0x6 (identificador no válido).

Cuestiones relacionadas