Dela via


Skapa gränssnittstilläggshanterare

Funktionerna i Shell kan utökas med registerposter och .ini filer. Även om den här metoden för att utöka skalet är enkel och lämplig för många ändamål, är den begränsad. Om du till exempel använder registret för att ange en anpassad ikon för en filtyp visas samma ikon för varje fil av den typen. Om du utökar gränssnittet med registret kan du inte variera ikonen för olika filer av samma typ. Andra aspekter av Shell, till exempel egenskapsbladet Egenskaper som visas när man högerklickar på en fil, kan inte alls ändras med registret.

En mer kraftfull och flexibel metod för att utöka gränssnittet är att implementera gränssnittstilläggshanterare. Dessa hanterare kan implementeras för en mängd olika åtgärder som Shell kan utföra. Innan du vidtar åtgärden frågar Shell tilläggshanteraren, vilket ger den möjlighet att ändra åtgärden. Ett vanligt exempel är en snabbmenytilläggshanterare. Om en implementeras för en filtyp, kommer den att frågas varje gång en av filerna högerklickas. Hanteraren kan sedan ange ytterligare menyobjekt på fil-för-fil-basis i stället för att ha samma uppsättning för hela filtypen.

I det här dokumentet beskrivs hur du implementerar tilläggshanterare som gör att du kan ändra en mängd olika Shell-åtgärder. Följande hanterare är associerade med en viss filtyp och gör att du kan ange fil för fil:

Handler Beskrivning
snabbmenyhanterare Anropas innan en fils snabbmeny visas. Det gör att du kan lägga till objekt på snabbmenyn på fil-för-fil-basis.
Datahanterare Anropas när en dra och släpp-åtgärd utförs på dragShell-objekt. Det gör det möjligt för dig att tillhandahålla ytterligare urklippsformat till släppmålet.
Drop-hanterare Anropas när ett dataobjekt dras över eller släpps på en fil. Det gör att du kan göra en fil till ett släppmål.
Ikonhanterare Anropas innan en fils ikon visas. Det gör att du kan ersätta filens standardikon med en anpassad ikon på fil-för-fil-basis.
egenskapsbladshanterare Anropas innan ett objekts Egenskaper egenskapsblad visas. Det gör att du kan lägga till eller ersätta sidor.
miniatyrbild hanterare Innehåller en bild som representerar objektet.
Infotip-hanterare Ger popup-text när användaren hovrar muspekaren över objektet.
metadatahanterare Ger läs- och skrivåtkomst till metadata (egenskaper) som lagras i en fil. Detta kan användas för att utöka informationsvyn, informationstipsen, egenskapssidan och grupperingsfunktionerna.

 

Andra hanterare är inte associerade med en viss filtyp men anropas före vissa Shell-åtgärder:

Handler Beskrivning
Kolumnhanterare Anropas av Utforskaren innan den visar informationsvyn för en mapp. Det gör att du kan lägga till anpassade kolumner i vyn Information.
Kopieringskrokhanterare Anropas när en mapp eller ett skrivarobjekt är på väg att flyttas, kopieras, tas bort eller byta namn. Det gör att du kan godkänna eller lägga in sitt veto mot åtgärden.
Dra-och-släpp-kontroll Anropas när en fil dras med höger musknapp. Det gör att du kan ändra snabbmenyn som visas.
Ikonöverläggshanterare Anropas innan en fils ikon visas. Det gör att du kan ange ett överlägg för filens ikon.
sökhanterare Anropad för att starta en sökmotor. Det gör att du kan implementera en anpassad sökmotor som är tillgänglig från Start-menyn eller Utforskaren.

 

Information om hur du implementerar specifika tilläggshanterare beskrivs i avsnitten ovan. Resten av det här dokumentet beskriver några implementeringsproblem som är gemensamma för alla Shell-tilläggshanterare.

Implementera gränssnittstilläggshanterare

En stor del av implementeringen av ett Gränssnittstilläggshanterarobjekt beror på 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.

Många Gränssnittstilläggshanterare är processbaserade COM-objekt (Component Object Model). De måste tilldelas ett GUID och registreras enligt beskrivningen i Registrera Gränssnittstilläggshanterare. 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 en Shell extensionshanterare implementera ett IUnknown--gränssnitt och en klassfabrik. De flesta tilläggshanterare 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. Shellen använder dessa gränssnitt för att initiera hanteraren.

Gränssnittet IPersistFile måste implementeras med följande:

  • Datahanterare
  • Släpp hanterare

Tidigare krävdes även ikonhanterare för att implementera IPersistFile, men detta är inte längre sant. För ikonhanterare är IPersistFile nu valfri och andra gränssnitt som IInitializeWithItem föredras.

Gränssnittet IShellExtInit måste implementeras med följande:

  • Snabbmenyhanterare
  • Dra och släpp-hanterare
  • Egenskapsbladshanterare

Implementera IPersistFile

Gränssnittet IPersistFile är avsett 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, pszFileName, ä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 vanligtvis 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 CSampleExtHandler ä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.

wchar_t m_szFileName[MAX_PATH];    // The file name
DWORD m_dwMode;                  // The file access mode

CSampleExtHandler::GetClassID(CLSID *pCLSID)
{
    *pCLSID = CLSID_SampleExtHandler;
}

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

Implementera 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-.

  • pIDFolder innehåller en mapppekare till en lista över objektidentifierare (PIDL). För egenskapsbladstillägg är det NULL. För snabbmenytillägg är det PIDL för mappen som innehåller det objekt vars snabbmeny visas. För nondefault-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 den innehålla flera filer som var och en måste extraheras.

LPCITEMIDLIST  m_pIDFolder;           //The folder's PIDL
wchar_t        m_szFile[MAX_PATH];    //The file name
IDataObject   *m_pDataObj;            //The IDataObject pointer
HKEY           m_hRegKey;             //The file or folder's registry key

STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, 
                                   IDataObject *pDataObj, 
                                   HKEY hRegKey) 
{ 
    // If Initialize has already been called, release the old PIDL
    ILFree(m_pIDFolder);
    m_pIDFolder = nullptr;

    // Store the new PIDL.
    if (pIDFolder)
    {
        m_pIDFolder = ILClone(pIDFolder);
    }
    
    // If Initialize has already been called, release the old
    // IDataObject pointer.
    if (m_pDataObj)
    { 
        m_pDataObj->Release(); 
    }
     
    // If a data object pointer was passed in, save it and
    // extract the file name. 
    if (pDataObj) 
    { 
        m_pDataObj = pDataObj; 
        pDataObj->AddRef(); 
      
        STGMEDIUM   medium;
        FORMATETC   fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
        UINT        uCount;

        if (SUCCEEDED(m_pDataObj->GetData(&fe, &medium)))
        {
            // Get the count of files dropped.
            uCount = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);

            // Get the first file name from the CF_HDROP.
            if (uCount)
                DragQueryFile((HDROP)medium.hGlobal, 0, m_szFile, 
                              sizeof(m_szFile)/sizeof(TCHAR));

            ReleaseStgMedium(&medium);
        }
    }

    // Duplicate the registry handle. 
    if (hRegKey) 
        RegOpenKeyEx(hRegKey, nullptr, 0L, MAXIMUM_ALLOWED, &m_hRegKey); 
    return S_OK; 
}

CSampleExtHandler är namnet på den klass som används för att implementera gränssnittet. Variablerna m_pIDFolder, m_pDataObject, m_szFileNameoch m_hRegKey är privata variabler som används för att lagra den information som skickas in. För enkelhetens skull förutsätter det här exemplet att endast ett filnamn kommer att lagras av dataobjektet. När FORMATETC- struktur hämtas från dataobjektet används DragQueryFile för att extrahera filnamnet från FORMATETC-strukturens medium.hGlobal- medlem. Om en registernyckel skickas använder metoden RegOpenKeyEx för att öppna nyckeln och tilldelar handtaget till m_hRegKey.

Anpassning av infotip

Det finns två sätt att anpassa informationstips:

Om du vill visa en fast sträng för ett namnområdestillägg skapar du en post med namnet InfoTip i {CLSID} nyckeln för namnområdestillägget. Ange värdet för posten som antingen den literalsträng som du vill visa, som du ser i det här exemplet, eller en indirekt sträng som anger en resurs och ett index inom den resursen (i lokaliseringssyfte).

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 post med namnet InfoTip i ProgID- nyckel av den filtypen. Ange värdet för posten som antingen den literalsträng som du vill visa eller en indirekt sträng som anger en resurs och ett index i resursen (för lokaliseringsändamål), som du ser i det här exemplet.

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = Resource.dll, 3

Om du vill att Shell ska visa specifika filegenskaper i infotip för en viss filtyp skapar du en post med namnet InfoTip i ProgID nyckel för den filtypen. Ange värdet för posten som en semikolonseparerad lista över kanoniska egenskapsnamn, formatidentifierare (FMTID)/egenskapsidentifierare (PID)-par, eller båda. Det här värdet måste börja med "prop:" för att identifiera det som en egenskapsliststräng. Om du utelämnar "prop:" visas värdet som en literalsträng och visas som sådan.

I följande exempel är propname ett kanoniskt egenskapsnamn (till exempel System.Date) och {fmtid},pid ett FMTID/PID-par.

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = prop: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/drivrutiner
PageCount Antal sidor PIDSI_PAGECOUNT
Namn Vänligt namn Standardmappläge
Ursprungsplats Platsen för den ursprungliga filen Portföljmapp och papperskorgsmapp
DatumBorttaget Datum då filen togs bort Papperskorgsmapp
Typ Typ av fil Standardvy för mappdetaljer
Storlek Filstorlek Detaljerad vy för standardmapp
SyncCopyIn Samma som OriginalLocation Samma som OriginalLocation
Modifierad Senast ändrat datum Standardmappens detaljer
Skapad Datum som skapats Standardvy för mappdetaljer
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
Antal Besök Antal besök Favoritmapp
Attribut Filattribut Detaljvy för standardmapp
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

 

Förbättra Windows Search med Gränssnittstilläggshanterare

Gränssnittstilläggshanterare kan användas för att förbättra användarupplevelsen som tillhandahålls av en Windows Search-protokollhanterare. För att möjliggöra sådana förbättringar måste den stödande Shell-tilläggshanteraren vara utformad för att integreras med sökprotokollhanteraren som en datakälla. Information om hur du förbättrar en Windows Search-protokollhanterare genom integrering med en Shell-tilläggshanterare finns i Lägga till ikoner, förhandsgranskningar och snabbmenyer. Mer information om Protokollhanterare för Windows Search finns i Utveckla protokollhanterare.

Registrera gränssnittstilläggshanterare

Ett gränssnittstilläggshanterarobjekt måste registreras innan gränssnittet kan använda det. Det här avsnittet är en allmän diskussion om hur du registrerar en Shell-tilläggshanterare.

Varje gång du skapar eller ändrar en Shell-tilläggshanterare är det viktigt att meddela systemet att du har gjort en ändring med SHChangeNotifyoch ange händelsen SHCNE_ASSOCCHANGED. Om du inte anropar SHChangeNotifykanske ändringen inte identifieras förrän systemet har startats om.

Precis som med alla COM-objekt måste du skapa ett GUID för hanteraren med hjälp av ett verktyg som UUIDGEN.exe. Skapa en nyckel under HKEY_CLASSES_ROOT\CLSID- vars namn är strängformen för GUID. Eftersom Shell-tilläggshanterare är processerver måste du skapa en InProcServer32- nyckel under GUID-nyckeln med standardvärdet inställt på sökvägen till hanterarens DLL. Använd lägenhetstrådningsmodellen.

Varje gång shell vidtar en åtgärd som kan omfatta en Shell-tilläggshanterare kontrollerar den lämplig registernyckel. Nyckeln som en tilläggshanterare registreras under styr därför när den anropas. Det är vanligt att till exempel ha en snabbmenyhanterare som anropas när Shell visar en snabbmeny för en medlem i en filtyp. I det här fallet måste hanteraren registreras under filtypens ProgID- nyckel.

Hanterarnamn

Om du vill aktivera en Shell-tilläggshanterare skapar du en undernyckel med undernyckelnamnet för hanteraren (se nedan) under undernyckeln ShellEx för antingen ProgID- (för filtyper) eller shell-objekttypens namn (för fördefinierade gränssnittsobjekt).

Om du till exempel vill registrera en snabbmenytilläggshanterare för MyProgram.1 börjar du med att skapa följande undernyckel:

HKEY_CLASSES_ROOT
   MyProgram.1
      ShellEx
         ContextMenuHandlers

För följande hanterare skapar du en undernyckel under nyckeln "Handler Subkey name" vars namn är strängversionen av CLSID för Shell-tillägget. Flera tillägg kan registreras under subnyckeln för hanteraren genom att skapa flera subnycklar.

Handler Gränssnitt Undernyckelnamn för hanterare
Snabbåtkomstmenyhanterare IContextMenu ContextMenuHandlers
Copyhook-hanterare ICopyHook CopyHookHandlers
Dra och släpp-hanterare IContextMenu DragDropHandlers
Egenskapsbladshanterare IShellPropSheetExt PropertySheetHandlers
Kolumnleverantörshanterare (föråldrad i Windows Vista) IColumnProvider ColumnHandlers

 

För följande hanterare är standardvärdet för nyckeln "Handler Subkey Name" strängversionen av CLSID för Shell-tillägget. Endast ett tillägg kan registreras för dessa hanterare.

Handler Gränssnitt Undernyckelnamn för hanterare
Datahanterare IDataObject DataHandler
Släpp-hanterare IDropTarget DropHandler
Ikonhanterare IExtractIconA/W IconHandler
Bildhanterare IExtractImage {BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
Miniatyrbildhanterare IThumbnailProvider {E357FCCD-A995-4576-B01F-234630154E96}
Infotip-hanterare IQueryInfo {00021500-0000-0000-C000-000000000046}
Shell-länk (ANSI ) IShellLinkA {000214EE-0000-0000-C000-000000000046}
Shell-länk (UNICODE) IShellLinkW {000214F9-0000-0000-C000-000000000046}
Strukturerad lagring IStorage {0000000B-0000-0000-C000-000000000046}
Metadata IPropertyStore PropertyHandler
Metadata IPropertySetStorage (inaktuell i Windows Vista) PropertyHandler
Fäst på Start-menyn IStartMenuPinnedList {a2a9545d-a0c2-42b4-9708-a0b2badd77c8}
Fäst i aktivitetsfältet {90AA3A4E-1CBA-4233-B8BB-535773D48449}

 

De undernycklar som anges för att lägga till Fäst till Start-menyn och Fäst i Aktivitetsfältet till ett objekts genvägsmeny krävs endast för filtyper som innehåller posten IsShortCut.

Stöd för kolumnproviderhanterare har tagits bort i Windows Vista. Från och med Windows Vista har IPropertySetStorage blivit inaktuell till förmån för IPropertyStore.

Även om IExtractImage fortfarande stöds, är IThumbnailProvider att föredra för Windows Vista och senare.

Fördefinierade gränssnittsobjekt

Gränssnittet definierar ytterligare objekt under HKEY_CLASSES_ROOT som kan utökas på samma sätt som filtyper. Om du till exempel vill lägga till en egenskapsbladshanterare för alla filer kan du registrera under PropertySheetHandlers nyckel.

HKEY_CLASSES_ROOT
   *
      shellex
         PropertySheetHandlers

Följande tabell innehåller de olika undernycklarna för HKEY_CLASSES_ROOT under vilka tilläggshanterare kan registreras. Observera att många tilläggshanterare inte kan registreras under alla undernycklar i listan. Mer information finns i den specifika hanterarens dokumentation.

Subnyckel Beskrivning Möjliga hanterare Version
* Alla filer Snabbmeny, egenskapsblad, verb (se nedan) Alla
AllaFilsystemObjekt Alla filer och filmappar Snabbmeny, egenskapsblad, verb 4.71
mapp Alla mappar Snabbmeny, egenskapsblad, verb Alla
Katalog Aktmappar Snabbmeny, egenskapsblad, verb Alla
Katalog\Bakgrund Mappbakgrund Endast snabbmeny 4.71
Drive Alla enheter i "Den här datorn", till exempel "C:\" Snabbmeny, egenskapsblad, verb Alla
Nätverk Hela nätverket (under Mina nätverksplatser) Snabbmeny, egenskapsblad, verb Alla
Nätverk\Typ\# Alla objekt av typen # (se nedan) Snabbmeny, egenskapsblad, verb 4.71
NetShare Alla nätverksandelar Snabbmeny, egenskapsblad, verb 4.71
NetServer Alla nätverksservrar Snabbmeny, egenskapsblad, verb 4.71
nätverksleverantör_namn Alla objekt som tillhandahålls av nätverksprovidern "network_provider_name" Snabbmeny, egenskapsblad, verb Alla
skrivare Alla skrivare Snabbmeny, egenskapsblad Alla
AudioCD Ljud-CD på CD-enhet Endast verb Alla
DVD DVD-enhet (Windows 2000) Snabbmeny, egenskapsblad, verb 4.71

 

Anteckningar:

  • Snabbmenyn för filmappens bakgrund nås genom att högerklicka i en filmapp, men inte över något av mappens innehåll.
  • "Verb" är specialkommandon som registrerats under HKEY_CLASSES_ROOT\Undernyckel\Shell\Verb .
  • För Network\Type\# är "#" en nätverksprovidertypkod i decimaltecken. Nätverksproviderns typkod är det höga ordet för en nätverkstyp. Listan över nätverkstyper anges i winnetwk.h-huvudfilen (WNNC_NET_*-värden). Till exempel är WNNC_NET_SHIVA 0x00330000, så motsvarande typnyckel skulle vara HKEY_CLASSES_ROOT\\Typ av nätverk\51 .
  • "network_provider_name" är ett nätverksleverantörsnamn som specificeras av WNetGetProviderName, där mellanslag har konverterats till understreck. Om till exempel Microsoft Networking-nätverksprovidern är installerad är providernamnet "Microsoft Windows Network" och motsvarande network_provider_name är Microsoft_Windows_Network.

Exempel på en tilläggshanterares registrering

Om du vill aktivera en viss hanterare skapar du en undernyckel under tilläggshanterarens typnyckel med namnet på hanteraren. Shell använder inte hanterarens namn, men det måste skilja sig från alla andra namn under den typen av undernyckel. Ange standardvärdet för namnundernyckeln till strängformen för hanterarens GUID.

I följande exempel visas registerposter som aktiverar snabbmeny- och egenskapsbladstilläggshanterare med hjälp av ett exempel på .myp-filtypen:

HKEY_CLASSES_ROOT
   .myp
      (Default) = MyProgram.1
   CLSID
      {00000000-1111-2222-3333-444444444444}
         InProcServer32
            (Default) = C:\MyDir\MyCommand.dll
            ThreadingModel = Apartment
      {11111111-2222-3333-4444-555555555555}
         InProcServer32
            (Default) = C:\MyDir\MyPropSheet.dll
            ThreadingModel = Apartment
   MyProgram.1
      (Default) = MyProgram Application
      Shellex
         ContextMenuHandler
            MyCommand
               (Default) = {00000000-1111-2222-3333-444444444444}
         PropertySheetHandlers
            MyPropSheet
               (Default) = {11111111-2222-3333-4444-555555555555}

Registreringsproceduren som beskrivs i det här avsnittet måste följas för alla Windows-system.

vägledning för att implementera In-Process-tillägg