Recupero di informazioni sul contenuto di una cartella
La sezione Recupero dell'ID di una cartella ha illustrato due approcci per ottenere il puntatore di un oggetto dello spazio dei nomi a un elenco di identificatori di elemento (PIDL). Una domanda ovvia è: Una volta che hai un PIDL, cosa puoi fare con esso? Una domanda correlata è: Cosa accade se nessun approccio funziona o è adatto per l'applicazione? La risposta a entrambe le domande richiede un'analisi più attenta del modo in cui viene implementato lo spazio dei nomi. La chiave è l'interfaccia IShellFolder.
- Uso dell'interfaccia IShellFolder
- Enumerare il contenuto di una cartella
- Determinare i Nomi Visualizzati e Altre Proprietà
- Ottenere un puntatore all'interfaccia IShellFolder di una sottocartella
- Determinare la cartella padre di un oggetto
Uso dell'interfaccia IShellFolder
In precedenza in questa documentazione le cartelle dello spazio dei nomi venivano definite oggetti. Anche se, a quel punto, il termine è stato usato in senso libero, è in realtà vero anche in senso stretto. Ogni cartella dello spazio dei nomi è rappresentata da un oggetto COM (Component Object Model). Ogni oggetto cartella espone una serie di interfacce che possono essere usate per un'ampia gamma di attività. Alcune interfacce facoltative potrebbero non essere esposte da tutte le cartelle. Tuttavia, tutte le cartelle devono esporre l'interfaccia fondamentale, IShellFolder.
Il primo passaggio nell'uso di un oggetto cartella consiste nel recuperare un puntatore all'interfaccia IShellFolder. Oltre a fornire l'accesso alle altre interfacce dell'oggetto, IShellFolder espone un gruppo di metodi che gestiscono una serie di attività comuni, diverse delle quali sono descritte in questa sezione.
Per recuperare un puntatore all'interfaccia IShellFolder di un oggetto di spazio dei nomi, è necessario prima chiamare SHGetDesktopFolder. Questa funzione restituisce un puntatore all'interfaccia IShellFolder della radice dello spazio dei nomi, ovvero il desktop. Dopo aver ottenuto l'interfaccia IShellFolder del desktop, è possibile procedere in diversi modi.
Se si dispone già del PIDL della cartella a cui si è interessati, ad esempio chiamando SHGetFolderLocation, è possibile recuperarne l'interfaccia IShellFolder chiamando il metodo IShellFolder::BindToObjectdel desktop. Se si dispone del percorso di un oggetto file system, è prima necessario ottenere il relativo PIDL chiamando il metodo IShellFolder::ParseDisplayName del desktop e quindi chiamare IShellFolder::BindToObject. Se nessuno di questi approcci è applicabile, è possibile usare altri metodi IShellFolder per spostarsi nello spazio dei nomi. Per altre informazioni, vedere Esplorazione dello spazio dei nomi.
Enumerazione del contenuto di una cartella
La prima cosa che in genere si vuole fare con una cartella è scoprire cosa contiene. È prima necessario chiamare il metodo IShellFolder::EnumObjects della cartella. La cartella creerà un oggetto di enumerazione OLE standard e restituirà la relativa interfaccia IEnumIDList. Questa interfaccia espone quattro metodi standard,Clone, Next, Resete Skip, che possono essere usati per enumerare il contenuto della cartella.
La procedura di base per enumerare il contenuto di una cartella è:
- Chiamare il metodo IShellFolder::EnumObjects delle cartelle per recuperare un puntatore all'interfaccia IEnumIDList di un oggetto di enumerazione.
- Passare un PIDL non allocato a IEnumIDList::Next. Next si occupa dell'allocazione del PIDL, ma l'applicazione deve deallocarlo quando non è più necessario. Quando viene restituito Next, il PIDL conterrà solo l'ID dell'elemento dell'oggetto e i caratteri di terminazione NULL. In altre parole, si tratta di un PIDL a livello singolo, relativo alla cartella, non di un PIDL completo.
- Ripetere il passaggio 2 fino a Successivo restituisce S_FALSE per indicare che tutti gli elementi sono stati enumerati.
- Chiamare IEnumIDList::Release per rilasciare l'oggetto di enumerazione.
Nota
È importante tenere traccia del fatto che si stia lavorando con un PIDL completo o relativo. Alcune funzioni e metodi accetteranno entrambi, ma altri accetteranno solo uno o l'altro.
I tre metodi rimanenti IEnumIDList (Reset, Skipe Clone) sono utili se è necessario eseguire enumerazioni ripetute della cartella. Consentono di reimpostare l'enumerazione, ignorare uno o più oggetti e creare una copia dell'oggetto di enumerazione per conservarne lo stato.
Determinazione dei nomi visualizzati e di altre proprietà
Dopo aver enumerato tutti i PIDL contenuti in una cartella, è possibile scoprire quale tipo di oggetti rappresentano. L'interfaccia IShellFolder fornisce diversi metodi utili, due dei quali sono illustrati qui. Altri metodi IShellFolder e altre interfacce di cartella della shell vengono illustrati più avanti.
Una delle proprietà più utili è il nome visualizzato dell'oggetto. Per recuperare il nome visualizzato di un oggetto, passare il relativo PIDL a IShellFolder::GetDisplayNameOf. Anche se l'oggetto può trovarsi in un punto qualsiasi all'interno dello spazio dei nomi sotto la cartella padre, il relativo PIDL deve essere referito alla cartella.
IShellFolder::GetDisplayNameOf restituisce il nome visualizzato come parte di una struttura STRRET. Poiché l'estrazione del nome visualizzato da una struttura di STRRET può essere un po' complicata, la Shell fornisce due funzioni che si occupano di questo lavoro al posto tuo, StrRetToStr e StrRetToBuf. Entrambe le funzioni accettano una struttura STRRET e restituiscono il nome visualizzato come stringa normale. Differiscono solo per la modalità di allocazione della stringa.
Oltre al nome visualizzato, un oggetto può avere un numero di attributi, ad esempio se si tratta di una cartella o se può essere spostato. È possibile recuperare gli attributi di un oggetto passando il relativo PIDL a IShellFolder::GetAttributesOf. L'elenco completo degli attributi è piuttosto grande, quindi dovresti consultare il riferimento per i dettagli. Si noti che il PIDL passato a GetAttributesOf deve essere a livello singolo. In particolare, IShellFolder::GetAttributesOf accetterà i PIDL restituiti da IEnumIDList::Next. È possibile passare una matrice di PIDLs e GetAttributesOf restituirà gli attributi comuni a tutti gli oggetti della matrice.
Se si dispone di un percorso completo o PIDL di un oggetto, SHGetFileInfo offre un modo semplice per recuperare informazioni su un oggetto sufficiente per molti scopi. SHGetFileInfo accetta un percorso completo o un PIDL e restituisce un'ampia gamma di informazioni sull'oggetto, tra cui:
- Nome visualizzato dell'oggetto
- Attributi dell'oggetto
- Handle per le icone degli oggetti
- Puntatore alla lista delle immagini di sistema
- Percorso del file contenente l'icona dell'oggetto
Recupero di un puntatore all'interfaccia IShellFolder di una sottocartella
È possibile determinare se la cartella contiene sottocartelle chiamando IShellFolder::GetAttributesOf e verificando se è impostato il flag SFGAO_FOLDER. Se l'oggetto è una cartella, puoi associarti ad esso, il quale fornisce un puntatore alla relativa interfaccia IShellFolder.
Per eseguire l'associazione a una sottocartella, chiamare il metodo IShellFolder::BindToObject della cartella padre. Questo metodo accetta il PIDL della sottocartella e restituisce un puntatore all'interfaccia IShellFolder. Dopo aver creato questo puntatore, è possibile usare i metodi IShellFolder per enumerare il contenuto delle sottocartelle, determinarne le proprietà e così via.
Determinazione della cartella padre di un oggetto
Se si dispone del PIDL di un oggetto, potrebbe essere necessario un handle per una delle interfacce esposte dalla relativa cartella padre. Ad esempio, se si desidera determinare il nome visualizzato associato a un PIDL usando IShellFolder::GetDisplayNameOf, è prima necessario recuperare l'interfaccia IShellFolder dell'oggetto padre. È possibile eseguire questa operazione con le tecniche descritte nelle sezioni precedenti. Tuttavia, un approccio molto più semplice consiste nell'usare la funzione Shell, SHBindToParent. Questa funzione accetta il PIDL completo di un oggetto e restituisce un puntatore all'interfaccia specificato nella cartella padre. Facoltativamente, restituisce anche il PIDL a livello singolo dell'elemento da usare in metodi come IShellFolder::GetAttributesOf.
L'applicazione console di esempio seguente recupera il PIDL della cartella speciale System e ne restituisce il nome visualizzato.
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>
#include <objbase.h>
int main()
{
IShellFolder *psfParent = NULL;
LPITEMIDLIST pidlSystem = NULL;
LPCITEMIDLIST pidlRelative = NULL;
STRRET strDispName;
TCHAR szDisplayName[MAX_PATH];
HRESULT hr;
hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);
hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);
if(SUCCEEDED(hr))
{
hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);
hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));
cout << "SHGDN_NORMAL - " <<szDisplayName << '\n';
}
psfParent->Release();
CoTaskMemFree(pidlSystem);
return 0;
}
L'applicazione usa prima SHGetFolderLocation per recuperare il PIDL della cartella di sistema. Chiama quindi SHBindToParent, che restituisce un puntatore all'interfaccia IShellFolder della cartella padre e il PIDL della cartella System relativo al suo padre. Usa quindi il metodo IShellFolder::GetDisplayNameOf della cartella padre per recuperare il nome visualizzato della cartella System. Poiché GetDisplayNameOf restituisce una strutturaSTRRET, StrRetToBuf viene utilizzato per convertire il nome visualizzato in una stringa normale. Dopo aver visualizzato il nome visualizzato, i puntatori dell'interfaccia vengono rilasciati e il PIDL di sistema viene liberato. Si noti che non è necessario liberare il PIDL relativo restituito da SHBindToParent.