Condividi tramite


Inizializzazione dei gestori dell'estensione shell

Gran parte dell'implementazione di un oggetto gestore estensioni shell è dettata dal relativo tipo. Esistono tuttavia alcuni elementi comuni. In questo argomento vengono illustrati gli aspetti dell'implementazione condivisi da tutti i gestori di estensione shell.

Tutti i gestori di estensione Shell sono oggetti COM (Component Object Model) in-process. Devono essere assegnati a un GUID e registrati come descritto in Registrazione dei Gestori dell'estensione shell. Vengono implementati come DLL e devono esportare le funzioni standard seguenti:

  • DllMain. Punto di ingresso standard per la DLL.
  • DllGetClassObject. Espone la class factory dell'oggetto.
  • DllCanUnloadNow. COM chiama questa funzione per determinare se l'oggetto sta servendo i client. In caso contrario, il sistema può scaricare la DLL e liberare la memoria associata.

Analogamente a tutti gli oggetti COM, i gestori dell'estensione shell devono implementare un'interfaccia IUnknown e una fabbrica di classi . La maggior parte deve anche implementare un'interfaccia IPersistFile o IShellExtInit in Windows XP o versioni precedenti. Questi sono stati sostituiti da IInitializeWithStream, IInitializeWithItem e IInitializeWithFile in Windows Vista. Shell usa queste interfacce per inizializzare il gestore.

L'interfaccia IPersistFile deve essere implementata dai seguenti:

  • Gestori di icone
  • Gestori di dati
  • Eliminare i gestori

L'interfacciaIShellExtInitdeve essere implementata dal codice seguente:

  • Gestori di menu di scelta rapida
  • Gestori di trascina e rilascia
  • Gestori dei fogli delle proprietà

Gli argomenti seguenti sono trattati nella parte restante di questo argomento:

Implementazione di IPersistFile

L'interfaccia IPersistFile è progettata per consentire il caricamento o il salvataggio di un oggetto in un file su disco. Dispone di sei metodi oltre a IUnknown, cinque dei propri e il metodoGetClassIDche eredita da IPersist. Con le estensioni shell, IPersist viene usato solo per inizializzare un oggetto gestore estensioni shell. Poiché in genere non è necessario leggere o scrivere sul disco, solo i metodi GetClassID e Load richiedono un'implementazione nonken.

Shell chiama GetClassID prima e la funzione restituisce l'identificatore di classe (CLSID) dell'oggetto gestore di estensione. La Shell chiama quindi Load e trasferisce due valori. Il primo, pszFile, è una stringa Unicode con il nome del file o della cartella su cui Shell sta per funzionare. Il secondo è dwMode, che indica la modalità di accesso ai file. Poiché in genere non è necessario accedere ai file, dwMode è in genere zero. Il metodo archivia questi valori in base alle esigenze per riferimento successivo.

Il frammento di codice seguente illustra come un gestore di estensioni shell tipico implementa i metodiGetClassIDe Load. È progettato per gestire ANSI o Unicode. CLSID_SampleExtHandler è il GUID dell'oggetto del gestore di estensione e CSampleShellExtension è il nome della classe usata per implementare l'interfaccia. Le variabili m_szFileName e m_dwMode sono variabili private usate per archiviare il nome e i flag di accesso del file.

class CSampleShellExtension : public IPersistFile
{
    // Method declarations not included

    private:
    WCHAR m_szFileName[MAX_PATH];    // The file name
    DWORD m_dwMode;                  // The file access mode
}

IFACEMETHODIMP CSampleShellExtension::GetClassID(__out CLSID *pCLSID)
{
    *pCLSID = CLSID_SampleExtHandler;
}

IFACEMETHODIMP CSampleShellExtension::Load(PCWSTR pszFile, DWORD dwMode)
{
    m_dwMode = dwMode;
    return StringCchCopy(m_szFileName, ARRAYSIZE(m_szFileName), pszFile); 
}

// The implementation sample is continued in the next section.

Implementazione di IShellExtInit

L'interfacciaIShellExtInit diha un solo metodo, IShellExtInit::Initialize, oltre a IUnknown. Il metodo ha tre parametri che shell può usare per passare vari tipi di informazioni. I valori passati dipendono dal tipo di gestore e alcuni possono essere impostati su NULL.

  • pidlFolder contiene il puntatore di una cartella a un elenco di identificatori di elemento (PIDL). Si tratta di un PIDL assoluto. Per le estensioni della finestra proprietà, questo valore è NULL. Per le estensioni del menu di scelta rapida, si tratta del PIDL della cartella che contiene l'elemento il cui menu di scelta rapida viene visualizzato. Per i gestori di trascinamento non predefiniti, si tratta del PIDL della cartella di destinazione.
  • pDataObject contiene un puntatore all'interfaccia IDataObject di un oggetto dati. L'oggetto dati contiene uno o più nomi di file in formato CF_HDROP.
  • hRegKey contiene una chiave del Registro di sistema per l'oggetto file o il tipo di cartella.

Il metodo IShellExtInit::Initialize archivia il nome del file, puntatore IDataObject e la chiave del Registro di sistema in base alle esigenze per un uso successivo. Il frammento di codice seguente illustra un'implementazione di IShellExtInit::Initialize. Per semplicità, in questo esempio si presuppone che l'oggetto dati contenga solo un singolo file. In generale, l'oggetto dati potrebbe contenere più file, ognuno dei quali dovrà essere estratto.

// This code continues the CSampleShellExtension sample shown in the
// "Implementing IPersistFile" section above.

class CSampleShellExtension : public IShellExtInit
{
    // Method declarations not included
    
    private:
    // IDList of the folder for extensions invoked on the folder, such as 
    // background context menu handlers or nondefault drag-and-drop handlers. 
    PIDLIST_ABSOLUTE m_pidlFolder;
    
    // The data object contains an expression of the items that the handler is 
    // being initialized for. Use SHCreateShellItemArrayFromDataObject to 
    // convert this object to an array of items. Use SHGetItemFromObject if you
    // are only interested in a single Shell item. If you need a file system
    // path, use IShellItem::GetDisplayName(SIGDN_FILESYSPATH, ...).
    IDataObject *m_pdtobj;
    
    // For context menu handlers, the registry key provides access to verb 
    // instance data that might be stored there. This is a rare feature to use 
    // so most extensions do not need this variable.
    HKEY m_hRegKey;             
}
    
// This method must be very efficient. Do not do any unnecessary work here.
// Use Initialize to acquire resources that will be used later.

IFACEMETHODIMP CSampleShellExtension::Initialize(__in_opt PCIDLIST_ABSOLUTE pidlFolder,
                                                 __in_opt IDataObject *pDataObject, 
                                                 __in_opt HKEY hRegKey) 
{ 
    // In some cases, handlers are initialized multiple times. Therefore, 
    // clear any previous state here.
    CoTaskMemFree(m_pidlFolder);
    m_pidlFolder = NULL;
    
    if (m_pdtobj)
    { 
        m_pdtobj->Release(); 
    }
    
    if (m_hRegKey)
    {
        RegCloseKey(m_hRegKey);
        m_hRegKey = NULL;
    }
    
    // Capture the inputs for use later.
    HRESULT hr = S_OK;
    
    if (pidlFolder)
    {
        m_pidlFolder = ILClone(pidlFolder);   // Make a copy to use later.
        hr = m_pidlFolder ? S_OK : E_OUTOFMEMORY;
    }
    
    if (SUCCEEDED(hr))
    {
        // If a data object pointer was passed into the method, save it and
        // extract the file name. 
        if (pDataObject) 
        { 
            m_pdtobj = pDataObject; 
            m_pdtobj->AddRef(); 
        }
    
        // It is uncommon to use the registry handle, but if you need it,
        // duplicate it now.
        if (hRegKey)
        {
            LSTATUS const result = RegOpenKeyEx(hRegKey, NULL, 0, KEY_READ, &m_hRegKey); 
            hr = HRESULT_FROM_WIN32(result);
        }
    }
    
    return hr;
}

Personalizzazione del tooltip

Esistono due modi per personalizzare gli infotip. Un modo consiste nell'implementare un oggetto che supporta IQueryInfo e quindi registrare l'oggetto nella sottochiave appropriata nel Registro di sistema (vedere di seguito). In alternativa, è possibile specificare una stringa fissa o un elenco di determinate proprietà di file da visualizzare.

Per visualizzare una stringa fissa per un'estensione dello spazio dei nomi, creare una sottochiave denominata InfoTip sotto la chiave CLSID dell'estensione dello spazio dei nomi. Impostare i dati della sottochiave come stringa da visualizzare.

HKEY_CLASSES_ROOT
   CLSID
      {CLSID}
         InfoTip = InfoTip string for your namespace extension

Per visualizzare una stringa fissa per un tipo di file, creare una sottochiave denominata InfoTip sotto la chiave ProgID del tipo di file per cui si desidera fornire le descrizioni informazioni. Impostare i dati della sottochiave come stringa da visualizzare.

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = InfoTip string for all files of this type

Se si desidera che Shell mostri determinate proprietà del file nell'infotip per un tipo di file specifico, creare una sottochiave denominata InfoTip sotto la chiave ProgID di tale tipo di file. Impostare i dati della sottochiave come elenco delimitato da punto e virgola di nomi di proprietà canonici o {fmtid}, coppie pid in cui nome propname è un nome di proprietà canonico e {fmtid}, pid è una coppia FMTID/PID.

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = propname;propname;{fmtid},pid;{fmtid},pid

È possibile utilizzare i nomi di proprietà seguenti.

Nome della proprietà Descrizione Recuperato da
Autore Autore del documento PIDSI_AUTHOR
Titolo Titolo del documento PIDSI_TITLE
Oggetto Riepilogo dell'oggetto PIDSI_SUBJECT
Commento Commenti del documento PIDSI_COMMENT o proprietà di cartella/unità
Conteggio pagine Numero di pagine PIDSI_PAGECOUNT
Nome Nome amichevole Visualizzazione cartella standard
Posizione Originale Percorso del file originale Cartella valigetta e cartella del Cestino
DataEliminazione Data di eliminazione del file Cestino del computer
Digitare Tipo di file Visualizzazione dettagli cartella standard
Grandezza Dimensioni del file Visualizzazione dettagli cartella standard
SyncCopyIn Uguale a OriginalLocation Uguale a OriginalLocation
Modificato Data ultima modifica Visualizzazione dettagli cartella standard
Creato Data di creazione Visualizzazione dettagli cartella standard
Acceduto Data dell'ultimo accesso Visualizzazione dettagli cartella standard
InFolder Directory contenente il file Risultati della ricerca dei documenti
Rango Qualità della corrispondenza di ricerca Risultati della ricerca dei documenti
Freespace Spazio di archiviazione disponibile Unità disco
NumeroDiVisite Numero di visite Cartella Preferiti
Attributi Gli attributi del file Visualizzazione dettagli cartella standard
Società Nome società PIDDSI_COMPANY
Categoria Categoria documento PIDDSI_CATEGORY
Diritto d’autore Copyright multimediale PIDMSI_COPYRIGHT
HTMLInfoTipFile File di suggerimento HTML Desktop.ini file per la cartella

 

Registrazione dei Gestori dell'Estensione Shell