Condividi tramite


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

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 dell'uso di un oggetto cartella consiste nel recuperare un puntatore alla relativa 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 dello spazio dei nomi, è prima necessario chiamare SHGetDesktopFolder. Questa funzione restituisce un puntatore all'interfaccia IShellFolder della radice dello spazio dei nomi, 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 recuperare la relativa interfaccia IShellFolder chiamando il metodo IShellFolder::BindToObject del desktop. Se si dispone del percorso di un oggetto file system, è prima necessario ottenere il relativo PIDL chiamando il metodo IShellFolder::P arseDisplayName 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à l'interfaccia IEnumIDList . Questa interfaccia espone quattro metodi standard, ovvero Clone, Next, Reset e Skip, che possono essere usati per enumerare il contenuto della cartella.

La procedura di base per enumerare il contenuto di una cartella è:

  1. Chiamare il metodo IShellFolder::EnumObjects delle cartelle per recuperare un puntatore all'interfaccia IEnumIDList di un oggetto di enumerazione.
  2. Passare un PIDL non allocato a IEnumIDList::Next. Successivamente si occupa dell'allocazione del PIDL, ma l'applicazione deve deallocarla quando non è più necessaria. Al termine, il CODICE PIDL conterrà solo l'ID elemento dell'oggetto e i caratteri NULL di terminazione. In altre parole, si tratta di un PIDL a livello singolo, relativo alla cartella, non di un PIDL completo.
  3. Ripetere il passaggio 2 fino a quando Next restituisce S_FALedizione Standard per indicare che tutti gli elementi sono stati enumerati.
  4. 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, ma altri accettano solo uno o l'altro.

 

I tre metodi IEnumIDList rimanenti (Reset, Skip e 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 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 sotto la cartella padre nello spazio dei nomi, il relativo CODICE PIDL deve essere relativo alla cartella.

IShellFolder::GetDisplayNameOf restituisce il nome visualizzato come parte di una struttura STRRET . Poiché l'estrazione del nome visualizzato da una struttura STRRET può risultare leggermente complessa, shell fornisce due funzioni che eseguono automaticamente il processo, 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 dovrebbe essere visualizzato il riferimento per i dettagli. Si noti che il PIDL passato a GetAttributesOf deve essere a livello singolo. In particolare, IShellFolder::GetAttributesOf accetterà i PIDLs 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 PIDL e restituisce un'ampia gamma di informazioni sull'oggetto, tra cui:

  • Nome visualizzato dell'oggetto
  • Attributi dell'oggetto
  • Handle per le icone dell'oggetto
  • Handle per l'elenco di 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 il flag SFGAO_FOLDER è impostato. Se un oggetto è una cartella, è possibile associarlo, che 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 alla relativa 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, è necessario recuperare prima l'interfaccia IShellFolder dell'elemento padre dell'oggetto. È 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 innanzitutto 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 rispetto al relativo padre. Usa quindi il metodo IShellFolder::GetDisplayNameOf della cartella padre per recuperare il nome visualizzato della cartella System. Poiché GetDisplayNameOf restituisce una struttura STRRET, StrRetToBuf viene usato per convertire il nome visualizzato in una stringa normale. Dopo aver visualizzato il nome visualizzato, i puntatori dell'interfaccia vengono rilasciati e il FILE PIDL di sistema viene liberato. Si noti che non è necessario liberare il PIDL relativo restituito da SHBindToParent.