Sdílet prostřednictvím


Inicializace obslužných rutin rozšíření prostředí

Většina implementace objektu obslužného modulu rozšíření Shellu je určena jeho typem. Existují však některé běžné prvky. Toto téma popisuje aspekty implementace, které sdílí všechny obslužné rutiny prostředí pro rozšíření.

Všechny obslužné rutiny rozšíření prostředí jsou objekty modelu COM (Component Object Model) běžící v procesu. Musí jim být přiřazen identifikátor GUID a registrovány, jak je popsáno v registrace obslužných rutin rozšíření prostředí. Implementují se jako knihovny DLL a musí exportovat následující standardní funkce:

  • DllMain. Standardní vstupní bod pro knihovnu DLL.
  • DllGetClassObject. Zpřístupňuje továrnu tříd objektu.
  • DllCanUnloadNow. Com volá tuto funkci k určení, zda objekt obsluhuje nějaké klienty. Pokud ne, systém může uvolnit knihovnu DLL a uvolnit přidruženou paměť.

Stejně jako všechny objekty COM musí obslužné rutiny rozšíření prostředí implementovat IUnknown rozhraní a třídy factory. Většina musí také implementovat rozhraní IPersistFile nebo IShellExtInit v systému Windows XP nebo starších verzích. Tyto položky byly nahrazeny IInitializeWithStream, IInitializeWithItem a IInitializeWithFile v systému Windows Vista. Shell používá tato rozhraní k inicializaci obslužného procesu.

Rozhraní IPersistFile musí být implementováno následujícím kódem:

  • Správci ikon
  • Zpracovatelé dat
  • Obslužné rutiny pro upuštění

Rozhraní IShellExtInit musí být implementováno následujícím kódem:

  • Obslužné programy místní nabídky
  • Úchyty pro přetažení
  • Obslužné rutiny seznamu vlastností

Ve zbývající části tohoto tématu jsou popsány následující témata:

Implementace IPersistFile

Rozhraní IPersistFile je navržené tak, aby umožňovalo načtení objektu ze souboru disku nebo jeho uložení do souboru disku. Má šest metod včetně IUnknown, z toho pět vlastních, a metodu GetClassID, kterou dědí z IPersist. S rozšířeními Shellu se IPersist používá pouze k inicializaci objektu zpracovatele rozšíření Shellu. Vzhledem k tomu, že obvykle není nutné číst z disku ani na něj zapisovat, pouze metody GetClassID a Load vyžadují ne-tokenovou implementaci.

Shell nejprve volá GetClassID a poté funkce vrátí identifikátor třídy (CLSID) objektu rozšíření. Prostředí pak volá Load a předává dvě hodnoty. První pszFile, je řetězec Unicode s názvem souboru nebo složky, se kterou Shell chystá pracovat. Druhý je dwMode, který označuje režim přístupu k souboru. Protože obvykle není potřeba přistupovat k souborům, dwMode je obvykle nula. Metoda ukládá tyto hodnoty podle potřeby pro pozdější referenci.

Následující fragment kódu ukazuje, jak typická obslužná rutina rozšíření Shell implementuje GetClassID a Load metody. Je navržený tak, aby zpracovával ansi nebo Unicode. CLSID_SampleExtHandler je identifikátor GUID objektu obslužné rutiny rozšíření a CSampleShellExtension je název třídy použité k implementaci rozhraní. Proměnné m_szFileName a m_dwMode jsou soukromé proměnné, které slouží k uložení názvu souboru a přístupových příznaků.

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.

Implementace IShellExtInit

Rozhraní IShellExtInit má pouze jednu metodu, IShellExtInit::Initialize, kromě IUnknown. Metoda má tři parametry, které shell může použít k předávání různých typů informací. Předané hodnoty závisí na typu obslužné rutiny a některé je možné nastavit na NULL.

  • pidlFolder obsahuje ukazatel složky na seznam identifikátorů položek (PIDL). Jedná se o absolutní PIDL. U rozšíření seznamu vlastností je tato hodnota NULL. U rozšíření kontextových nabídek se jedná o PIDL složky obsahující položku, jejíž kontextová nabídka se zobrazuje. U obslužných rutin přetažení, které nejsou ve výchozím nastavení, je to PIDL cílové složky.
  • pDataObject drží ukazatel na rozhraní IDataObject datového objektu. Datový objekt obsahuje jeden nebo více názvů souborů ve formátu CF_HDROP.
  • hRegKey obsahuje klíč registru pro objekt souboru nebo typ složky.

Metoda IShellExtInit::Initialize ukládá název souboru, IDataObject ukazatel a klíč registru podle potřeby pro pozdější použití. Následující fragment kódu znázorňuje implementaci IShellExtInit::Initialize. Pro zjednodušení tento příklad předpokládá, že datový objekt obsahuje pouze jeden soubor. Obecně platí, že datový objekt může obsahovat více souborů, z nichž každý bude potřeba extrahovat.

// 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;
}

Přizpůsobení Infotipu

Informační popisy můžete přizpůsobit dvěma způsoby. Jedním ze způsobů je implementace objektu, který podporuje IQueryInfo a pak objekt zaregistrovat pod správným podklíčem v registru (viz níže). Případně můžete zadat pevný řetězec nebo seznam určitých vlastností souboru, které se mají zobrazit.

Pokud chcete zobrazit pevný řetězec pro rozšíření oboru názvů, vytvořte pod klíčem CLSID vašeho rozšíření oboru názvů podklíč s názvem InfoTip. Nastavte data tohoto podklíče na řetězec, který chcete zobrazit.

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

Pokud chcete zobrazit pevný řetězec pro typ souboru, vytvořte podklíč s názvem InfoTip pod klíčem ProgID typu souboru, pro který chcete zadat informační popisy. Nastavte data tohoto podklíče na řetězec, který chcete zobrazit.

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

Pokud chcete, aby prostředí zobrazoval určité vlastnosti souboru v informačním popisu pro určitý typ souboru, vytvořte podklíč s názvem InfoTip pod klíčem ProgID tohoto typu souboru. Nastavte data tohoto podklíče na středník oddělený seznam názvů kanonických vlastností nebo {fmtid}, dvojice pid, kde propname je název kanonické vlastnosti a {fmtid},pid je páry FMTID/PID.

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

Můžete použít následující názvy vlastností.

Název vlastnosti Popis Citováno z
Autor Autor dokumentu PIDSI_AUTHOR
Titul Název dokumentu PIDSI_TITLE
Předmět Souhrn předmětu PIDSI_SUBJECT
Komentář Komentáře k dokumentům vlastnosti PIDSI_COMMENT nebo vlastnosti složky/jednotky
Počet stránek Počet stránek PIDSI_PAGECOUNT
Jméno Přátelský název Standardní zobrazení složek
PůvodníUmístění Umístění původního souboru Složka aktovky a složka Koš
DatumSmazáno Datum odstranění souboru Složka Odpadkového Koše
Typ Typ souboru Standardní zobrazení podrobností složky
Velikost Velikost souboru Standardní zobrazení podrobností složky
SyncCopyIn Stejné jako OriginalLocation Stejné jako OriginalLocation
Upravený Datum poslední změny Standardní zobrazení podrobností složky
Vytvořeno Datum vytvoření Standardní zobrazení podrobností složky
Přístupné Datum posledního přístupu Standardní zobrazení podrobností složky
InFolder Adresář obsahující soubor Výsledky hledání dokumentu
Hodnost Kvalita shody vyhledávání Výsledky hledání dokumentu
FreeSpace Dostupný prostor úložiště Diskové jednotky
Počet návštěv Počet návštěv Složka Oblíbené
Atributy Atributy souboru Standardní zobrazení podrobností složky
Společnost Název společnosti PIDDSI_COMPANY
Kategorie Kategorie dokumentu PIDDSI_CATEGORY
Autorské právo Autorská práva k médiím PIDMSI_COPYRIGHT
HTMLInfoTipFile Soubor HTML InfoTip Desktop.ini soubor pro složku

 

Registrace obslužných rutin rozšíření Shell