2009-04-01 5 views
6

(j'utilise Visual Studio 2008, si je me souviens d'avoir des problèmes similaires avec les anciennes versions ainsi.)Problèmes de configuration icône de l'application

J'ai essayé plusieurs méthodes différentes (beaucoup d'entre eux mentionné dans this other question), mais j'ai encore quelques problèmes étranges:

  1. en incluant une icône comme une ressource, il montre comme l'icône de fichier exécutable immédiatement, mais pour l'icône pour afficher sur la barre des tâches, je dois redémarrer l'ordinateur. Jusque-là, il continue à apparaître comme n'importe quelle icône précédente. Le nettoyage de la solution, en redémarrant VS, n'a aucun effet. Ce n'est pas un gros problème, car cela n'affectera pas un exe libéré, mais il serait bon de savoir où garder l'ancienne icône en cache et comment s'en débarrasser.

  2. Quoi que je fasse, l'icône affichée lorsque alt-tabulation est l'icône de l'application par défaut (carrée et blanche et générique). Cela inclut l'incorporation de l'icône dans l'exécutable, ainsi que la définition de ICON_BIG avec WM_SETICON.

En ce qui concerne la deuxième question, mon code ressemble à quelque chose comme:

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

Cependant, après l'envoi WM_SETICON, GetLastError() retours 6, "La poignée est invalide.". hWnd est un handle de fenêtre valide et hIcon semble être un handle d'icône valide. J'ai essayé de chercher des raisons pour lesquelles WM_SETICON pourrait causer cette erreur, et à tout le moins, pour déterminer quel traitement il pense est invalide, mais pas encore de chance. J'ai effacé le code d'erreur immédiatement avant d'appeler SendMessage(), il doit donc être défini quelque part dans le traitement du message.

J'ai essayé une autre méthode, le chargement de l'icône de l'exe lui-même, où l'ID de la ressource est 101 (c'est la première et seule ressource inclus):

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

... mais la même chose arrive; après avoir appelé SendMessage(), GetLastError() donne le même état d'erreur.

J'ai essayé différentes dimensions (telles que 48x48, qui sont toutes présentes dans le fichier icône), mais sans aucun effet différent. Je sais que c'est définitivement trouver et charger les images, parce que si je spécifie une taille qui n'existe pas ou un ID de ressource invalide ou un nom de fichier incorrect (selon la façon dont je le charge), il échoue bien avant SendMessage().

Étrangement, si je spécifie ICON_SMALL au lieu de ICON_BIG, l'appel réussit sans statut d'erreur, mais de the docs, je dois utiliser ICON_BIG pour définir l'icône utilisée pendant alt-Tab. En outre, si j'utilise ICON_BIG mais que je charge l'icône 16x16, je n'obtiens aucun statut d'erreur, mais rien ne change.

Des idées sur ce qui pourrait causer l'échec de WM_SETICON? Quelque chose de terriblement mauvais avec le code que j'ai posté (en dehors des problèmes de formatage/style/casting, car il est simplifié à la base)?

Répondre

3

J'ai réexaminé ceci pour voir si je peux fermer ma question. J'ai été incapable d'afficher l'icône de l'application dans la liste alt-tab juste en l'intégrant dans l'exécutable; il apparaîtra dans la barre des tâches, comme l'icône du fichier dans l'Explorateur, et ailleurs tout va bien.

Je pensais que je vais essayer quelque chose de plus simple pour régler l'icône manuellement, et est allé avec LoadIcon() à la place, comme le code ci-dessous montre:

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

Cela semble avoir fait le tour. Je ne sais vraiment pas pourquoi, mais jusqu'ici c'est le seul changement qui a eu un effet. Ce n'est vraiment pas un problème sur lequel je devrais passer plus de temps, donc je vais aller avec ça.

+0

Je rencontre le même problème aujourd'hui. Malheureusement, cela ne fonctionne pas pour moi. Je dois chercher sur internet pour d'autres solutions. – Lothar

+0

La méthode 'LoadImage' fonctionne très bien pour moi d'afficher l'icône dans le menu' alt' + 'Tab' J'ai eu le problème où je ne mettais pas' LoadImage' 'BIG_ICON' à 32x32, une fois que je l'ai fait travaillé comme un charme. Voir: http://stackoverflow.com/a/24029664/1828637 – Noitidart

2

J'ai utilisé un seul fichier .ico avec plusieurs résolutions 16x16, 32x32, 48x48, 96x96 sans problèmes, comme icône de l'application. Ensuite, les fenêtres vont prendre la bonne taille.

Le shell Windows a un icon cache, il y a un trick pour le redémarrer sans redémarrer ou se déconnecter de la session en cours, ou pour supprimer le fichier explorer.exe du gestionnaire de tâches.

0

Si trouvé la solution pour moi. J'ai créé une fenêtre d'application CFrameWnd invisible, puis quelques autres fenêtres principales (qui sont des fenêtres de dialogue). La règle magique non documentée est: Vous devez changer la grande icône dans le premier CFrameWnd créé. Bien que chaque fenêtre conserve sa propre instance ICON_BIG, elle ne les utilise pas. Il semble donc impossible d'afficher différentes icônes de la barre des tâches pour différentes fenêtres à l'intérieur d'une même application.

2

OK, cela a fonctionné un régal pour moi:

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

Pour ceux qui viennent à cette même difficulté si vous allez changer ICON_BIG vous devez d'abord envoyer WM_SETICON avec ICON_SMALL puis passez à ICON_BIG.

Par exemple:

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] 

Vous devrez utiliser SetLastError après la première SendMessage pour effacer toute erreur renvoyée.

Si vous ne faites que définir ICON_SMALL, vous pouvez ignorer ICON_BIG. Pour quelque raison que ce soit dans tous mes tests, vous devez définir ICON_SMALL indépendamment du fait que cette icône doit changer ou non, avant d'essayer de changer ICON_BIG, sinon vous obtiendrez toujours le code d'erreur 0x6 (handle invalide).

Questions connexes