2009-04-01 11 views
6

(Ich bin mit Visual Studio 2008, obwohl ich auch ähnliche Probleme mit älteren Versionen mit Speichern.)Probleme mit der Einstellung Anwendungssymbol

ich verschiedene Methoden (viele von ihnen in this other question erwähnt) versucht haben, aber ich habe immer noch einige seltsame Fragen:

  1. Wenn ein Symbol als Ressource einschließlich, es zeigt auf, als die ausführbare Datei des Symbol sofort, aber für das Symbol in der Taskleiste zeigen, muss ich neu starten der Computer. Bis dahin zeigt es sich immer noch als das, was das vorherige Symbol war. Das Reinigen der Lösung und das Neustarten von VS haben keine Auswirkungen. Kein wirklich großes Problem, da es sich nicht auf eine freigegebene Exe auswirken wird, aber es wäre schön zu wissen, wo es das alte Icon im Cache hält und wie man es loswird.

  2. Egal was ich mache, das Symbol wird angezeigt, wenn Alt-Tabbing das Standard-App-Symbol ist (quadratisch und weiß und generisch). Dazu gehört das Einbetten des Symbols in die ausführbare Datei sowie das Festlegen von ICON_BIG mit WM_SETICON.

Was die zweite Frage, sieht mein Code so etwas wie:

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

jedoch nach dem Senden WM_SETICON, GetLastError() kehrt 6, "Der Griff ist ungültig.". hWnd ist ein gültiges Fensterhandle und hIcon scheint ein gültiges Symbolhandle zu sein. Ich habe versucht, nach Gründen zu suchen, warum WM_SETICON diesen Fehler verursachen konnte, und mindestens, um herauszufinden, welcher Griff es denkt, ist ungültig, aber noch kein Glück. Ich habe den Fehlercode sofort vor dem Aufruf SendMessage() gelöscht, so dass es irgendwo in der Verarbeitung der Nachricht festgelegt werden muss.

Ich habe versucht, ein alternatives Verfahren, das Symbol aus der exe selbst Laden, in dem die ID der Ressource 101 (es das erste und einzige Ressource ist im Lieferumfang enthalten):

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

... aber die gleiche Sache das passiert; Nach dem Aufruf SendMessage() gibt GetLastError() den gleichen Fehlerstatus.

Ich habe verschiedene Dimensionen (wie 48x48, die alle in der Symboldatei vorhanden sind) ausprobiert, aber zu keinen anderen Effekt. Ich weiß, dass es die Bilder definitiv findet und lädt, weil, wenn ich eine Größe gebe, die nicht existiert, oder eine ungültige Betriebsmittelidentifikation oder der falsche Dateiname (abhängig davon, wie ich es lade) es lange vor SendMessage() ausfällt.

Seltsam, wenn ich ICON_SMALL statt ICON_BIG angeben, ist der Aufruf erfolgreich ohne Fehlerstatus, sondern von the docs, ich brauche ICON_BIG zu verwenden, um das Symbol, während Alt-Tab verwendet einzustellen. Wenn ich ICON_BIG verwende, aber das 16x16 Icon lade, bekomme ich keinen Fehlerstatus, aber nichts ändert sich.

Irgendwelche Ideen über das, was WM_SETICON zum Scheitern bringen könnte? Alles, was mit dem Code, den ich gepostet habe, schrecklich falsch ist (abgesehen von Formatierungs-/Stil-/Casting-Problemen, da es nur auf die Grundlagen vereinfacht wird)?

Antwort

3

Ich habe dieses wieder besucht, um zu sehen, ob ich meine Frage abschließen kann. Ich konnte das Symbol der App nicht in der Alt-Tab-Liste anzeigen lassen, sondern einfach in die ausführbare Datei einbetten. Es wird in der Taskleiste angezeigt, als das Symbol der Datei im Explorer und anderswo in Ordnung.

Ich dachte, ich etwas einfacher für die Einstellung das Symbol manuell versuchen würde, und ging mit LoadIcon() statt, wie der folgende Code zeigt:

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

Dieser den Trick getan zu haben scheint. Ich weiß wirklich nicht warum, aber bis jetzt ist es die einzige Veränderung, die irgendeinen Effekt hatte. Es ist wirklich kein Thema, für das ich mehr Zeit aufwenden sollte, also werde ich einfach damit fortfahren.

+0

Ich laufe auf das gleiche Problem heute. Leider funktioniert das nicht für mich. Ich muss im Internet nach anderen Lösungen suchen. – Lothar

+0

Die 'LoadImage' Methode funktioniert gut, um das Icon im' alt' + 'Tab' Menü zu zeigen. Ich hatte das Problem, dass ich' 'LoadImage'' BIG_ICON'' nicht auf 32x32 setzte, nachdem ich das gemacht habe Lief wie am Schnürchen. Siehe: http://stackoverflow.com/a/24029664/1828637 – Noitidart

2

Ich habe eine einzelne .ico-Datei mit mehreren Auflösungen 16x16, 32x32, 48x48, 96x96 ohne Probleme, als Anwendungssymbol verwendet. Dann werden Fenster die richtige Größe aufnehmen.

Die Windows-Shell haben eine icon cache, gibt es eine trick, um es ohne Neustart oder Abmeldung von der aktuellen Sitzung neu zu starten, oder explorer.exe vom Task-Manager zu töten.

0

Wenn die Lösung für mich gefunden. Ich habe ein unsichtbares CFrameWnd-Anwendungsfenster und dann einige andere Hauptfenster (das sind Dialogfenster) erstellt. Die magische undokumentierte Regel lautet: Sie müssen das große Symbol im ersten erstellten CFrameWnd ändern. Während jedes Fenster seine eigene ICON_BIG-Instanz behält, verwendet es sie nicht. Daher scheint es nicht möglich, verschiedene Taskleistensymbole für verschiedene Fenster in einer Anwendung anzuzeigen.

2

OK, arbeitete diese eine Belohnung für mich:

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

Für alle diese gleichen Schwierigkeiten kommen, wenn Sie ICON_BIG ändern wollen, müssen Sie zuerst WM_SETICON mit ICON_SMALL schicken und dann zu ICON_BIG fortzufahren.

Zum Beispiel:

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] 

Sie müssen SetLastError verwenden, nachdem die ersten Sendmessage jeden zurück Fehler zu löschen.

Wenn Sie nur ICON_SMALL einstellen, können Sie ICON_BIG ignorieren. Aus irgendeinem Grund in allen meinen Tests müssen Sie ICON_SMALL einstellen, unabhängig davon, ob das Symbol geändert werden muss oder nicht, bevor Sie versuchen, ICON_BIG zu ändern, sonst erhalten Sie immer den Fehlercode 0x6 (ungültiges Handle).