Implementazione delle interfacce oggetto cartella di base

La procedura per l'implementazione di un'estensione dello spazio dei nomi è simile a quella per qualsiasi altro oggetto COM (Component Object Model) in-process. Tutte le estensioni devono supportare tre interfacce principali che forniscono a Esplora risorse le informazioni di base necessarie per visualizzare le cartelle dell'estensione nella visualizzazione albero. Tuttavia, per sfruttare appieno le funzionalità di Esplora risorse, l'estensione deve anche esporre una o più interfacce facoltative che supportano funzionalità più sofisticate, ad esempio menu di scelta rapida o trascinamento della selezione, e fornire una visualizzazione cartelle.

Questo documento illustra come implementare le interfacce primarie e facoltative chiamate da Esplora risorse per informazioni sul contenuto dell'estensione. Per informazioni su come implementare una visualizzazione cartelle e su come personalizzare Esplora risorse, vedere Implementazione di una visualizzazione cartelle.

Implementazione e registrazione di base

Come server COM in-process, la DLL deve esporre diverse funzioni e interfacce standard:

Queste funzioni e interfacce vengono implementate nello stesso modo in cui sono per la maggior parte degli altri oggetti COM. Per informazioni dettagliate, vedere la documentazione COM.

Registrazione di un'estensione

Come per tutti gli oggetti COM, è necessario creare un GUID CLSID (Class Identifier) per l'estensione. Registrare l'oggetto creando una sottochiave di HKEY_CLASSES_ROOT\CLSID denominata per CLSID dell'estensione. La DLL deve essere registrata come server in-process e deve specificare il modello di threading apartment. È possibile personalizzare il comportamento della cartella radice di un'estensione aggiungendo un'ampia gamma di sottochiavi e valori alla chiave CLSID dell'estensione.

Molti di questi valori si applicano solo alle estensioni con punti di giunzione virtuale. Questi valori non si applicano alle estensioni i cui punti di giunzione sono cartelle di file system. Per altre informazioni, vedere Specifica del percorso di un'estensione dello spazio dei nomi. Per modificare il comportamento di un'estensione con un punto di giunzione virtuale, aggiungere uno o più dei valori seguenti alla chiave CLSID dell'estensione:

  • WantsFORPARSING. Il nome di analisi per un'estensione con un punto di giunzione virtuale avrà in genere il formato ::{GUID}. Le estensioni di questo tipo in genere contengono elementi virtuali. Tuttavia, alcune estensioni, ad esempio Documenti personali, corrispondono effettivamente alle cartelle del file system, anche se hanno punti di giunzione virtuali. Se l'estensione rappresenta gli oggetti del file system in questo modo, è possibile impostare il valore WantsFORPARSING. Esplora risorse richiederà quindi il nome di analisi della cartella radice chiamando il metodo IShellFolder::GetDisplayNameOf dell'oggetto cartella con uFlags impostato su SHGDN_FORPARSING e pidl impostato su un singolo puntatore vuoto a un elenco di identificatori di elemento (PIDL). Un PIDL vuoto contiene solo un carattere di terminazione. Il metodo deve quindi restituire il nome di analisi della cartella radice ::{GUID}.
  • HideFolderVerbs. I verbi registrati in HKEY_CLASSES_ROOT\Cartella normalmente sono associati a tutte le estensioni. Vengono visualizzati nel menu di scelta rapida dell'estensione e possono essere richiamati da ShellExecute. Per impedire che uno di questi verbi venga associato all'estensione, impostare il valore HideFolderVerbs.
  • HideAsDelete. Se un utente tenta di eliminare l'estensione, Esplora risorse nasconderà invece l'estensione.
  • HideAsDeletePerUser. Questo valore ha lo stesso effetto di HideAsDelete, ma per ogni utente. L'estensione è nascosta solo per gli utenti che hanno tentato di eliminarla. L'estensione è visibile a tutti gli altri utenti.
  • QueryForOverlay. Impostare questo valore per indicare che l'icona della cartella radice può avere una sovrapposizione di icone. L'oggetto cartella deve supportare l'interfaccia IShellIconOverlay . Prima che Esplora risorse visualizzi l'icona della cartella radice, richiederà un'icona di sovrimpressione chiamando uno dei due metodi IShellIconOverlay con pidlItem impostato su un PIDL vuoto.

I valori e le sottochiavi rimanenti si applicano a tutte le estensioni:

  • Per specificare il nome visualizzato della cartella del punto di giunzione dell'estensione, impostare il valore predefinito della sottochiave CLSID dell'estensione su una stringa appropriata.
  • Quando il cursore passa il puntatore su una cartella, viene in genere visualizzata una descrizione informazioni che descrive il contenuto della cartella. Per fornire una descrizione info per la cartella radice dell'estensione, creare un valore di InfoTip REG_SZ per la chiave CLSID dell'estensione e impostarlo su una stringa appropriata.
  • Per specificare un'icona personalizzata per la cartella radice dell'estensione, creare una sottochiave della sottochiave CLSID dell'estensione denominata DefaultIcon. Impostare il valore predefinito defaultIcon su un valore REG_SZ contenente il nome del file che contiene l'icona, seguito da una virgola, seguito da un segno meno, seguito dall'indice dell'icona nel file.
  • Per impostazione predefinita, il menu di scelta rapida della cartella radice dell'estensione conterrà gli elementi definiti in HKEY_CLASSES_ROOT\Cartella. Gli elementi Elimina, Rinomina e Proprietà vengono aggiunti se sono stati impostati i flag di SFGAO_XXX appropriati. È possibile aggiungere altri elementi al menu di scelta rapida della cartella radice o sostituire gli elementi esistenti, come si farebbe per un tipo di file. Creare una sottochiave shell sotto la chiave CLSID dell'estensione e definire i comandi come descritto in Estensione dei menu di scelta rapida.
  • Se è necessario un modo più flessibile per gestire il menu di scelta rapida della cartella radice, è possibile implementare un gestore di menu di scelta rapida. Per registrare il gestore del menu di scelta rapida, creare un tasto ShellEx sotto il tasto CLSID dell'estensione. Registrare il CLSID del gestore come si farebbe per un gestore di estensione della shell convenzionale.
  • Per aggiungere una pagina alla finestra delle proprietà Proprietà della cartella radice, assegnare alla cartella l'attributo SFGAO_HASPROPSHEET e implementare un gestore della finestra delle proprietà. Per registrare il gestore della finestra delle proprietà, creare una chiave ShellEx sotto la chiave CLSID dell'estensione. Registrare il CLSID del gestore come si farebbe per un gestore di estensione della shell convenzionale.
  • Per specificare gli attributi della cartella radice, aggiungere una sottochiave ShellFolder alla sottochiave CLSID dell'estensione. Creare un valore Attributes e impostarlo sulla combinazione appropriata di flag SFGAO_XXX.

Nella tabella seguente sono elencati alcuni attributi di uso comune per le cartelle radice.

Flag Valore Descrizione
SFGAO_FOLDER 0x20000000 La cartella radice dell'estensione contiene uno o più elementi.
SFGAO_HASSUBFOLDER 0x80000000 La cartella radice dell'estensione contiene una o più sottocartelle. Esplora risorse inserisce un segno più ( + ) accanto all'icona della cartella.
SFGAO_CANDELETE 0x00000020 La cartella radice dell'estensione può essere eliminata dall'utente. Il menu di scelta rapida della cartella avrà un elemento Elimina . Questo flag deve essere impostato per i punti di giunzione posizionati in una delle cartelle virtuali.
SFGAO_CANRENAME 0x00000010 La cartella radice dell'estensione può essere rinominata dall'utente. Il menu di scelta rapida della cartella avrà un elemento Rinomina .
SFGAO_HASPROPSHEET 0x00000040 La cartella radice dell'estensione ha una finestra delle proprietà Properties . Il menu di scelta rapida della cartella avrà una voce Proprietà . Per fornire la finestra delle proprietà, è necessario implementare un gestore della finestra delle proprietà. Registrare il gestore nella chiave CLSID dell'estensione, come descritto in precedenza.

 

L'esempio seguente mostra la voce del Registro di sistema CLSID per un'estensione con un nome visualizzato MyExtension. L'estensione ha un'icona personalizzata contenuta nella DLL dell'estensione con un indice pari a 1. Vengono impostati gli attributi SFGAO_FOLDER, SFGAO_HASSUBFOLDER e SFGAO_CANDELETE .

HKEY_CLASSES_ROOT
   CLSID
      {Extension CLSID}
         (Default) = MyExtension
         InfoTip = Some appropriate text
      DefaultIcon
         (Default) = c:\MyDir\MyExtension.dll,-1
      InProcServer32
         (Default) = c:\MyDir\MyExtension.dll
         ThreadingModel = Apartment
      ShellFolder
         Attributes = 0xA00000020

Gestione dei PIDL

Ogni elemento nello spazio dei nomi shell deve avere un PIDL univoco. Esplora risorse assegna un PIDL alla cartella radice e passa il valore all'estensione durante l'inizializzazione. L'estensione è quindi responsabile dell'assegnazione di un PIDL costruito correttamente a ognuno dei relativi oggetti e di fornire tali PIDLs a Esplora risorse su richiesta. Quando shell usa un FILE PIDL per identificare uno degli oggetti dell'estensione, l'estensione deve essere in grado di interpretare il FILE PIDL e identificare l'oggetto specifico. L'estensione deve anche assegnare un nome visualizzato e un nome di analisi a ogni oggetto. Poiché i PIDL vengono usati praticamente da ogni interfaccia di cartella, le estensioni in genere implementano un singolo gestore PIDL per gestire tutte queste attività.

Il termine PIDL è breve per una struttura ITEMIDLIST o un puntatore a tale struttura, a seconda del contesto. Come dichiarato, una struttura ITEMIDLIST ha un singolo membro, una struttura SHITEMID. La struttura ITEMIDLIST di un oggetto è in realtà una matrice compressa di due o più strutture SHITEMID. L'ordine di queste strutture definisce un percorso attraverso lo spazio dei nomi, nello stesso modo in cui c:\MyDirectory\MyFile definisce un percorso attraverso il file system. In genere, il PIDL di un oggetto sarà costituito da una serie di strutture SHITEMID che corrispondono alle cartelle che definiscono il percorso dello spazio dei nomi, seguito dalla struttura SHITEMID dell'oggetto, seguita da un terminatore.

Il terminatore è una struttura SHITEMID, con il membro cb impostato su NULL. Il carattere di terminazione è necessario perché il numero di strutture SHITEMID nel PIDL di un oggetto dipende dalla posizione dell'oggetto nello spazio dei nomi Shell e dal punto iniziale del percorso. Inoltre, le dimensioni delle varie strutture SHITEMID possono variare. Quando ricevi un PIDL, non hai modo semplice di determinarne le dimensioni o persino il numero totale di strutture SHITEMID . È invece necessario "camminare" la matrice compressa, struttura per struttura, fino a raggiungere il carattere di terminazione.

Per creare un FILE PIDL, l'applicazione deve:

  1. Creare una struttura SHITEMID per ognuno dei relativi oggetti.
  2. Assemblare le strutture SHITEMID pertinenti in un PIDL.

Creazione di una struttura SHITEMID

La struttura SHITEMID di un oggetto identifica in modo univoco l'oggetto all'interno della relativa cartella. Infatti, un tipo di PIDL usato da molti dei metodi IShellFolder è costituito solo dalla struttura SHITEMID dell'oggetto, seguita da un terminatore. La definizione di una struttura SHITEMID è:

typedef struct _SHITEMID { 
    USHORT cb; 
    BYTE   abID[1]; 
} SHITEMID, * LPSHITEMID;

Il membro abID è l'identificatore dell'oggetto. Poiché la lunghezza di abID non è definita e può variare, il membro cb viene impostato sulle dimensioni della struttura SHITEMID , in byte.

Poiché non è standardizzata né la lunghezza né il contenuto di abID , è possibile usare qualsiasi schema che si desidera assegnare valori abID agli oggetti. L'unico requisito è che non è possibile avere due oggetti nella stessa cartella con valori identici. Tuttavia, per motivi di prestazioni, la struttura SHITEMID deve essere allineata a DWORD. In altre parole, è necessario costruire i valori abID in modo che cb sia un multiplo integrale di 4.

In genere, abID punta a una struttura definita dall'estensione. Oltre all'ID dell'oggetto, questa struttura viene spesso utilizzata per contenere un'ampia gamma di informazioni correlate, ad esempio il tipo o gli attributi dell'oggetto. Gli oggetti cartella dell'estensione possono quindi estrarre rapidamente le informazioni dal FILE PIDL anziché eseguirne una query.

Nota

Uno degli aspetti più importanti della progettazione di una struttura di dati per un PIDL consiste nel rendere persistente e trasportabile la struttura. Nel contesto dei PIDL, il significato di questi termini è:

  • Persistente. Il sistema inserisce spesso PIDLs in vari tipi di archiviazione a lungo termine, ad esempio file di collegamento. Può quindi ripristinare questi PIDL dall'archiviazione in un secondo momento, possibilmente dopo il riavvio del sistema. Un FILE PIDL recuperato dall'archiviazione deve essere ancora valido e significativo per l'estensione. Questo requisito significa, ad esempio, che non è consigliabile usare puntatori o handle nella struttura PIDL. I PIDL contenenti questo tipo di dati normalmente non saranno significativi quando il sistema li recupera in un secondo momento dall'archiviazione.
  • Trasportabile. Un PIDL deve rimanere significativo quando viene trasportato da un computer a un altro. Ad esempio, un PIDL può essere scritto in un file di collegamento, copiato in un disco floppy e trasportato in un altro computer. Il PIDL deve comunque essere significativo per l'estensione in esecuzione nel secondo computer. Ad esempio, per assicurarsi che i PIDL siano trasportabili, usare caratteri ANSI o Unicode in modo esplicito. Evitare tipi di dati come TCHAR o LPTSTR. Se si usano questi tipi di dati, un PIDL creato in un computer che esegue una versione Unicode dell'estensione non sarà leggibile da una versione ANSI di tale estensione in esecuzione in un computer diverso.

 

La dichiarazione seguente illustra un semplice esempio di una struttura di dati.

typedef struct tagMYPIDLDATA {
  USHORT cb;
  DWORD dwType;
  WCHAR wszDisplayName[40];
} MYPIDLDATA, *LPMYPIDLDATA;

Il membro cb è impostato sulle dimensioni della struttura MYPIDLDATA . Questo membro rende MYPIDLDATA una struttura SHITEMID valida, in e di se stessa. Il resto dei membri equivale al membro abID di una struttura SHITEMID e contiene dati privati. Il membro dwType è un valore definito dall'estensione che indica il tipo di oggetto. Per questo esempio, dwType è impostato su TRUE per le cartelle e FALSE in caso contrario. Questo membro consente, ad esempio, di determinare rapidamente se l'oggetto è una cartella o meno. Il membro wszDisplayName contiene il nome visualizzato dell'oggetto. Poiché non si assegna lo stesso nome visualizzato a due oggetti diversi nella stessa cartella, il nome visualizzato funge anche da ID oggetto. In questo esempio wszDisplayName è impostato su 40 caratteri per garantire che la struttura SHITEMID sia allineata a DWORD. Per limitare le dimensioni dei PIDL, è invece possibile usare una matrice di caratteri a lunghezza variabile e regolare il valore di cb di conseguenza. Riempire la stringa di visualizzazione con un numero sufficiente di caratteri '\0' per mantenere l'allineamento DWORD della struttura. Altri membri che potrebbero essere utili per inserire nella struttura includono le dimensioni, gli attributi o il nome di analisi dell'oggetto.

Costruzione di un FILE PIDL

Dopo aver definito strutture SHITEMID per gli oggetti, è possibile usarle per costruire un FILE PIDL. I PIDL possono essere costruiti per diversi scopi, ma la maggior parte delle attività usa uno dei due tipi di PIDL. Il PIDL più semplice, a livello singolo, identifica l'oggetto relativo alla relativa cartella padre. Questo tipo di PIDL viene usato da molti dei metodi IShellFolder. Un PIDL a livello singolo contiene la struttura SHITEMID dell'oggetto, seguita da un terminatore. Un PIDL completo definisce un percorso attraverso la gerarchia dello spazio dei nomi dal desktop all'oggetto. Questo tipo di PIDL inizia sul desktop e contiene una struttura SHITEMID per ogni cartella nel percorso, seguita dall'oggetto e dal terminatore. Un FILE PIDL completo identifica in modo univoco l'oggetto all'interno dell'intero spazio dei nomi shell.

Il modo più semplice per costruire un PIDL consiste nell'usare direttamente la struttura ITEMIDLIST stessa. Creare una struttura ITEMIDLIST, ma allocare memoria sufficiente per contenere tutte le strutture SHITEMID. L'indirizzo di questa struttura punterà alla struttura SHITEMID iniziale. Definire i valori per i membri di questa struttura iniziale e quindi accodare tutte le strutture SHITEMID aggiuntive necessarie, nell'ordine appropriato. La procedura seguente illustra come creare un FILE PIDL a livello singolo. Contiene due strutture SHITEMID , una struttura MYPIDLDATA seguita da un terminatore:

  1. Usare la funzione CoTaskMemAlloc per allocare memoria per il PIDL. Allocare memoria sufficiente per i dati privati più USHORT (due byte) per il terminatore. Eseguire il cast del risultato in LPMYPIDLDATA.
  2. Impostare il membro cb della prima struttura MYPIDLDATA sulle dimensioni di tale struttura. Per questo esempio, si imposta cb su sizeof(MYPIDLDATA). Se si vuole usare una struttura a lunghezza variabile, è necessario calcolare il valore di cb.
  3. Assegnare valori appropriati ai membri dati privati.
  4. Calcolare l'indirizzo della struttura SHITEMID successiva. Eseguire il cast dell'indirizzo della struttura MYPIDLDATA corrente a LPBYTE e aggiungere tale valore al valore di cb determinato nel passaggio 3.
  5. In questo caso, la struttura SHITEMID successiva è il terminatore. Impostare il membro cb della struttura su zero.

Per i PIDL più lunghi, allocare memoria sufficiente e ripetere i passaggi da 3 a 5 per ogni struttura SHITEMID aggiuntiva.

La funzione di esempio seguente accetta il tipo e il nome visualizzato di un oggetto e restituisce il PIDL a livello singolo dell'oggetto. La funzione presuppone che il nome visualizzato, incluso il carattere Null di terminazione, non superi il numero di caratteri dichiarati per la struttura MYPIDLDATA. Se tale presupposto risulta errato, la funzione StringCbCopyW tronca il nome visualizzato. La variabile g_pMalloc è un puntatore IMalloc creato altrove e archiviato in una variabile globale.

LPITEMIDLIST CreatePIDL(DWORD dwType, LPCWSTR pwszDisplayName)
{
    LPMYPIDLDATA   pidlOut;
    USHORT         uSize;

    pidlOut = NULL;

    //Calculate the size of the MYPIDLDATA structure.
    uSize = sizeof(MYPIDLDATA);

    // Allocate enough memory for the PIDL to hold a MYPIDLDATA structure 
    // plus the terminator
    pidlOut = (LPMYPIDLDATA)m_pMalloc->Alloc(uSize + sizeof(USHORT));

    if(pidlOut)
    {
       //Assign values to the members of the MYPIDLDATA structure
       //that is the PIDL's first SHITEMID structure
       pidlOut->cb = uSize;
       pidlOut->dwType = dwType;
       hr = StringCbCopyW(pidlOut->wszDisplayName, 
                          sizeof(pidlOut->wszDisplayName), pwszDisplayName);
       
       // TODO: Add error handling here to verify the HRESULT returned 
       // by StringCbCopyW.

       //Advance the pointer to the start of the next SHITEMID structure.
       pidlOut = (LPMYPIDLDATA)((LPBYTE)pidlOut + pidlOut->cb);

       //Create the terminating null character by setting cb to 0.
       pidlOut->cb = 0;
    }

    return pidlOut;

Un PIDL completo deve avere strutture SHITEMID per ogni oggetto dal desktop all'oggetto. L'estensione riceve un FILE PIDL completo per la cartella radice quando shell chiama IPersistFolder::Initialize. Per costruire un PIDL completo per un oggetto, accettare il PIDL assegnato dalla shell alla cartella radice e aggiungere le strutture SHITEMID necessarie per passare dalla cartella radice all'oggetto .

Interpretazione di PIDLs

Quando shell o un'applicazione chiama una delle interfacce dell'estensione per richiedere informazioni su un oggetto, in genere identificherà l'oggetto da un PIDL. Alcuni metodi, ad esempio IShellFolder::GetUIObjectOf, usano IDLs relativi alla cartella padre e sono semplici da interpretare. Tuttavia, l'estensione riceverà probabilmente anche PIDLs completi. Il gestore PIDL deve quindi determinare a quali oggetti fa riferimento PIDL.

Ciò che complica l'attività di associazione di un oggetto a un PIDL completo è che una o più delle strutture SHITEMID iniziali nel PIDL potrebbero appartenere a oggetti che si trovano all'esterno dell'estensione nello spazio dei nomi Shell. Non hai modo di interpretare il significato del membro abID di tali strutture. Ciò che l'estensione deve fare è "camminare" l'elenco delle strutture SHITEMID , fino a raggiungere la struttura che corrisponde alla cartella radice. Da allora si saprà come interpretare le informazioni nelle strutture SHITEMID .

Per camminare sul PIDL, prendere il primo valore cb e aggiungerlo all'indirizzo del PIDL per avanzare il puntatore all'inizio della struttura SHITEMID successiva. Si punterà quindi al membro cb della struttura, che è possibile usare per avanzare il puntatore all'inizio della prossima struttura SHITEMID e così via. Ogni volta che si avanza il puntatore, esaminare la struttura SHITEMID per determinare se è stata raggiunta la radice dello spazio dei nomi dell'estensione.

Implementazione delle interfacce primarie

Come per tutti gli oggetti COM, l'implementazione di un'estensione è in gran parte una questione di implementazione di una raccolta di interfacce. Questa sezione illustra le tre interfacce principali che devono essere implementate da tutte le estensioni. Vengono usati per l'inizializzazione e per fornire a Esplora risorse informazioni di base sul contenuto dell'estensione. Queste interfacce, oltre a una visualizzazione cartelle, sono tutte necessarie per un'estensione funzionale. Tuttavia, per sfruttare completamente le funzionalità di Esplora risorse, la maggior parte delle estensioni implementa anche una o più interfacce facoltative.

Interfaccia IPersistFolder

L'interfaccia IPersistFolder viene chiamata per inizializzare un nuovo oggetto cartella. Il metodo IPersistFolder::Initialize assegna un PIDL completo al nuovo oggetto. Archiviare questo FILE PIDL per usarlo in un secondo momento. Ad esempio, un oggetto cartella deve usare questo CODICE PIDL per costruire PIDLs completi per gli elementi figlio dell'oggetto. L'autore dell'oggetto cartella può anche chiamare IPersist::GetClassID per richiedere il CLSID dell'oggetto.

In genere, un oggetto cartella viene creato e inizializzato dal metodo IShellFolder::BindToObject della cartella padre. Tuttavia, quando un utente accede all'estensione, Esplora risorse crea e inizializza l'oggetto cartella radice dell'estensione. Il PIDL ricevuto dall'oggetto cartella radice tramite IPersistFolder::Initialize contiene il percorso dal desktop alla cartella radice che sarà necessario costruire PIDLs completi per l'estensione.

Interfaccia IShellFolder

Shell considera un'estensione come una raccolta gerarchicamente ordinata di oggetti cartella. L'interfaccia IShellFolder è il nucleo di qualsiasi implementazione dell'estensione. Rappresenta un oggetto cartella e fornisce a Esplora risorse con molte delle informazioni necessarie per visualizzare il contenuto della cartella.

IShellFolder è in genere l'unica interfaccia di cartella diversa da IPersistFolder esposta direttamente da un oggetto cartella. Mentre Esplora risorse usa un'ampia gamma di interfacce obbligatorie e facoltative per ottenere informazioni sul contenuto della cartella, ottiene puntatori a tali interfacce tramite IShellFolder.

Esplora risorse ottiene il CLSID della cartella radice dell'estensione in diversi modi. Per informazioni dettagliate, vedere Specifica della posizione di un'estensione dello spazio dei nomi o visualizzazione di una visualizzazione autonoma di un'estensione dello spazio dei nomi. Esplora risorse usa quindi tale CLSID per creare e inizializzare un'istanza della cartella radice ed eseguire una query per un'interfaccia IShellFolder . L'estensione crea un oggetto cartella per rappresentare la cartella radice e restituisce l'interfaccia IShellFolder dell'oggetto. Gran parte del resto dell'interazione tra l'estensione e Esplora risorse viene quindi eseguita tramite IShellFolder. Esplora risorse chiama IShellFolder per:

  • Richiedere un oggetto in grado di enumerare il contenuto della cartella radice.
  • Ottenere vari tipi di informazioni sul contenuto della cartella radice.
  • Richiedere un oggetto che espone una delle interfacce facoltative. Tali interfacce possono quindi essere sottoposte a query per ottenere informazioni aggiuntive, ad esempio icone o menu di scelta rapida.
  • Richiedere un oggetto cartella che rappresenta una sottocartella della cartella radice.

Quando un utente apre una sottocartella della cartella radice, Esplora risorse chiama IShellFolder::BindToObject. L'estensione crea e inizializza un nuovo oggetto cartella per rappresentare la sottocartella e restituisce l'interfaccia IShellFolder . Esplora risorse chiama quindi questa interfaccia per vari tipi di informazioni e così via finché l'utente non decide di spostarsi altrove nello spazio dei nomi shell o chiudere Esplora risorse.

Nella parte restante di questa sezione vengono descritti brevemente i metodi IShellFolder più importanti e come implementarli.

EnumObjects

Prima di visualizzare il contenuto di una cartella nella visualizzazione albero, Esplora risorse deve prima determinare quale cartella contiene chiamando il metodo IShellFolder::EnumObjects. Questo metodo crea un oggetto di enumerazione OLE standard che espone un'interfaccia IEnumIDList e restituisce tale puntatore di interfaccia. L'interfaccia IEnumIDList consente a Esplora risorse di ottenere i PIDLs di tutti gli oggetti contenuti nella cartella. Questi PIDL vengono quindi usati per ottenere informazioni sugli oggetti contenuti nella cartella . Per altri dettagli, vedere Interfaccia IEnumIDList.

Nota

Il metodo IEnumIDList::Next deve restituire solo PIDLs relativi alla cartella padre. Il PIDL deve contenere solo la struttura SHITEMID dell'oggetto, seguita da un terminatore.

 

CreateViewObject

Prima di visualizzare il contenuto di una cartella, Esplora risorse chiama questo metodo per richiedere un puntatore a un'interfaccia IShellView . Questa interfaccia viene usata da Esplora risorse per gestire la visualizzazione cartelle. Creare un oggetto visualizzazione cartelle e restituire l'interfaccia IShellView .

Il metodo IShellFolder::CreateViewObject viene chiamato anche per richiedere una delle interfacce facoltative, ad esempio IContextMenu, per la cartella stessa. L'implementazione di questo metodo deve creare un oggetto che espone l'interfaccia richiesta e restituisce il puntatore all'interfaccia. Se Esplora risorse richiede un'interfaccia facoltativa per uno degli oggetti contenuti nella cartella, chiamerà IShellFolder::GetUIObjectOf.

GetUIObjectOf

Anche se le informazioni di base sul contenuto di una cartella sono disponibili tramite i metodi IShellFolder , l'estensione può anche fornire a Esplora risorse con vari tipi di informazioni aggiuntive. Ad esempio, è possibile specificare icone per il contenuto di una cartella o del menu di scelta rapida di un oggetto. Esplora risorse chiama il metodo IShellFolder::GetUIObjectOf per tentare di recuperare informazioni aggiuntive su un oggetto contenuto in una cartella. Esplora risorse specifica l'oggetto per cui desidera le informazioni e l'IID dell'interfaccia pertinente. L'oggetto folder crea quindi un oggetto che espone l'interfaccia richiesta e restituisce il puntatore dell'interfaccia.

Se l'estensione consente agli utenti di trasferire oggetti con trascinamento della selezione o degli Appunti, Esplora risorse chiamerà IShellFolder::GetUIObjectOf per richiedere un'interfaccia IDataObject o IDropTarget. Per informazioni dettagliate, vedere Trasferimento di oggetti shell con trascinamento della selezione e appunti.

Esplora risorse chiama IShellFolder::CreateViewObject quando vuole lo stesso tipo di informazioni sulla cartella stessa.

BindToObject

Esplora risorse chiama il metodo IShellFolder::BindToObject quando un utente tenta di aprire una delle sottocartelle dell'estensione. Se riid è impostato su IID_IShellFolder, è necessario creare e inizializzare un oggetto cartella che rappresenta la sottocartella e restituire l'interfaccia IShellFolder dell'oggetto.

Nota

Attualmente Esplora risorse chiama questo metodo solo per richiedere un'interfaccia IShellFolder . Tuttavia, non presupporre che questo sarà sempre il caso. È consigliabile controllare sempre il valore di riid prima di procedere.

 

GetDisplayNameOf

Esplora risorse chiama il metodo IShellFolder::GetDisplayNameOf per convertire il PIDL di uno degli oggetti della cartella in un nome. Tale PIDL deve essere relativo alla cartella padre dell'oggetto. In altre parole, deve contenere una singola struttura SHITEMID non NULL. Poiché esiste più di un modo possibile per denominare gli oggetti, Esplora risorse specifica il tipo di nome impostando uno o più flag SHGDNF nel parametro uFlags. Uno dei due valori, SHGDN_NORMAL o SHGDN_INFOLDER, verrà impostato per specificare se il nome deve essere relativo alla cartella o rispetto al desktop. Uno degli altri tre valori, SHGDN_FOREDITING, SHGDN_FORADDRESSBAR o SHGDN_FORPARSING, può essere impostato per specificare il nome da usare.

È necessario restituire il nome sotto forma di struttura STRRET. Se SHGDN_FOREDITING, SHGDN_FORADDRESSBAR e SHGDN_FORPARSING non sono impostati, restituire il nome visualizzato dell'oggetto. Se il flag SHGDN_FORPARSING è impostato, Esplora risorse richiede un nome di analisi. I nomi di analisi vengono passati a IShellFolder::P arseDisplayName per ottenere il PIDL di un oggetto, anche se potrebbe trovarsi uno o più livelli al di sotto della cartella corrente nella gerarchia dello spazio dei nomi. Ad esempio, il nome di analisi di un oggetto file system è il relativo percorso. È possibile passare il percorso completo di qualsiasi oggetto nel file system al metodo IShellFolder::P arseDisplayName del desktop e restituirà il PIDL completo dell'oggetto.

Mentre i nomi di analisi sono stringhe di testo, non devono necessariamente includere il nome visualizzato. È consigliabile assegnare nomi di analisi in base a ciò che funzionerà in modo più efficiente quando viene chiamato IShellFolder::P arseDisplayName. Ad esempio, molte delle cartelle virtuali della shell non fanno parte del file system e non dispongono di un percorso completo. A ogni cartella viene assegnato un GUID e il nome dell'analisi ha il formato ::{GUID}. Indipendentemente dallo schema usato, dovrebbe essere in grado di "round trip" in modo affidabile. Ad esempio, se un chiamante passa un nome di analisi a IShellFolder::P arseDisplayName per recuperare il PIDL di un oggetto e quindi passa tale PIDL a IShellFolder::GetDisplayNameOf con il flag SHGDN_FORPARSING impostato, il chiamante deve recuperare il nome di analisi originale.

GetAttributesOf

Esplora risorse chiama il metodo IShellFolder::GetAttributesOf per determinare gli attributi di uno o più elementi contenuti in un oggetto cartella. Il valore di cidl fornisce il numero di elementi nella query e aPidl punta a un elenco dei relativi PIDL.

Poiché il test per alcuni attributi può richiedere molto tempo, Esplora risorse limita in genere la query a un subset dei flag disponibili impostandone i valori in rfgInOut. Il metodo deve verificare solo gli attributi i cui flag sono impostati in rfgInOut. Lasciare impostati i flag validi e deselezionare il resto. Se nella query sono inclusi più elementi, impostare solo i flag che si applicano a tutti gli elementi.

Nota

Gli attributi devono essere impostati correttamente affinché un elemento venga visualizzato correttamente. Ad esempio, se un elemento è una cartella contenente sottocartelle, è necessario impostare il flag SFGAO_HASSUBFOLDER . In caso contrario, Esplora risorse non visualizzerà un elemento + accanto all'icona dell'elemento nella visualizzazione albero.

 

ParseDisplayName

Il metodo IShellFolder::P arseDisplayName è in qualche senso un'immagine mirror di IShellFolder::GetDisplayNameOf. L'uso più comune di questo metodo consiste nel convertire il nome di analisi di un oggetto nel PIDL associato. Il nome dell'analisi può fare riferimento a qualsiasi oggetto che si trova sotto la cartella nella gerarchia dello spazio dei nomi. Il PIDL restituito è relativo all'oggetto cartella che espone il metodo e in genere non è completo. In altre parole, anche se il PIDL può contenere diverse strutture SHITEMID , la prima sarà quella dell'oggetto stesso o la prima sottocartella nel percorso dalla cartella all'oggetto . Il chiamante dovrà aggiungere questo PIDL al PIDL completo della cartella per ottenere un PIDL completo per l'oggetto.

È anche possibile chiamare IShellFolder::P arseDisplayName per richiedere gli attributi di un oggetto. Poiché la determinazione di tutti gli attributi applicabili può richiedere molto tempo, il chiamante imposta solo i flag SFGAO_XXX che rappresentano informazioni a cui il chiamante è interessato. È necessario determinare quale di questi attributi è true per l'oggetto e cancellare i flag rimanenti.

Interfaccia IEnumIDList

Quando Esplora risorse deve enumerare gli oggetti contenuti in una cartella, chiama IShellFolder::EnumObjects. L'oggetto folder deve creare un oggetto di enumerazione che espone l'interfaccia IEnumIDList e restituire tale puntatore di interfaccia. Esplora risorse userà in genere IEnumIDList per enumerare i PIDLs di tutti gli oggetti contenuti nella cartella.

IEnumIDList è un'interfaccia di enumerazione OLE standard e viene implementata nel modo consueto. Tenere presente, tuttavia, che i PIDL restituiti devono essere relativi alla cartella e contenere solo la struttura SHITEMID dell'oggetto e un terminatore.

Implementazione delle interfacce facoltative

Esistono diverse interfacce della shell facoltative che gli oggetti cartella dell'estensione possono supportare. Molti di essi, ad esempio IExtractIcon, consentono di personalizzare vari aspetti del modo in cui l'utente visualizza l'estensione. Altri, ad esempio IDataObject, consentono all'estensione di supportare funzionalità come il trascinamento della selezione.

Nessuna delle interfacce facoltative viene esposta direttamente da un oggetto cartella. Esplora risorse chiama invece uno dei due metodi IShellFolder per richiedere un'interfaccia:

  • Esplora risorse chiama IShellFolder::GetUIObjectOf di un oggetto cartella per richiedere un'interfaccia per uno degli oggetti contenuti nella cartella.
  • Esplora risorse chiama IShellFolder::CreateViewObject di un oggetto cartella per richiedere un'interfaccia per la cartella stessa.

Per fornire le informazioni, l'oggetto folder crea un oggetto che espone l'interfaccia richiesta e restituisce il puntatore all'interfaccia. Esplora risorse chiama quindi tale interfaccia per recuperare le informazioni necessarie. In questa sezione vengono illustrate le interfacce facoltative più usate.

IExtractIcon

Esplora risorse richiede un'interfaccia IExtractIcon prima di visualizzare il contenuto di una cartella. L'interfaccia consente all'estensione di specificare icone personalizzate per gli oggetti contenuti nella cartella. In caso contrario, verranno usate le icone di file e cartelle standard. Per fornire un'icona personalizzata, creare un oggetto di estrazione icona che espone IExtractIcon e restituire un puntatore a tale interfaccia. Per altre informazioni, vedere la documentazione di riferimento di IExtractIcon o Creazione di gestori icona.

IContextMenu

Quando un utente fa clic con il pulsante destro del mouse su un oggetto, Esplora risorse richiede un'interfaccia IContextMenu . Per fornire menu di scelta rapida per gli oggetti, creare un oggetto gestore menu e restituire la relativa interfaccia IContextMenu .

Le procedure per la creazione di un oggetto gestore menu sono molto simili a quelle usate per creare un'estensione shell del gestore di menu. Per informazioni dettagliate, vedere Creazione di gestori di menu di scelta rapida o informazioni di riferimento su IContextMenu, IContextMenu2 o IContextMenu3.

IQueryInfo

Esplora risorse chiama l'interfaccia IQueryInfo per recuperare una stringa di testo della descrizione informazioni.

IDataObject e IDropTarget

Quando gli oggetti vengono visualizzati da Esplora risorse, un oggetto cartella non ha modo diretto di sapere quando un utente sta tentando di tagliare, copiare o trascinare un oggetto. Esplora risorse richiede invece un'interfaccia IDataObject . Per consentire il trasferimento dell'oggetto, creare un oggetto dati e restituire un puntatore alla relativa interfaccia IDataObject .

Analogamente, un utente potrebbe tentare di eliminare un oggetto dati in una rappresentazione di Esplora risorse di uno degli oggetti, ad esempio un'icona o un percorso della barra degli indirizzi. Esplora risorse richiede quindi un'interfaccia IDropTarget . Per consentire l'eliminazione dell'oggetto dati, creare un oggetto che espone un'interfaccia IDropTarget e restituire il puntatore all'interfaccia.

La gestione del trasferimento dei dati è uno degli aspetti più complessi della scrittura delle estensioni dello spazio dei nomi. Per una discussione dettagliata, vedere Trasferimento di oggetti shell con trascinamento della selezione e appunti.

Utilizzo dell'implementazione della visualizzazione cartella shell predefinita

Le origini dati che usano l'oggetto visualizzazione cartella shell predefinita (DefView) devono implementare queste interfacce:

Facoltativamente, possono implementare anche IPersistFolder3.