Newsgroup: it.comp.programmare.win32
Titolo: [Win32 API] - Come recuperare le icone di sistema, piccole?

Ciao, nel mio codice MFC uso la LoadIcon per aggiungere alla mia ImageList
le icone di sistema:
m_ImgListSmall->Add(LoadIcon(NULL, IDI_WARNING));
m_ImgListSmall->Add(LoadIcon(NULL, IDI_INFORMATION));
l'ImageList e'
associata ad un CListCtrl, ho notato che le icone che ricavo sono quelle in
formato 32*32 pixel, perche' se dimensiono l'ImageList a 32*32, quando
mostro gli Item del CListCtrl in modalita' LargeIcon, le icone sono quelle
giuste, ma in modalita' report o SmallIcon e con l'ImageList settata a
16*16, le icone sono di qualita' scadente. In sostanza, la LoadIcon
restituisce le icone 32*32.
Sapete come fare a recuperare le icone
piccole?
Su MSDN ho letto che al posto di LoadIcon ora bisognerebbe
usare la LoadImage, ma non ho visto alcun parametro che mi permetta di
decidere quale icona caricare.
A proposito, c'e' un modo di ricavare a
RunTime l'icona del cestino (a volte pieno, a volte vuoto)? In generale, se
volessi recuperare un icona di sistema quale quella della cartella "My
Pictures" o "My Documents", come faccio?
Grazie, ciao e buon lavoro,
Davide.
--------------------------------
Inviato via 
http://usenet.iol.it


Ti riporto quanto ho trovato su MSDN per il tuo 1° quesito:
SUMMARY
Under Windows 95, Windows 98, Windows NT 4.0, and Windows 2000, each
application is associated with two icons: a small icon (16x16) and a large
icon (32x32). The small icon is displayed in the upper-left hand corner of
the application and on the taskbar.
MORE INFORMATION
Large and small icons are associated with an application by using the
RegisterClassEx() function. This function takes a pointer to a WNDCLASSEX
structure. The WNDCLASSEX structure is similar to the WNDCLASS structure
except for the addition of the hIconSm parameter, which is used for the
handle to the small icon. If no small icon is associated with an
application, Windows 95 will use a 16x16 representation of the large icon.
NOTE: RegisterClassEx() is not currently implemented in Windows NT where it
returns NULL.
The LoadIcon() function loads the large icon member of an icon resource. To
load the small icon, use the new LoadImage() function as follows:
   LoadImage(  hInstance,
               MAKEINTRESOURCE(<icon identifier>),
               IMAGE_ICON,
               16,
               16,
               0);
The small icon currently associated with the application will be displayed
in the upper-left corner of the application's main window and on the task
bar. Both the large and the small icon association can be changed at runtime
by using the WM_SETICON message.
By default, the start menu will display the first icon defined in an
application's resources. This can be changed through the start menu property
sheets.
Explorer displays the first defined icon in an application's resources
unless the application adds an entry to the registry under the program
information called DefaultIcon or defines an icon handler shell extension
for the file type. Refer to the Shell Extension documentation for more
information on shell extensions.
Porlock.

               0);
Chiamando LoadImage in questo modo:
HICON
hIcon = (HICON) LoadImage(0, MAKEINTRESOURCE(IDI_WINLOGO), IMAGE_ICON, 16,
16, 0);
o in questo modo:
HICON hIcon = (HICON)
LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_WINLOGO), IMAGE_ICON,
16, 16, 0);
il valore di hIcon e' zero, per cui la LoadImage sembra
incapace di recuperare le icone predefinite.
ti ricordo che sto cercando
di "acchiappare" le icone di sistema, ovvero, quelle dichiarate in questo
modo nel file winuser.h:
#define IDI_APPLICATION     32512
#define
IDI_HAND            32513
#define IDI_QUESTION        32514
#define
IDI_EXCLAMATION     32515
#define IDI_ASTERISK        32516
#if(WINVER >=
0x0400)
#define IDI_WINLOGO         32517
#endif /* WINVER >= 0x0400 */
#else
#define IDI_APPLICATION     MAKEINTRESOURCE(32512)
#define IDI_HAND
MAKEINTRESOURCE(32513)
#define IDI_QUESTION        MAKEINTRESOURCE(32514)
#define IDI_EXCLAMATION     MAKEINTRESOURCE(32515)
#define IDI_ASTERISK
MAKEINTRESOURCE(32516)
#if(WINVER >= 0x0400)
#define IDI_WINLOGO
MAKEINTRESOURCE(32517)
#endif /* WINVER >= 0x0400 */
#endif /* RC_INVOKED
*/
#if(WINVER >= 0x0400)
#define IDI_WARNING     IDI_EXCLAMATION
#define IDI_ERROR       IDI_HAND
#define IDI_INFORMATION IDI_ASTERISK
Ho provato ed eliminare la chiamata a MAKEINTRESOURCE, pensando che fosse
superflua visto che e' gia' presente nella dichiarazione delle icone, ma
ottengo sempre un HICON nullo, uffa!!!



[...]
Hai provato ad utilizzare il flag LR_SHARED ?
HICON hIcon = (HICON) LoadImage(0, MAKEINTRESOURCE(IDI_WINLOGO), IMAGE_ICON,
16,16, LR_SHARED);
nella documentazione dice che se si tenta di caricare un'icona di sistema
senza specificare LR_SHARED la funzione fallisce.
Porlock.

 Pictures" o "My Documents", come faccio?
Ho trovato su MSDN un altro articolo interessante:
PRB: System Image List Does Not Contain Overlay Images
Q192055
dove oltre al problema specifico trattato dall'articolo è riportato quanto
segue:
You can obtain the handle to the system image list with a function call
similar to the following:
   HIMAGELIST  himl;
   SHFILEINFO  sfi;
   himl = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi,
      sizeof(SHFILEINFO), SHGFI_SYSICONINDEX);
On Windows 95 and Windows 98, this function returns the handle of the actual
system image list.
Per il resto ti rimando all'articolo. Comunque in questa maniera puoi
ottenere la lista delle immagini di sistema, che non è proprio ciò che
volevi tu ma può tornarti utile.
In alternativa ho provato a giocare un po' con le funzioni della SHELL e per
ottenere l'icona (piccola) del RecycleBin ho trovato questo modo:
SHFILEINFO shfi;
ZeroMemory(&shfi,sizeof(SHFILEINFO));
LPITEMIDLIST pPIDL = NULL;
LPMALLOC pMal=NULL;
SHGetMalloc(&pMal);
SHGetSpecialFolderLocation(NULL,CSIDL_BITBUCKET,&pPIDL);
SHGetFileInfo((LPCSTR)pPIDL,0,&shfi,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_SMAL
LICON|SHGFI_PIDL);
pMal->Free(pPIDL);
Brevemente con la funzione SHGetSpecialFolderLocation ottengo l'itemidlist
del cestino. Attraverso varie costanti puoi ottenere anche l'itemidlist
della cartella documenti. Comunque leggiti bene la documentazione sull'MSDN
poiché non tutte le costanti sono disponibili su tutti i S.O. Windows, e
alcune per poter essere utilizzate necessitano dell'installazione di una
libreria aggiuntiva (shfolder.dll mi pare).
Poi attraverso SHGetFileInfo ottengo l'icona piccola del cestino; anche qui
sono disponibili diverse costanti per ottenere varie informazioni.
L'handle dell'icona si trovao nella struttura SHFILEINFO :
typedef struct _SHFILEINFO{
    HICON hIcon;
    int   iIcon;
    DWORD dwAttributes;
    TCHAR szDisplayName[MAX_PATH];
    TCHAR szTypeName[80];
} SHFILEINFO;
Nel mio esempio non ho distrutto l'icona ottenuta, non credo che in
Windows95/98 sia lecito distruggere un'icona di sistema.
E' possibile che invece sotto NT tu ottenga invece una copia dell'icona, e
che quindi poi tu debba distruggerlo.
Sono particolari che dovrai approfondire.
Come ti dicevo con queste poche righe ho ottenuto un handle all'icona del
cestino e poi ho provveduto a visualizzarla su un controllo static.
Ciao
Porlock.