2009-04-01 12 views
6

(sto usando Visual Studio 2008, anche se mi ricordo di avere problemi simili con le versioni precedenti pure.)I problemi con l'impostazione icona dell'applicazione

Ho provato diversi metodi diversi (molti dei quali sono segnalati in this other question), ma sto ancora avendo alcuni strani problemi:

  1. Quando tra cui un'icona come una risorsa, lo fa apparire come l'icona del file eseguibile immediatamente, ma l'icona di presentarsi sulla barra delle applicazioni, devo riavviare il computer. Fino ad allora, continua a presentarsi come qualunque fosse l'icona precedente. Pulire la soluzione, riavviare VS, non ha alcun effetto. Non è un grosso problema, in quanto non influirà su un exe rilasciato, ma sarebbe bello sapere dove mantiene la vecchia icona memorizzata nella cache e come eliminarla.

  2. Indipendentemente da ciò che faccio, l'icona visualizzata quando alt-tab è l'icona predefinita dell'app (quadrata, bianca e generica). Ciò include l'incorporamento dell'icona nell'eseguibile e l'impostazione di ICON_BIG con WM_SETICON.

Per quanto riguarda il secondo punto, il mio codice sembra qualcosa di simile:

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

Tuttavia, dopo l'invio WM_SETICON, GetLastError() restituisce 6, "L'handle non è valido.". hWnd è un handle di finestra valido e hIcon sembra un handle di icone valido. Ho provato a cercare i motivi per cui WM_SETICON potrebbe causare quell'errore, e per lo meno, per capire chi lo gestisce pensa che non sia valido, ma ancora senza fortuna. Ho cancellato il codice di errore immediatamente prima di chiamare SendMessage(), quindi deve essere impostato da qualche parte nell'elaborazione del messaggio.

ho cercato un metodo alternativo, si carica l'icona dalla exe stesso, dove l'ID della risorsa è 101 (è la prima ed unica risorsa inclusa):

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

... ma la stessa cosa accade; dopo aver chiamato SendMessage(), GetLastError() fornisce lo stesso stato di errore.

Ho provato diverse dimensioni (come 48x48, che sono tutte presenti nel file icona), ma senza alcun effetto diverso. So che è sicuramente trovare e caricare le immagini, perché se si specifica una dimensione che non esiste o un ID risorsa non valido o il nome file sbagliato (a seconda di come lo sto caricando), fallisce molto prima dello SendMessage().

Stranamente, se specifico ICON_SMALL invece di ICON_BIG, la chiamata riesce senza stato di errore, ma da the docs, ho bisogno di usare ICON_BIG per impostare l'icona utilizzata mentre alt-tab. Inoltre, se uso ICON_BIG ma carico l'icona 16x16, non ottengo lo stato di errore, ma non cambia nulla.

Qualche idea su cosa potrebbe causare l'errore WM_SETICON? Qualcosa di terribilmente sbagliato con uno qualsiasi dei codici che ho postato (a parte i problemi di formattazione/stile/fusione, in quanto è semplificato solo alle basi)?

risposta

3

Ho rivisitato questo per vedere se riesco a chiudere la mia domanda. Non sono stato in grado di visualizzare l'icona dell'app nell'elenco alt-tab solo tramite l'incorporamento nell'eseguibile; verrà visualizzato nella barra delle applicazioni, come l'icona del file in Esplora risorse, e altrove va bene.

Ho pensato di provare qualcosa di più semplice per impostare l'icona manualmente, e se ne andò con LoadIcon() invece, come il codice qui sotto mostra:

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

Questo sembra aver fatto il trucco. Non so davvero perché, ma finora è l'unico cambiamento che ha avuto qualche effetto. Non è davvero un problema su cui dovrei dedicare altro tempo, quindi mi limiterò a farlo.

+0

Oggi mi imbatto nello stesso problema. Purtroppo questo non funziona per me. Devo cercare in internet altre soluzioni. – Lothar

+0

Il metodo 'LoadImage' funziona correttamente per me per mostrare l'icona nel menu' alt' + 'Tab' Ho avuto il problema in cui non ho impostato il' LoadImage' di 'BIG_ICON' su 32x32, una volta che l'ho fatto ha funzionato come un fascino. Vedi: http://stackoverflow.com/a/24029664/1828637 – Noitidart

2

Ho usato un singolo file .ico con risoluzioni multiple 16x16, 32x32, 48x48, 96x96 senza problemi, come icona dell'applicazione. Quindi le finestre prenderanno le dimensioni giuste.

Il guscio di windows ha un icon cache, c'è un trick per riavviarlo senza riavvio o disconnessione dalla sessione corrente, o killing explorer.exe dal task manager.

0

Se trovato la soluzione per me. Ho creato una finestra dell'applicazione CFrameWnd invisibile e poi alcune altre finestre principali (che sono finestre di dialogo). La regola magica non documentata è: Devi cambiare la grande icona nel primo CFrameWnd creato. Mentre ciascuna finestra mantiene la propria istanza ICON_BIG, non le usa. Quindi non sembra possibile mostrare diverse icone della barra delle applicazioni per finestre diverse all'interno di un'applicazione.

2

OK, questo ha funzionato a meraviglia per me:

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

per chi viene a questa stessa difficoltà, se avete intenzione di cambiare ICON_BIG è necessario inviare WM_SETICON con ICON_SMALL e quindi procedere a ICON_BIG.

Ad esempio:

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] 

Sarà necessario utilizzare SetLastError dopo la prima SendMessage per cancellare eventuali errori restituiti.

Se si imposta solo ICON_SMALL, è possibile ignorare ICON_BIG. Per qualsiasi ragione in tutti i miei test devi impostare ICON_SMALL indipendentemente dal fatto che quell'icona debba essere modificata o meno, prima di provare a cambiare ICON_BIG, altrimenti otterrai sempre il codice di errore 0x6 (handle non valido).