Initiera gränssnittstilläggshanterare
En stor del av implementeringen av ett Shell-tilläggshanterarobjekt styrs av dess typ. Det finns dock några vanliga element. I det här avsnittet beskrivs de aspekter av implementeringen som delas av alla Shell-tilläggshanterare.
Alla Gränssnittstilläggshanterare är processbaserade COM-objekt (Component Object Model). De måste tilldelas ett GUID och registreras enligt beskrivningen i Registering Shell Extension Handlers. De implementeras som DLL:er och måste exportera följande standardfunktioner:
- DllMain. Standardinmatningspunkten till DLL:en.
- DllGetClassObject. Exponerar objektets klassfabrik.
- DllCanUnloadNow. COM anropar den här funktionen för att avgöra om objektet betjänar några klienter. Annars kan systemet ta bort DLL:en och frigöra det associerade minnet.
Precis som alla COM-objekt måste Gränssnittstilläggshanterare implementera ett IUnknown--gränssnitt och en klassfabrik. De flesta måste också implementera antingen ett IPersistFile- eller IShellExtInit--gränssnitt i Windows XP eller tidigare. Dessa ersattes av IInitializeWithStream, IInitializeWithItem och IInitializeWithFile i Windows Vista. Skalet använder dessa gränssnitt för att initiera hanteraren.
Gränssnittet IPersistFile måste implementeras med följande:
- Ikonhanterare
- Datahanterare
- Släpp hanterare
Gränssnittet IShellExtInit måste implementeras med följande:
- Snabbmenyhanterare
- Dra och släpp-hanterare
- Egenskapsarkhandläggare
Följande ämnen beskrivs i resten av det här avsnittet:
Implementera IPersistFile
Gränssnittet IPersistFile är utformat för att tillåta att ett objekt läses in från eller sparas i en diskfil. Den har sex metoder utöver IUnknown, fem egna och metoden GetClassID som den ärver från IPersist. Med Shell-tillägg används IPersist endast för att initiera ett Shell-tilläggshanterarobjekt. Eftersom det vanligtvis inte finns något behov av att läsa från eller skriva till disken kräver endast metoderna GetClassID och Load en icke-token implementering.
Shell anropar GetClassID först och funktionen returnerar klassidentifieraren (CLSID) för tilläggshanterarobjektet. Shell anropar sedan Load och skickar in två värden. Den första, pszFile, är en Unicode-sträng med namnet på den fil eller mapp som Shell är på väg att fungera på. Den andra är dwMode, vilket anger filåtkomstläget. Eftersom det normalt inte finns något behov av att komma åt filer är dwMode- vanligtvis noll. Metoden lagrar dessa värden efter behov för senare referens.
Följande kodfragment illustrerar hur en typisk Shell-tilläggshanterare implementerar GetClassID- och Load-metoder. Den är utformad för att hantera antingen ANSI eller Unicode. CLSID_SampleExtHandler är tilläggshanterarobjektets GUID och CSampleShellExtension är namnet på den klass som används för att implementera gränssnittet. Variablerna m_szFileName och m_dwMode är privata variabler som används för att lagra filens namn och åtkomstflaggor.
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.
Implementering av IShellExtInit
Gränssnittet IShellExtInit har bara en metod, IShellExtInit::Initiera, förutom IUnknown. Metoden har tre parametrar som Shell kan använda för att skicka in olika typer av information. De värden som skickas in beror på typen av hanterare och vissa kan anges till NULL-.
- pidlFolder innehåller en pekare för en mapp till en lista över objektidentifierare (PIDL). Detta är en absolut PIDL. För egenskapsbladstillägg är detta värde NULL. För snabbmenytillägg är det PIDL för mappen som innehåller det objekt vars snabbmeny visas. För icke-standardiserade dra-och-släpp-hanterare är det PIDL för målmappen.
- pDataObject innehåller en pekare till ett dataobjekts IDataObject--gränssnitt. Dataobjektet innehåller ett eller flera filnamn i CF_HDROP format.
- hRegKey innehåller en registernyckel för filobjektet eller mapptypen.
Metoden IShellExtInit::Initialize lagrar filnamnet, IDataObject pekare och registernyckel efter behov för senare användning. Följande kodfragment illustrerar en implementering av IShellExtInit::Initiera. För enkelhetens skull förutsätter det här exemplet att dataobjektet endast innehåller en enda fil. I allmänhet kan dataobjektet innehålla flera filer, som var och en måste extraheras.
// 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;
}
Anpassning av infotip
Det finns två sätt att anpassa informationstips. Ett sätt är att implementera ett objekt som stöder IQueryInfo och sedan registrera objektet under rätt undernyckel i registret (se nedan). Du kan också ange antingen en fast sträng eller en lista över vissa filegenskaper som ska visas.
Om du vill visa en fast sträng för ett namnområdestillägg skapar du en undernyckel med namnet InfoTip under CLSID-nyckeln för namnområdestillägget. Ange att data för undernyckeln ska vara den sträng som du vill ska visas.
HKEY_CLASSES_ROOT
CLSID
{CLSID}
InfoTip = InfoTip string for your namespace extension
Om du vill visa en fast sträng för en filtyp skapar du en undernyckel med namnet InfoTip under ProgID- nyckel för filtypen som du vill ange informationstips för. Ange att data för undernyckeln ska vara den sträng som du vill ska visas.
HKEY_CLASSES_ROOT
ProgID
InfoTip = InfoTip string for all files of this type
Om du vill att Shell ska visa vissa filegenskaper i infotip för en viss filtyp skapar du en undernyckel med namnet InfoTip under ProgID nyckel av den filtypen. Ange att data för den undernyckeln ska vara en semikolondelinerad lista över kanoniska egenskapsnamn eller {fmtid}, pid-par där propname är ett kanoniskt egenskapsnamn och {fmtid}, pid är ett FMTID/PID-par.
HKEY_CLASSES_ROOT
ProgID
InfoTip = propname;propname;{fmtid},pid;{fmtid},pid
Följande egenskapsnamn kan användas.
Egenskapsnamn | Beskrivning | Hämtad från |
---|---|---|
Författare | Författare till dokumentet | PIDSI_AUTHOR |
Titel | Dokumentets rubrik | PIDSI_TITLE |
Subjekt | Ämnessammanfattning | PIDSI_SUBJECT |
Kommentar | Dokumentkommentar | Egenskaper för PIDSI_COMMENT eller mapp/enhetsegenskaper |
PageCount | Antal sidor | PIDSI_PAGECOUNT |
Namn | Beskrivande namn | Standardvy för mapp |
Ursprunglig plats | Platsen för den ursprungliga filen | Portföljmapp och papperskorgsmapp |
DatumBorttaget | Datum då filen togs bort | Papperskorgsmapp |
Typ | Typ av fil | Standardmappvyn för detaljer |
Storlek | Filstorlek | Standardvy för mappdetaljer |
SyncCopyIn | Samma som OriginalLocation | Samma som OriginalLocation |
Modifierad | Senast ändrat datum | Standardvy för mappinformation |
Skapad | Datum som skapats | Vyn Standardmappsinformation |
Nås | Senast använt datum | Vyn Standardmappsinformation |
InFolder | Katalog som innehåller filen | Sökresultat för dokument |
Rang | Kvalitet på sökmatchning | Sökresultat för dokument |
Freespace | Tillgängligt lagringsutrymme | Diskenheter |
AntalBesök | Antal besök | Favoritmapp |
Attribut | Filattribut | Standardvyn för mappdetaljer |
Företag | Företagsnamn | PIDDSI_COMPANY |
Kategori | Dokumentkategori | PIDDSI_CATEGORY |
Upphovsrätt | Medieupphovsrätt | PIDMSI_COPYRIGHT |
HTMLInfoTipFile | HTML InfoTip-fil | Desktop.ini fil för mapp |
Relaterade ämnen