Programmazione
BETACopertinaSommarioInternet IDInformazioniBrowserGuida
BETA
Clicca qui per maggiori informazioni

Sommario
Internet ID
Indici di BETA
Redazione
Mailing list
Installazione
Mirror ufficiali
Licenza Pubbl. Beta
Cerca
Stampa





BETA sul Web
Beta.it:
Menu Settori e sezioni

I piddle del namespace

Questo è il primo di una serie di articoli che riguardano la possibilità di estendere le funzionalità della shell di Windows 95 e di NT 4.0. I concetti presentati non sono dei più facili da capire, per cui non scoraggiatevi se all'inizio tutto sembrerà molto oscuro: quando avremo finito il buio sarà pesto! 
  

di Stefano Casini 
Articolista Senior, BETA   


[Inizio articolo]Introduzione 

Sono passati ormai piu' di tre anni dall'avvento di Windows 95; questi, per quanto si sia rivelato fragile in alcuni suoi componenti, ed abbia generato sentimenti di odio da parte dei puristi informatici, sta diventando lo standard di fatto dei sistemi operativi per PC, e lo sara' almeno per 4 o 5 anni, almeno finche' si arrivera' alla fusione di 95 (o 98) con NT. Senza voler entrare nel merito delle altre componenti del sistema operativo, vogliamo esaminare quella parte che ha contribuito al successo di 95, ovvero l'interfaccia grafica che si presenta all'utente, indubbiamente gradevole all'occhio e funzionale nell'uso, e passare in rassegna i modi che permettono di estenderne le funzionalita'. 
Come tutti (o quasi) sapranno, il modulo eseguibile che si occupa di gestire l'interfaccia di Windows 95 con l'utente si chiama explorer.exe, e si trova nella cartella in cui viene installato Windows; in realta' explorer.exe (che d'ora in poi chiameremo semplicemente Explorer, piuttosto che Gestione Risorse come nella traduzione italiana) non lavora da solo, ma viene aiutato da alcune Dynamic Link Library (DLL) e dal registro di Windows (registry): infatti viene implementata un'architettura client-server, dove Explorer accede, in seguito ad un evento che si verifica nel sistema (per esempio il click con il mouse su un'icona del desktop), al registry, legge qual e' la DLL che si occupa di gestire quel tipo di evento per quel particolare tipo di icona, quindi chiama alcune interfacce standardizzate presenti nella DLL che eseguono il lavoro (per esempio quello di far aprire un menu' contestuale che contiene alcune voci piuttosto che altre).  Le interfacce esposte dalla DLL sono di tipo COM (Component Object Model), e chiunque abbia avuto a che fare con COM e' perfettamente convinto che piu' che un acronimo COM sia l'abbreviazione di COMPLICATO. Per rendere la cosa piu' interessante il campo d'azione di Explorer non e' limitato ai soli file o directory, ma comprende anche gli oggetti virtuali (folder ed item, come ad esempio la cartella virtuale Risorse del computer, o gli oggetti virtuali quali le connessioni di Accesso Remoto); l'insieme degli oggetti fisici e di quelli virtuali prende il nome di namespace, ed ogni oggetto (folder o item) all'interno del namespace e' individuato da un PIDL (pointer to item identifier list). 
Prima di procedere oltre giova ricordare che Explorer e' la shell di Windows 95, ma non e' Windows 95, anche se si tende ad identificare l'uno con l'altro; pertanto i pregi ed i difetti di Explorer non vanno ad inficiare quelle che sono altre caratteristiche importanti di un sistema operativo, quali la gestione del file system, delle porte di comunicazione, etc., e volendo Explorer puo' essere sostituito con un'altra shell, quale ad esempio il vecchio Program Manager, o scritta magari da terze parti. 
 

[Inizio articolo]Il namespace 

Il namespace corrisponde praticamente al file system, solamente che incorpora anche gli oggetti virtuali, ossia quegli item che non hanno una corrispondenza con un preciso file o directory sul disco fisso. Se nel disco fisso la radice del file system e' la root directory (\), nel namespace di Explorer la radice e' il folder virtuale Desktop, ma attenzione: se esplorate il namespace di Windows 95, troverete due Desktop, uno che e' il folder virtuale (ed e' quello presente al livello di gerarchia piu' alta nella combobox che si trova nella toolbar delle finestre di Explorer), l'altro che e' una directory, situata nella directory di Windows, al cui interno sono contenuti i file reali che avete sulla vostra scrivania. Per fare un esempio, il Desktop virtuale contiene oggetti virtuali quali Risorse del computer, Risorse di rete, il Cestino, ecc., oltre ai file ed ai collegamenti a file che si trovano nella directory windows\desktop; e, se ancora non si e' capito, la radice del namespace e' il folder virtuale e non la directory! 
Un folder e' un contenitore di item del namespace; questi item possono essere a loro volta dei folder, oppure degli oggetti virtuali o dei file; in genere, ciascun folder puo' contenere solo un ben determinato tipo di oggetti; ogni tipo di folder e' un oggetto COM che sa come enumerare il proprio contenuto e le azioni da intraprendere in seguito agli eventi; ed e' l'unico nel namespace a conoscere queste cose, perche' il namespace e' gerarchico, dove il padre conosce solo i propri figli ma non ha alcuna informazione sui nipoti. Ogni item di un folder viene univocamente identificato, all'interno del folder che lo contiene, da un item identifier (ID), mentre il medesimo item puo' essere identificato, sempre in maniera univoca, a partire dalla radice del namespace (il Desktop), mediante una item identifier list (IDL). Nella programmazione delle estensioni di Explorer, si usa spesso il puntatore alla lista degli item identifier (PIDL), per gli amici piddle
 

[Inizio articolo]Il piddle, questo sconosciuto 

Ogni item identifier (ID) viene individuato da una semplice struttura, la SHITEMID, cosi' definita: 
typedef struct _SHITEMID 
{   // mkid 
    USHORT cb;       // size of identifier, including cb itself 
    BYTE   abID[1];  // variable length item identifier 
} SHITEMID, * LPSHITEMID; 
formata da un campo che ne dichiara la lunghezza, e da un campo a lunghezza variabile che ne identifica il contenuto; il campo con la lunghezza ha come valore la lunghezza dell'array di BYTE adID piu'  il sizeof(USHORT) (vedi fig. 1). 

fig. 1 
Figura 1 
 
La lista degli ID viene implementata con il vecchio trucco di concatenare una dopo l'altra piu' strutture di tipo SHITEMID, terminandola con una in cui il campo cb ha valore zero (ed adID non c'e'); questa la definizione della struttura ITEMIDLIST: 

typedef struct _ITEMIDLIST 
{       // idl 
        SHITEMID mkid;  // list of item identifers 
} ITEMIDLIST, * LPITEMIDLIST; 
 
La lista si puo' percorrere esaminando il campo cb di ogni SHITEMID, fermandosi quando troviamo il valore zero (deve essere uno zero a 16 bit) (vedi fig. 2). 

fig. 2 
Figura 2 
 
Ad esempio: 
 
0 7 P I P P O
rappresenta un item identifier
 
0 6 A L D O
rappresenta  un altro item identifier
 
0 9 R O N A L D O
rappresenta un terzo item identifier
 
0 7 P I P P O 0 6 A L D O 0 9 R O N A L D O 0 0
rappresenta la item identifier list ottenuta concatenando i tre ID.

In questo caso abbiamo messo negli ID delle stringhe, ma il contenuto puo' essere una qualsiasi forma binaria, il cui significato e' noto solo al folder padre degli ID. 
Notate bene: la IDL deve sempre essere terminata da uno zero a 16 bit
La memoria per i puntatori alle item identifier list (PIDL), poiche' questi puntatori vengono passati attraverso le interfacce COM della shell, deve essere allocata usando l'apposita interfaccia di COM, la IMalloc, oppure la "helper function" SHGetMalloc. Usare le classiche funzioni di Win32 quali GlobalAlloc puo' portare a risultati disastrosi. 
I piddle possono essere catalogati in vari modi: 
Relativo - e' il PIDL che specifica in maniera univoca un oggetto all'interno di un certo folder del namespace; 
Assoluto - e' il PIDL che specifica in maniera univoca un oggetto rispetto all'intero namespace; 
Semplice - la item identifier list contiene solo un item identifier; 
Complesso - la item identifier list contiene piu' di un item identifier. 
 

[Inizio articolo]Cosa si trova dentro ai piddle? 

Per rispondere, esaminiamo alcuni dei piddle piu' comuni che troviamo nel nostro namespace, ricordando pero' che, a seconda del folder padre che contiene gli item, nel piddle ci si puo' trovare di tutto, da stringhe, a numeri binari, record o campi di database, tutto quello che passava per la mente al programmatore che ha implementato il folder; gli esempi presentati pertanto sono molto limitativi, utili piu' che altro a scopo didattico. 
Partiamo dal nostro Desktop, e andiamo a vedere il piddle di Risorse del computer (a proposito, per leggere i piddle bisogna scriversi un programma che li legga, non esistono comandi diretti della shell di 95); per risparmiare spazio e fatica, nel seguito omettero' i due byte a zero che terminano il piddle, ma ricordate che in realta' ci devono SEMPRE essere. Otteniamo quanto segue (in esadecimale): 
 
byte valore
0 14
1 0
2 1F
3 0
4 E0
5 4F
6 D0
7 20
8 EA
9 3A
A 69
B 10
C A2
D D8
E 8
F 0
10 2B
11 30
12 30
13 9D
 

I primi 2 byte rappresentano la lunghezza del piddle (in questo caso e' pari a 20 byte). I 2 byte successivi rappresentano un numeretto magico (1Fh), il cui significato e' noto solo ad Explorer, ma che possiamo ipotizzare significhi che l'oggetto e' un folder virtuale. I 16 byte successivi rappresentano l'identificatore della classe cui appartiene Risorse del computer, che ritroviamo nel registry di Windows, sotto la chiave: HKEY_CLASSES_ROOT/CLSID/{20D04FE0-3AEA-1069-A2D8-08002B30309D}; quando interagiamo con il mouse sull'icona Risorse del computer, Explorer apre il registry alla chiave suddetta, la espande e va a leggere qual'e' il server da chiamare per gestire le azioni (in questo caso e' shell32.dll); inoltre, nelle varie sottochiavi, trova altre informazioni sull'icona di default, etc. 
Vediamo ora il piddle del Cestino
 
byte valore
0 14
1 0
2 1F
3 0
4 40
5 F0
6 5F
7 64
8 81
9 50
A 1B
B 10
C 9F
D 8
E 0
F AA
10 0
11 2F
12 95
13 4E
 
In questo caso vediamo che anche il Cestino e' un folder, il cui CLSID e' {645FF040-5081-101B-9F08-00AA002F954E}; dal registry vediamo le icone usate per segnalarne lo stato di "full" o "empty", il server e' sempre shell32.dll, infine il che Cestino aggiunge delle estensioni autonome alla gestione sia della finestra delle proprieta', sia dei propri menu' contestuali. 
Concludiamo con il piddle del folder di Accesso Remoto
 
byte valore
0 14
1 0
2 1F
3 0
4 A0
5 FF
6 2C
7 99
8 57
9 F5
A 1A
B 10
C 88
D EC
E 0
F DD
10 1
11 C
12 CC
13 48
 
IL CLSID di Accesso Remoto e' {992CFFA0-F557-101A-88EC-00DD010CCC48}, il suo server e' rnaui.dll, che ne fornisce pure l'icona che vediamo mostrata sul Desktop. La sottochiave ShellFolder ci segnala che e' possibile creare dei link al folder di Accesso Remoto
Passiamo a vedere ora il piddle di un file che mi trovo sul Desktop, e precisamente di un file .lnk che fa da collegamento a Powerpnt.exe: 
 
byte valore
0 2E
1 0
2 32
3 0
4 38
5 1
6 0
7 0
8 E9
9 24
A A4
B 3B
C 20
D 0
E 50 P
F 6F o
10 77 w
11 65 e
12 72 r
13 50 P
14 6F o
15 69 i
16 6E n
17 74 t
18 20
19 34 4
1A 2E .
1B 30 0
1C 2E .
1D 6C l
1E 6E n
1F 6B k
20 0
21 50 P
22 4F O
23 57 W
24 45 E
25 52 R
26 50 P
27 7E ~
28 32 2
29 2E .
2A 4C L
2B 43 N
2C 4B K
2D 0
 
Stavolta il piddle e' lungo 47 byte, il numeretto magico e' cambiato (32h invece di 1Fh), ad indicare che non si tratta piu' di un folder ma di un file, e cambiano anche le informazioni contenute nel piddle: i byte da 4h a 7h contengono la lunghezza del file (138h equivalgono a 312, la dimensione del file), i byte da 8h a Bh contengono la data di ultima modifica del file (9 agosto 1998, ore 07.29.08; curioso come l'ora riportata sia quella assoluta del meridiano zero, mentre la finestra delle proprieta' del file mostra l'ora corrispondente al nostro fuso orario e tiene conto anche dell'ora legale, riportando percio' le 9); il byte Ch contiene gli attributi del file (il valore 20h significa che e' un file archivio; ricordiamo che 0h e' un file normale, 1h e' a sola lettura, 2h e' nascosto, 4h di sistema, 10h directory); il byte successivo dovrebbe contenere informazioni sugli attributi estesi del file; infine, il piddle contiene in successione il nome lungo (PowerPoint 4.0.lnk) ed il nome DOS (POWERP~2.LNK) del file. 
Dopo aver scoperto che, per una directory, le cose sono uguali ai file, tranne che il numeretto magico vale 31h, ed il piddle contiene valori zero nei byte della dimensione, osserviamo il piddle di un file che punta ad una applicazione DOS (l'orario dei treni), ovvero un .pif; e' uno di quei tipi di file di cui Explorer non mostra mai l'estensione nelle proprie finestre, come i .lnk ed i .url (per curiosita' provate a cercare nel registry la parola "NeverShowExt"). 
 
byte valore
0 1B
1 0
2 32
3 0
4 C7
5 3
6 0
7 0
8 F8
9 24
A BA
B B3
C 20
D 80
E 49 I
F 6E n
10 66 f
11 6F o
12 74 t
13 72 r
14 61 a
15 2E .
16 70 p
17 69 i
18 66 f
19 0
1A 0
 
Da notare la comparsa al byte Dh di un attributo esteso, a differenza dei file "normali", e la mancanza del nome DOS del file; purtroppo non sono in grado, al momento, di spiegarne le ragioni; trovare documentazione sull'architettura interna di Explorer e' impossibile ai comuni mortali. 
Quelli esaminati erano piddle semplici, relativi al folder virtuale Desktop (e quindi, allo stesso tempo, assoluti, poiche' Desktop e' la radice del namespace); vediamo adesso un esempio di piddle contenuto in un folder diverso, per esempio quello relativo ad una connessione di Accesso Remoto
 
byte valore
0 14
1 0
2 1F
3 0
4 E0
5 4F
6 D0
7 20
8 EA
9 3A
A 69
B 10
C A2
D D8
E 8
F 0
10 2B
11 30
12 30
13 9D
14 14
15 0
16 2E
17 0
18 A0
19 FF
1A 2C
1B 99
1C 57
1D F5
1E 1A
1F 10
20 88
21 EC
22 0
23 DD
24 1
25 C
26 CC
27 48
28 19
29 0
2A 0
2B 0
2C 2
2D 0
2E 0
2F 0
30 1
31 0
32 0
33 0
34 0
35 0
36 0
37 0
38 54 T
39 49 I
3A 4E N
3B 20
3C 52 R
3D 6F o
3E 6D m
3F 61 a
40 0
 
Si tratta di un piddle complesso ed assoluto, perche' identifica l'oggetto rispetto alla radice del namespace; riconosciamo il primo ID, lungo 20 byte, ed e' proprio il folder Risorse del computer; ad esso segue, lungo la lista degli ID, un altro folder, anche questo gia' visto, ed e' il folder di Accesso Remoto; notiamo che il numero magico (byte 16h) non vale piu' 1Fh come in precedenza, ma 2Eh; questo perche' nel primo caso il folder padre di Risorse del computer e' il Desktop, nel secondo caso il folder padre di Accesso Remoto e' Risorse del computer, ed ogni padre ha un diverso modo di chiamare i figli. Chiude la lista un ID di 25 byte, che contiene, oltre a 15 byte di significato oscuro per noi ma non per Accesso Remoto, il nome della connessione (TIN Roma). Giova ricordare che le connessioni di Accesso Remoto sono degli oggetti virtuali, e che non troverete sul vostro hard disk un file che gli corrisponde. 
Per finire, ecco il piddle del file fisico c:\windows\winfile.exe, ovvero File Manager
 
byte valore
0 14
1 0
2 1F
3 0
4 E0
5 4F
6 D0
7 20
8 EA
9 3A
A 69
B 10
C A2
D D8
E 8
F 0
10 2B
11 30
12 30
13 9D
14 19
15 0
16 23
17 43 C
18 3A :
19 5C \
1A 0
1B 0
1C 0
1D 0
1E 0
1F 0
20 0
21 0
22 0
23 0
24 0
25 0
26 0
27 0
28 0
29 0
2A 0
2B 11
2C EE
2D 17
2E 0
2F 31
30 0
31 0
32 0
33 0
34 0
35 8B
36 21
37 B5
38 AA
39 10
3A 80
3B 57 W
3C 69 i
3D 6E n
3E 64 d
3F 6F o
40 77 w
41 73 s
42 0
43 0
44 1B
45 0
46 32
47 0
48 A0
49 65
4A 2
4B 0
4C 18
4D 21
4E 60
4F 51
50 20
51 80
52 57 W
53 69 i
54 6E n
55 66 f
56 69 i
57 6C l
58 65 e
59 2E .
5A 65 e
5B 78 x
5C 65 e
5D 0
5E 0
 
Riconosciamo nuovamente i primi 20 byte come il CLSID di Risorse del computer, cui seguono 25 byte che identificano il drive C; quindi 23 byte individuano la directory Windows (come si riconosce dal numero magico 31h posto nel byte 2Fh, dagli zeri nei byte della dimensione, dal valore 10 nel byte 39h), che possiede un attributo esteso di valore 80h nel byte 40h; infine 27 byte identificano il file all'interno della directory (numero magico 32h, dimensione del file nei byte da 48h a 4Bh, file di tipo archivio come ci dice il byte 50h, attributo esteso nel byte 51h). 
Insomma, dopo questi esempi, dovrebbe essere un po' piu' chiaro il ruolo che hanno i piddle nel sostituire i pathname, rispetto al classico file system, nel namespace di Explorer. 
 
 

[Inizio articolo]Le API che usano i piddle 

Abbiamo detto che per estendere le funzionalita’ di Explorer bisogna ricorrere alle interfacce COM, che non sono il massimo della semplicita’. Esistono pero’ alcune funzioni dell’API di Windows95 che permettono ad un’applicazione di eseguire specifici task che hanno a che fare con la shell bypassando l’utilizzo di COM. Queste “helper function” sono riconoscibili poiche’ hanno il prefisso SH nel nome. 
Di queste funzioni alcune accettano un piddle come parametro, o lo restituiscono; in quest’ultimo caso, bisogna ricordarsi che la memoria referenziata dal piddle restituito, una volta che non serve piu’, deve essere liberata usando il task allocator della shell. Per fortuna, esiste l’helper function SHGetMalloc, che permette di recuperare il puntatore all’interfaccia IMalloc senza fare troppa fatica; la funzione sotto riportata puo’ essere usata per liberare la memoria allocata dalle funzioni della shell. 
 
void LiberaMemoriaConMalloc(void * pMemoria)
{
        LPMALLOC pMalloc;

        // controlliamo che il puntatore non sia NULL
        if(!pMemoria)
               return;

        // recuperiamo il puntatore all’interfaccia IMalloc
        SHGetMalloc(&pMalloc);

        // usiamo il metodo Free dell’interfaccia per liberare la memoria
        pMalloc->Free(pMemoria);

        // rilasciamo l’interfaccia IMalloc
        pMalloc->Release();
}
Vediamo adesso un po’ di queste funzioni: 
 
WINSHELLAPI void WINAPI SHAddToRecentDocs(UINT  uFlags, LPCVOID pv);
Questa funzione permette di aggiungere un documento alla lista dei Dati recenti che compare sul menu Avvio; i parametri sono due: 
UINT uFlags
puo' assumere valore SHARD_PATH o SHARD_PIDL, e' un flag indicante il significato del secondo parametro passato alla funzione; 
LPCVOID pv
e' il puntatore al blocco di memoria che contiene il pathname da aggiungere alla lista, nel caso in cui uFlags valga SHARD_PATH, oppure il puntatore ad una struttura ITEMIDLIST contenente l'identificatore del documento all'interno del namespace, nel caso in cui uFlags valga SHARD_PIDL. Se pv e' NULL, la funzione azzera la lista dei Dati recenti
 
WINSHELLAPI BOOL WINAPI SHGetPathFromIDList(LPCITEMIDLIST  pidlLPSTR  pszPath);
Questa funzione permette di convertire una lista di item identifier (IDL) nel pathname equivalente del file system; i parametri sono due:
LPCITEMIDLIST  pidl
e’ il puntatore ad una IDL che specifica la posizione di un file o di una directory rispetto alla radice del namespace (piddle assoluto);
LPSTR  pszPath
e’ il puntatore al buffer che riceve il pathname; la funzione fa affidamento sul fatto che il buffer sia grande MAX_PATH byte, per cui ricordatevi di allocarlo di questa misura.
Naturalmente, se l’oggetto individuato dal piddle non fa parte del file system, la funzione fallisce e ritorna FALSE; negli altri casi viene riempito il buffer pszPath con il pathname del file e la funzione ritorna TRUE.
 
WINSHELLAPI HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, \
  int nFolder, LPCITEMIDLIST * ppidl);
Questa funzione permette di recuperare il piddle di uno dei folder "speciali" di Windows 95: questi sono sia i folder virtuali di sistema (Desktop, Pannellodi Controllo, Stampanti, Risorse di rete, Risorse del computer, Cestino), sia le directory che si trovano nel registry sotto la chiave HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders; i parametri sono tre:
HWND hwndOwner
e' l'handle ad una finestra che eventualmente mostra una dialog box o una message box;
int nFolder
e'un numero che specifica quale folder "speciale" recuperare; i valori previsti sono:
CSIDL_BITBUCKET - Cestino
CSIDL_CONTROLS - Pannello di controllo
CSIDL_DESKTOP - Folder virtuale Desktop
CSIDL_DESKTOPDIRECTORY - Directory Desktop
CSIDL_DRIVES - Risorse del computer
CSIDL_FONTS - Folder virtuale Font
CSIDL_NETHOOD - Directory Risorse di rete
CSIDL_NETWORK - Folder virtuale Risorse di rete
CSIDL_PERSONAL - Directory Preferiti
CSIDL_PRINTERS - Folder virtuale Stampanti
CSIDL_PROGRAMS - Directory Programmi
CSIDL_RECENT - Directory Recent
CSIDL_SENDTO - Directory SendTo
CSIDL_STARTMENU - Directory Menu Avvio
CSIDL_STARTUP - Directory Esecuzione Automatica
CSIDL_TEMPLATES - Directory ShellNew
LPCITEMIDLIST * ppidl
e' il puntatore che verra' riempito in uscita dal piddle assoluto che individua all'interno del namespace il folder "speciale" specificato dal parametro precedente. La funzione se ha successo ritorna il valore NOERROR.
 
WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder(LPBROWSEINFO lpbi);
Questa funzione mostra una dialog box che permette all'utente di selezionare un folder (virtuale o meno).
LPBROWSEINFO lpbi
e' il puntatore ad una struttura BROWSEINFO; tra i suoi campi c'e'
LPCITEMIDLIST pidlRoot
che viene riempito in entrata con il piddle della locazione del namespace che fungera' da radice per la finestra di dialogo; questo significa che l'utente della dialog box non potra' risalire al folder padre del pidlRoot, ovvero potra' navigare solo nella parte di namespace sottostante pidlRoot. Se pidlRoot ha valore NULL, la dialog box usera' come radice il folder virtuale Desktop. La dialog box e' personalizzabile tramite una funzione callback, il cui indirizzo viene riportato in uno dei campi della struttura BROWSEINFO, e si puo' indicare se la scelta del folder deve essere limitata solo a particolari tipi di folder (ad esempio solo i computer, solo le stampanti, solo le directory del file system, ecc.). Se si seleziona un folder e si preme il pulsante OK la funzione ritorna il piddle del folder selezionato, che ricordiamo deve essere deallocato una volta che non serve piu'; se invece si preme il pulsante Annulla la funzione ritorna NULL.
 
WINSHELLAPI DWORD WINAPI SHGetFileInfo(LPCTSTR pszPath, DWORD dwFileAttributes,
SHFILEINFO FAR * psfi, UINT cbFileInfo, UINT uFlags);
Questa funzione recupera informazioni su di un oggetto del file system, sia esso un disco, una directory o un file.
LPCTSTR pszPath
punta ad un buffer che contiene il pathname dell'oggetto. Se uFlags contiene il flag SHGFI_PIDL allora pszPath deve essere un puntatore alla ITEMIDLIST che individua univocamente l'oggetto all'interno del namespace;
DWORD dwFileAttributes
contiene l'indicazione degli attributi del file di cui richiediamo le informazioni. Questo campo e' valido solo se uFlags contiene il flag SHGFI_USEFILEATTRIBUTES;
SHFILEINFO FAR * psfi
e' il puntatore ad una struttura di tipo SHFILEINFO, che ricevera' le informazioni sul file;
UINT cbFileInfo
contiene la dimensione, in byte, della struttura SHFILEINFO;
UINT uFlags
in questo parametro si specificano i flag su quali informazioni recuperare dal file; i valori previsti sono:
SHGFI_ATTRIBUTES - recupera gli attributi del file e li mette nel campo dwAttributes della struttura puntata da psfi
SHGFI_DISPLAYNAME - recupera il display name del file e lo mette nel campo szDisplayName della struttura puntata da psfi
SHGFI_EXETYPE - la funzione ritorna il tipo di eseguibile (.COM, .BAT, .EXE per DOS, Win 16 bit o Win 32 bit) se il file e' un eseguibile
SHGFI_ICON - recupera l'handle dell'icona che rappresenta il file e l'indice dell'icona all'interno della image list di sistema. Copia queste informazioni nei campi hIcon e iIcon della struttura puntata da psfi
SHGFI_ICONLOCATION - recupera il pathname del file che contiene l'icona che rappresenta il file e lo mette nel campo szDisplayName della struttura puntata da psfi
SHGFI_LARGEICON - modifica il flag SHGFI_ICON
SHGFI_LINKOVERLAY - modifica il flag SHGFI_ICON
SHGFI_OPENICON - modifica il flag SHGFI_ICON
SHGFI_PIDL - specifica che pszPath e' un piddle invece che un pathname
SHGFI_SELECTED - modifica il flag SHGFI_ICON
SHGFI_SHELLICONSIZE - modifica il flag SHGFI_ICON
SHGFI_SMALLICON - modifica il flag SHGFI_ICON
SHGFI_SYSICONINDEX - recupera l'indice dell'icona all'interno della image list di sistema e lo mette nel campo iIcon della struttura puntata da psfi
SHGFI_TYPENAME - recupera la stringa che descrive il tipo di file, e la copia nel campo szTypeName della struttura puntata da psfi
SHGFI_USEFILEATTRIBUTES - indica che la funzione deve usare il parametro dwFileAttributes
Il valore ritornato dalla funzione dipende dal tipo di flag settati col parametro uFlags: se il flag e' SHGFI_EXETYPE il valore di ritorno contiene il tipo di eseguibile; se il flag contiene SHGFI_ICON o SHGFI_SYSICONINDEX il valore di ritorno e' l'handle all'image list di sistema che contiene l'icona; negli altri casi la funzione ritorna TRUE se ha successo, FALSE se fallisce.
 

[Inizio articolo]Conclusioni 

Abbiamo visto che attraverso il namespace Explorer allarga il classico file system agli oggetti virtuali, e come ogni oggetto del namespace sia identificato da una item identifier list (IDL), che corrisponde ad un "pathname virtuale". Per alcuni oggetti (virtuali e non) del namespace abbiamo anche visto come e' strutturata la IDL che li rappresenta, sempre tenendo conto che il significato di ogni ID e' perfettamente noto solo al folder che lo contiene. L'implementazione dei folder e degli oggetti avviene attraverso le interfacce COM di Explorer, interfacce che possono essere derivate usando DLL esterne che ne estendono le funzionalita' o creano nuove classi di folder. Le IDL vengono passate attraverso le interfacce COM usando i puntatori (PIDL), familiarmente chiamati piddle; esistono alcune "helper funcions" dell'API di Win32 che permettono di lavorare sui piddle senza passare per le interfacce COM, facilitando cosi' il lavoro al programmatore. Descritto il funzionamento di alcune di queste funzioni, rimane solo da presentare una semplice applicazione corredata di sorgenti che le utilizza: battezzata FASTDIR, permette attraverso il suo menu di accedere direttamente ad alcuni dei folder "speciali" di Explorer, e di esplorarne il namespace sottostante, nonche' di azzerare il contenuto del menu Avvio->Dati recenti. Il sorgenti possono essere compilati con Visual C++ 4.0 e versioni successive, mentre chi non ha il compilatore puo' comunque utilizzare l'eseguibile (naturalmente solo su Windows95 o NT4).
La prossima volta parleremo delle piu' volte citate interfacce COM di Explorer.


Stefano Casini, ingegnere, è Articolista di BETA dal 1995 e svolge un lavoro che non ha nulla a che fare con la programmazione; è raggiungibile su Internet tramite la redazione oppure all'indirizzo etngh@tin.it 

Copyright © 1998 Stefano Casini, tutti i diritti sono riservati. Questo Articolo di BETA, insieme alla Rivista, è distribuibile secondo i termini e le condizioni della Licenza Pubblica Beta, come specificato nel file LPB


BETA Rivista | Copertina | Sommario | InternetID | Informazioni | Browser
BETA Sul Web: http://www.beta.it

Copertina Sommario Internet ID Informazioni Browser
Home Page BETA Rivista Indice Articoli Beta Editore, articoli e pubblicazioni Beta2, contributi esterni BETA Logo, siti premiati Premio BETA Logo Licenza Article/Document Definition Format Promozione Pubblicita' Mirroring Mirror Ufficiali BETA Navigatore NavSearch Novità BETA Stampa/Press Releases BETA Settori online Eventi Public Bookstore (libreria) Settori riservati Redazione