Megosztás:


Az alapszintű mappaobjektum-felületek implementálása

A névtérbővítmény implementálásának eljárása hasonló minden más folyamaton belüli összetevő-objektummodell (COM) objektumhoz. Minden bővítménynek három elsődleges felületet kell támogatnia, amelyek biztosítják a Windows Intéző számára a bővítmény mappáinak fanézetben való megjelenítéséhez szükséges alapvető információkat. A Windows Intéző képességeinek teljes kihasználásához azonban a bővítménynek el kellérhetővé tennie egy vagy több olyan opcionális felületet is, amely támogatja a kifinomultabb funkciókat, például a helyi menüket vagy a húzást, és mappanézetet biztosít.

Ez a dokumentum bemutatja, hogyan implementálhatja a Windows Explorer által a bővítmény tartalmával kapcsolatos információkat hívó elsődleges és opcionális felületeket. A mappanézet implementálásáról és a Windows Intéző testreszabásáról a Mappanézet implementálásacímű témakörben olvashat.

Alapszintű megvalósítás és regisztráció

Folyamaton belüli COM-kiszolgálóként a DLL-nek több szabványos függvényt és felületet kell elérhetővé tennie:

Ezek a függvények és interfészek ugyanúgy vannak implementálva, mint a legtöbb más COM-objektum esetében. További részletekért tekintse meg a COM dokumentációját.

Bővítmény regisztrálása

Mint minden COM-objektum esetében, a bővítményhez is létre kell hoznia egy osztályazonosítót (CLSID). Regisztrálja az objektumot úgy, hogy létrehoz egy HKEY_CLASSES_ROOT\CLSID alkulcsot, amelyet az ön bővítményének CLSID-azonosítójáról nevez el. A DLL-t folyamaton belüli kiszolgálóként kell regisztrálni, és meg kell határoznia az apartman szálkezelési modellt. A bővítmény gyökérmappájának viselkedését úgy szabhatja testre, hogy különböző alkulcsokat és értékeket ad hozzá a bővítmény CLSID-kulcsához.

Ezen értékek közül több csak a virtuális csomópontokkal rendelkező bővítményekre vonatkozik. Ezek az értékek nem vonatkoznak azokra a bővítményekre, amelyek csatlakozási pontjai fájlrendszermappák. További információért tekintse meg Névtérbővítmény helyének megadásacímű témakört. Ha egy bővítmény viselkedését virtuális csatlakozási ponttal szeretné módosítani, adjon hozzá egy vagy több értéket a bővítmény CLSID-kulcsához:

  • El akarja érni a 2010-et. A virtuális csomóponttal rendelkező bővítmények elemzési neve általában a következő lesz: :{GUID}. Az ilyen típusú bővítmények általában virtuális elemeket tartalmaznak. Egyes bővítmények, például a Dokumentumok, valójában a fájlrendszer mappáinak felelnek meg, még akkor is, ha virtuális csomópontokkal rendelkeznek. Ha a bővítmény így jelöli a fájlrendszer objektumait, beállíthatja a WantsFORPARSING értéket. A Windows Intéző ezután kéri a gyökérmappa elemzési nevét úgy, hogy meghívja a mappaobjektum IShellFolder::GetDisplayNameOf metódusát, ahol uFlags értéke SHGDN_FORPARSING, és a pidl egyetlen üres mutatóra van állítva, amely egy elem-azonosító listára (PIDL) mutat. Az üres PIDL csak egy terminátort tartalmaz. A metódusnak ezután a gyökérmappa ::{GUID} elemzési nevét kell visszaadnia.
  • HideFolderVerbs. A HKEY_CLASSES_ROOT\Mappa alatt regisztrált igék általában minden bővítményhez vannak társítva. Ezek a bővítmény helyi menüjében jelennek meg, és a ShellExecutesegítségével hívhatók meg. Ha meg szeretné akadályozni, hogy ezek az igék a bővítményhez legyenek társítva, állítsa be a HideFolderVerbs értéket.
  • HideAsDelete. Ha egy felhasználó megpróbálja törölni a bővítményt, a Windows Intéző ehelyett elrejti a bővítményt.
  • HideAsDeletePerUser. Ez az érték ugyanaz, mint a HideAsDelete, de felhasználónkénti alapon. A bővítményt csak azok a felhasználók rejtik el, akik megpróbálták törölni. A bővítmény minden más felhasználó számára látható.
  • QueryForOverlay. Állítsa be ezt az értéket úgy, hogy jelezze, hogy a gyökérmappa ikonja átfedésben lehet egy ikonnal. A mappaobjektumnak támogatnia kell az IShellIconOverlay felületet. Mielőtt a Windows Intéző megjeleníti a gyökérmappa ikonját, egy átfedés ikont fog kérni a két IShellIconOverlay metódus egyikének meghívásával, pidlItem egy üres PIDL-ra van állítva.

A fennmaradó értékek és alkulcsok az összes bővítményre érvényesek:

  • A bővítmény csatlakozási pontmappájának megjelenítendő nevének megadásához állítsa a bővítmény CLSID-alkulcsának alapértelmezett értékét egy megfelelő sztringre.
  • Amikor a kurzor egy mappára mutat, általában megjelenik egy információs tipp, amely leírja a mappa tartalmát. A bővítmény gyökérmappájához tartozó infotip megadásához hozzon létre egy InfoTip REG_SZ értéket a bővítmény CLSID-kulcsához, és állítsa be egy megfelelő karakterláncra.
  • Ha egyéni ikont szeretne megadni a bővítmény gyökérmappájához, hozzon létre egy alkulcsot a bővítmény CLSID-alkulcsának DefaultIconnéven. Állítsa a DefaultIcon alapértelmezett értékét egy REG_SZ értékre, amely tartalmazza az ikont tartalmazó fájl nevét, majd egy vesszőt, majd egy mínuszjelet, majd a fájlban lévő ikon indexét.
  • Alapértelmezés szerint a bővítmény gyökérmappájának helyi menüje tartalmazza a HKEY_CLASSES_ROOT\Folderalatt definiált elemeket. A Delete, Rename, and Properties items is hozzá lesz adva, ha beállította a megfelelő SFGAO_XXX jelzőket. Hozzáadhat más elemeket a gyökérmappa helyi menüjéhez, vagy felülírhatja a meglévő elemeket, ugyanúgy, mint egy fájltípusesetében. Hozzon létre egy Shell- alkulcsot a bővítmény CLSID-kulcsa alatt, és definiálja a parancsokat a Helyi menük kiterjesztésecímű témakörben leírtak szerint.
  • Ha rugalmasabb módon szeretné kezelni a gyökérmappa helyi menüjét, implementálhat egy helyi menükezelőt. A helyi menükezelő regisztrálásához hozzon létre egy ShellEx kulcsot a bővítmény CLSID-kulcsa alatt. Regisztrálja a bővítmény-kezelő CLSID-azonosítóját, ahogyan egy hagyományos Creating Shell Extension Handlersesetén.
  • Ha fel szeretne adni egy lapot a gyökérmappa Tulajdonságok tulajdonságlapjára, adja meg a mappa SFGAO_HASPROPSHEET attribútumát, és implementáljon egy tulajdonságlapkezelőt. A tulajdonságlap-kezelő regisztrálásához hozzon létre egy ShellEx kulcsot a bővítmény CLSID-kulcsa alatt. Regisztrálja a kezelő CLSID-azonosítóját ugyanúgy, mint egy hagyományos Shell-bővítmény-kezelő létrehozásaesetén.
  • A gyökérmappa attribútumainak megadásához adjon hozzá egy ShellFolder alkulcsot a bővítmény CLSID-alkulcsához. Hozzon létre egy attribútumértéket, és állítsa be a SFGAO_XXX jelzők megfelelő kombinációjára.

Az alábbi táblázat felsorol néhány gyakran használt attribútumot a gyökérmappákhoz.

Zászló Érték Leírás
SFGAO_FOLDER 0x20000000 A bővítmény gyökérmappája egy vagy több elemet tartalmaz.
SFGAO_HASSUBFOLDER 0x80000000 A bővítmény gyökérmappája egy vagy több almappát tartalmaz. A Windows Explorer egy pluszjelet (+) helyez el a mappaikon mellé.
SFGAO_CANDELETE 0x00000020 A bővítmény gyökérmappáját a felhasználó törölheti. A mappa helyi menüjében megjelenik egy Delete elem. Ezt a jelölőt a virtuális mappákalá helyezett csomópontokhoz kell beállítani.
SFGAO_CANRENAME 0x00000010 A bővítmény gyökérmappáját a felhasználó átnevezheti. A mappa helyi menüjében megjelenik egy Átnevezés elem.
SFGAO_HASPROPSHEET 0x00000040 A bővítmény gyökérmappája egy Tulajdonságok tulajdonságlappal rendelkezik. A mappa helyi menüjében egy Tulajdonságok elem található. A tulajdonságlap megadásához implementálnia kell egy tulajdonságlap-kezelőt. Regisztrálja a kezelőt a bővítmény CLSID-kulcsa alatt, ahogy azt korábban már említettem.

 

Az alábbi példa egy MyExtension megjelenítendő névvel rendelkező bővítmény CLSID beállításjegyzék-bejegyzését mutatja be. A bővítmény egyéni ikonnal rendelkezik, amely a bővítmény DLL-jében található 1 indexkel. A SFGAO_FOLDER, SFGAO_HASSUBFOLDERés SFGAO_CANDELETE attribútumok be vannak állítva.

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

PIDL-k kezelése

A Rendszerhéj-névtér minden elemének egyedi PIDL-sel kell rendelkeznie. A Windows Intéző egy PIDL-t rendel a gyökérmappához, és az inicializáláskor továbbítja az értéket a bővítménynek. Ezután a bővítmény felelős egy megfelelően összeállított PIDL-nek az egyes objektumokhoz való hozzárendeléséért, és az ilyen PIDL-ek kérésre a Windows Intézőhöz való biztosításáért. Ha a Shell EGY PIDL-t használ a bővítmény egyik objektumának azonosításához, a bővítménynek képesnek kell lennie a PIDL értelmezésére és az adott objektum azonosítására. A bővítménynek hozzá kell rendelnie egy megjelenítendő nevet és egy elemzési nevet minden objektumhoz. Mivel a PIDL-eket gyakorlatilag minden mappafelület használja, a bővítmények általában egyetlen PIDL-kezelőt implementálnak, az összes feladat kezelésére.

A PIDL kifejezés egy ITEMIDLIST szerkezet vagy egy ilyen struktúra mutatója, a környezettől függően. A deklarált módon egy ITEMIDLIST struktúrának egyetlen tagja van, SHITEMID struktúrája. Az objektum ITEMIDLIST struktúrája valójában két vagy több SHITEMID szerkezetből álló tömb. Ezeknek a struktúráknak a sorrendje definiál egy elérési utat a névtéren keresztül, ugyanúgy, ahogyan a c:\MyDirectory\MyFile a fájlrendszeren keresztül definiál egy elérési utat. Az objektum PIDL-jét általában SHITEMID struktúrák sorozata alkotja, amelyek megfelelnek a névtér elérési útját meghatározó mappáknak, majd az objektum SHITEMID struktúrája, amelyet egy terminátor követ.

A terminátor egy SHITEMID szerkezet, amelynek cb tagja null . A végjel azért szükséges, mert az objektum PIDL-jében lévő SHITEMID struktúrák száma az objektum Shell névtérbeli helyétől és az elérési út kiindulópontjától függ. Ezenkívül a különböző SHITEMID struktúrák mérete eltérő lehet. Ha PIDL-t kap, nincs egyszerű módja annak méretének vagy akár a SHITEMID struktúrák teljes számának meghatározására. Ehelyett "végig kell járnia" a csomagolt tömböt, egyik struktúráról a másikra, amíg el nem éri a terminátort.

PIDL létrehozásához az alkalmazásnak a következőre van szüksége:

  1. Hozzon létre egy SHITEMID struktúrát az egyes objektumokhoz.
  2. Állítsa össze a vonatkozó SHITEMID struktúrákat egy PIDL-be.

SHITEMID-struktúra létrehozása

Az objektum SHITEMID struktúrája egyedileg azonosítja az objektumot a mappájában. A IShellFolder metódusok által használt PIDL-típus valójában csak az objektum SHITEMID szerkezetéből áll, amelyet egy terminátor követ. A SHITEMID-struktúra definíciója a következő:

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

Az abID tag az objektum azonosítója. Mivel a abID hossza nincs meghatározva, és eltérő lehet, a cb tag a SHITEMID szerkezet méretére van állítva bájtban.

Mivel sem az abID hossza, sem tartalma nem szabványosított, bármilyen sémát használhat, amelyet abID értékeket szeretne hozzárendelni az objektumokhoz. Az egyetlen követelmény, hogy nem lehet két objektum ugyanabban a mappában azonos értékekkel. Teljesítménybeli okokból azonban a SHITEMID struktúrának DWORDkell igazodnia. Más szóval, úgy kell létrehoznia a abID értékeket, hogy a cb a 4 szerves többszörösei legyenek.

Az abID- általában egy bővítmény által definiált struktúrára mutatnak. Az objektum azonosítója mellett ezt a struktúrát gyakran használják különböző kapcsolódó információk, például az objektum típusa vagy attribútumai tárolására. A bővítmény mappaobjektumai ezután gyorsan kinyerhetik az információkat a PIDL-ből ahelyett, hogy le kellene kérdezni.

Jegyzet

A PIDL-hez készült adatstruktúra tervezésének egyik legfontosabb szempontja, hogy a struktúra megőrizhető és szállítható legyen. A PIDL-k kontextusában a következő kifejezések jelentése van:

  • Megőrizhető. A rendszer gyakran helyezi el a PIDL-eket a hosszú távú tárolás különböző típusaiban, például a parancsikonfájlokban. Ezt követően később helyreállíthatja ezeket a PIDL-eket a tárolóból, valószínűleg a rendszer újraindítása után. A tárolóból helyreállított PIDL-nek továbbra is érvényesnek és értelmezhetőnek kell lennie a bővítmény számára. Ez a követelmény például azt jelenti, hogy a PIDL-struktúrában ne használjon mutatókat vagy fogópontokat. Az ilyen típusú adatokat tartalmazó PIDL-k általában értelmetlenek lesznek, amikor a rendszer később helyreállítja őket a tárolóból.
  • Hordozható. A PIDL-nek értelmesnek kell maradnia, ha az egyik számítógépről a másikra kerül át. A PIDL például írható egy parancsikonfájlba, átmásolható egy hajlékonylemezre, és áthelyezhető egy másik számítógépre. Ennek a PIDL-nek továbbra is hasznosnak kell lennie a második számítógépen futó bővítmény számára. Ha például biztosítani szeretné, hogy a PIDL-ek szállíthatók legyenek, használjon kifejezetten ANSI- vagy Unicode-karaktereket. Kerülje az adattípusokat, például TCHAR vagy LPTSTR. Ha ezeket az adattípusokat használja, a bővítmény Unicode-verzióját futtató számítógépen létrehozott PIDL-t a bővítmény ANSI-verziója nem fogja olvasni egy másik számítógépen.

 

Az alábbi deklaráció egy egyszerű adatstruktúra-példát mutat be.

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

A cb tag a MYPIDLDATA struktúrájának méretére van állítva. Ez a tag önmagában érvényes SHITEMID struktúrát képez, a MYPIDLDATA elemmel. A többi tag egyenértékű az abIDSHITEMID struktúrájának tagjaival, és privát adatokat tárol. A dwType tag egy bővítmény által definiált érték, amely az objektum típusát jelzi. Ebben a példában a dwType a mappák esetében TRUE értékre van állítva, egyébként FALSE értéket kap. Ez a tag például lehetővé teszi, hogy gyorsan megállapítsa, hogy az objektum mappa-e vagy sem. A wszDisplayName tag tartalmazza az objektum megjelenítendő nevét. Mivel ugyanazt a megjelenítendő nevet nem rendelné hozzá ugyanabban a mappában lévő két különböző objektumhoz, a megjelenítendő név is objektumazonosítóként szolgál. Ebben a példában wszDisplayName 40 karakterre van állítva, hogy a SHITEMID szerkezet DWORDlegyen igazítva. A PIDL-k méretének korlátozásához ehelyett használhat változó hosszúságú karaktertömböt, és ennek megfelelően módosíthatja a cb értékét. A megjelenítési karakterláncot elég '\0' karakterrel kell kitölteni, hogy fenntartsa a szerkezet DWORD igazítását. A szerkezetben hasznos lehet más tagok is, például az objektum mérete, attribútumai vagy elemzési neve.

PIDL létrehozása

Miután definiálta SHITEMID struktúrákat az objektumokhoz, használhatja őket egy PIDL létrehozására. A PIDL-ek többféle célra is létrehozhatók, de a legtöbb feladat kétféle PIDL-típus egyikét használja. A legegyszerűbb, egyszintű PIDL azonosítja az objektumot a szülőmappához képest. Ezt a PIDL-t számos IShellFolder metódus használja. Az egyszintű PIDL tartalmazza az objektum SHITEMID szerkezetét, amelyet egy terminátor követ. A teljes körűen minősített PIDL a névtérhierarchia útvonalát határozza meg az asztaltól az objektumig. Az ilyen típusú PIDL az asztalon kezdődik, és egy SHITEMID struktúrát tartalmaz az elérési úton található minden mappához, ezt követi az objektum és a terminátor. Egy teljesen minősített PIDL egyedileg azonosítja az objektumot a teljes Shell-névtérben.

A PIDL létrehozásának legegyszerűbb módja, ha közvetlenül a ITEMIDLIST struktúrával dolgozik. Hozzon létre egy ITEMIDLIST struktúrát, de elegendő memóriát foglaljon le az összes SHITEMID struktúrák tárolásához. A struktúra címe a SHITEMID kezdeti struktúrára mutat. Adjon meg értékeket a kezdeti struktúra tagjainak, majd fűzze hozzá a szükséges számú további SHITEMID struktúrákat a megfelelő sorrendben. Az alábbi eljárás egy egyszintű PIDL létrehozását ismerteti. Két SHITEMID struktúrát tartalmaz – egy MYPIDLDATA struktúrát, amelyet egy terminátor követ:

  1. A CoTaskMemAlloc függvénnyel foglaljon le memóriát a PIDL számára. Foglaljon le elegendő memóriát saját adataihoz, valamint egy USHORT (két bájt) a terminátor számára. Alakítsa át az eredményt LPMYPIDLDATA-vá.
  2. Állítsa be az első MYPIDLDATA struktúra 'cb' tagját a struktúra méretére. Ebben a példában a cb értékét a MYPIDLDATA méretére állítaná be. Ha változó hosszúságú struktúrát szeretne használni, ki kell számítania a cbértékét.
  3. Rendelje hozzá a megfelelő értékeket a privát adattagokhoz.
  4. Számítsa ki a következő SHITEMID szerkezet címét. Adja hozzá az aktuális MYPIDLDATA struktúra címét az LPBYTE-hez, és adja hozzá ezt az értéket a 3. lépésben meghatározott cb értékéhez.
  5. Ebben az esetben a következő SHITEMID szerkezet a terminátor. Állítsa a szerkezet cb tagját nullára.

Hosszabb PIDL-ek esetén foglalja le a megfelelő memóriát, és ismételje meg a 3–5. lépést minden további SHITEMID struktúrához.

Az alábbi mintafüggvény egy objektum típusát és megjelenítendő nevét veszi fel, és visszaadja az objektum egyszintű PIDL-jét. A függvény feltételezi, hogy a megjelenítendő név , beleértve annak null karakterét is, nem lépi túl a MYPIDLDATA struktúrához deklarált karakterek számát. Ha ez a feltételezés tévesnek bizonyul, a StringCbCopyW függvény csonkolja a megjelenítendő nevet. A g_pMalloc változó egy máshol létrehozott és globális változóban tárolt IMallocmutató.

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;

A teljesen minősített PIDL-nek SHITEMID struktúrákkal kell rendelkeznie az asztaltól kezdve minden objektumhoz az Ön objektumáig. A bővítmény teljes mértékben minősített PIDL-t kap a gyökérmappához, amikor a Shell meghívja IPersistFolder::Initialize. Ha teljesen minősített PIDL-t szeretne létrehozni egy objektumhoz, vegye fel a Shell által a gyökérmappához rendelt PIDL-t, és fűzze hozzá a SHITEMID struktúrákat, amelyek szükségesek ahhoz, hogy a gyökérmappából az objektumhoz vigye.

A PIDL-ek értelmezése

Amikor a Shell vagy egy alkalmazás meghívja a bővítmény egyik felületét, hogy adatokat kérjen egy objektumról, általában egy PIDL azonosítja az objektumot. Egyes metódusok, például IShellFolder::GetUIObjectOf, a szülőmappához viszonyítva, könnyen értelmezhető PIDL-eket használnak. A bővítmény azonban valószínűleg teljes körűen minősített PIDL-eket is kap. A PIDL-kezelőnek ezután meg kell határoznia, hogy melyik objektumra hivatkozik a PIDL.

Ami bonyolítja az objektumok teljes mértékben minősített PIDL-vel való társításának feladatát, az az, hogy a PIDL kezdeti SHITEMID egy vagy több struktúrája olyan objektumokhoz tartozhat, amelyek a Shell névterében található bővítményen kívül vannak. Ön képtelen értelmezni az abID tag jelentését. A bővítménynek végig kell mennie a SHITEMID struktúrák listáján, amíg el nem éri a gyökérmappának megfelelő struktúrát. Ettől kezdve tudni fogja, hogyan értelmezheti az információkat a SHITEMID struktúrákban.

A PIDL bejárásához vegyük az első cb értéket, és adjuk hozzá a PIDL címéhez, hogy a mutatót a következő SHITEMID struktúra elejére állítsuk. Ezután a szerkezet cb tagjára mutat, amellyel az egérmutatót a következő SHITEMID szerkezet elejére helyezheti, és így tovább. Minden alkalommal, amikor előrébb lép a mutatóval, vizsgálja meg a SHITEMID struktúrát annak megállapításához, hogy elérte-e a bővítmény névterének gyökérszintjét.

Az elsődleges felületek implementálása

Mint minden COM-objektum esetén, a bővítmények implementálása nagyrészt interfészek gyűjteményének implementálásán múlik. Ez a szakasz a három elsődleges felületet ismerteti, amelyeket minden bővítménynek végre kell hajtania. Ezek az inicializáláshoz és a Windows Intézőnek a bővítmény tartalmával kapcsolatos alapvető információk biztosításához használhatók. Ezek a felületek, valamint a mappanézetmind szükségesek a funkcionális bővítményekhez. A Windows Explorer funkcióinak teljes kihasználásához azonban a legtöbb bővítmény egy vagy több opcionális felületet is implementál.

IPersistFolder felület

A rendszer meghívja az IPersistFolder felületet egy új mappaobjektum inicializálásához. Az IPersistFolder::Initialize metódus egy teljesen minősített PIDL-t rendel az új objektumhoz. Tárolja ezt a PIDL-t későbbi használatra. Egy mappaobjektumnak például ezt a PIDL-t kell használnia ahhoz, hogy teljesen minősített PIDL-eket hozzon létre az objektum gyermekei számára. A mappaobjektum létrehozója meghívhatja IPersist::GetClassID is az objektum CLSID-azonosítójának lekéréséhez.

A mappaobjektumokat általában a szülőmappa IShellFolder::BindToObject metódusa hozza létre és inicializálja. Amikor azonban egy felhasználó megkeresi a bővítményt, a Windows Intéző létrehozza és inicializálja a bővítmény gyökérmappájának objektumát. A gyökérmappa-objektum a IPersistFolder::Initialize segítségével az asztaltól a gyökérmappáig tartó elérési utat kapja meg, amelyre szüksége van a bővítményhez szükséges teljesen minősített PIDL-ek összeállításához.

IShellFolder-felület

A Shell egy bővítményt mappaobjektumok hierarchikusan rendezett gyűjteményeként kezel. Az IShellFolder felület a bővítmények implementációjának központi eleme. Ez egy mappaobjektumot jelöl, és a Windows Intézőben a mappa tartalmának megjelenítéséhez szükséges információk nagy részét biztosítja.

IShellFolder általában az egyetlen olyan mappafelület, amely nem IPersistFolder, amelyet közvetlenül egy mappaobjektum fed le. Bár a Windows Intéző számos szükséges és opcionális felületet használ a mappa tartalmával kapcsolatos információk beszerzéséhez, ezekhez a felületekhez az IShellFolderkeresztül jut hozzá.

A Windows Intéző számos módon lekéri a bővítményed gyökérmappájának CLSID-azonosítóját. További információ: Névtérbővítmény helyének megadása vagy A névtérbővítménySelf-Contained nézetének megjelenítése. A Windows Intéző ezt a CLSID-t használja a gyökérmappa egy példányának létrehozásához és inicializálásához, valamint egy IShellFolder interfész lekérdezéséhez. A bővítmény létrehoz egy mappaobjektumot, amely a gyökérmappát jelöli, és visszaadja az objektum IShellFolder felületét. A bővítmény és a Windows Intéző közötti interakció nagy része ezután IShellFolderkeresztül történik. A Windows Intéző meghívja IShellFolder az alábbi művelethez:

  • Kérjen egy objektumot, amely számba tudja adni a gyökérmappa tartalmát.
  • Szerezze be a gyökérmappa tartalmával kapcsolatos különböző típusú információkat.
  • Kérjen egy objektumot, amely elérhetővé teszi az egyik választható felületet. Ezek a felületek ezután további információkért, például ikonokért vagy helyi menükért kérdezhetők le.
  • Kérjen egy mappaobjektumot, amely a gyökérmappa almappáját jelöli.

Amikor egy felhasználó megnyitja a gyökérmappa almappáját, a Windows Intéző meghívja IShellFolder::BindToObject. A bővítmény létrehoz és inicializál egy új mappaobjektumot, amely az almappát jelöli, és visszaadja a IShellFolder felületét. A Windows Intéző ezután meghívja ezt a felületet különböző típusú információkhoz, és így tovább, amíg a felhasználó úgy nem dönt, hogy a Shell névterében máshol navigál, vagy bezárja a Windows Intézőt.

A szakasz hátralévő része röviden ismerteti az IShellFolder metódusok fontosabb elemeit és azok megvalósításának módját.

EnumObjects

Mielőtt megjelenítené egy mappa tartalmát a fanézetben, a Windows Intézőnek először meg kell határoznia, hogy mit tartalmaz a mappa a IShellFolder::EnumObjects metódus meghívásával. Ez a metódus létrehoz egy szabványos OLE enumerálási objektumot, amely elérhetővé tesz egy IEnumIDList felületet, és visszaadja az illesztőmutatót. Az IEnumIDList felület lehetővé teszi, hogy a Windows Intéző lekérje a mappa összes tartalmazott objektumának a PIDL-jét. Ezek a PIDL-k ezután a mappa által tartalmazott objektumokra vonatkozó információk lekérésére szolgálnak. További részletekért lásd IEnumIDList interface.

Jegyzet

A IEnumIDList::Következő metódus csak a szülőmappához viszonyított PIDL-eket adja vissza. A PIDL-nek csak az objektum SHITEMID szerkezetét kell tartalmaznia, amelyet egy terminátor követ.

 

CreateViewObject

Mielőtt a mappa tartalma megjelenne, a Windows Intéző meghívja ezt a metódust, hogy kérést tegyen egy mutatóra az IShellView felülethez. A Windows Intéző ezt a felületet használja a mappa nézetének kezelésére. Hozzon létre egy mappanézet-objektumot, és adja vissza a IShellView felületét.

A IShellFolder::CreateViewObject metódust is meghívjuk, hogy kérje a mappa egyik opcionális felületét, például IContextMenu. A metódus implementálásának létre kell hoznia egy objektumot, amely elérhetővé teszi a kért felületet, és visszaadja a felület mutatóját. Ha a Windows Intézőnek szüksége van egy opcionális felületre a mappa egyik objektumához, meghívja IShellFolder::GetUIObjectOf.

GetUIObjectOf

Bár a mappa tartalmával kapcsolatos alapvető információk az IShellFolder metódusokon keresztül érhetők el, a bővítmény számos további információt is biztosít a Windows Intézőnek. Megadhat például ikonokat egy mappa vagy egy objektum helyi menüjének tartalmához. A Windows Intéző meghívja a IShellFolder::GetUIObjectOf metódust, hogy megpróbáljon további információkat lekérni egy mappa által tartalmazott objektumról. A Windows Intéző megadja, hogy melyik objektumhoz szeretné megadni az információkat, és a megfelelő felület IID-azonosítóját. A mappaobjektum ezután létrehoz egy objektumot, amely elérhetővé teszi a kért felületet, és visszaadja a felület mutatóját.

Ha a bővítmény lehetővé teszi, hogy a felhasználók objektumokat vigyenek át húzással vagy vágólap segítségével, a Windows Intéző meghívja a IShellFolder::GetUIObjectOf-t, hogy kérjen egy IDataObject vagy IDropTarget interfészt. További információkért lásd: Shell-objektumok átvitele húzással és ejtéssel, valamint a vágólap használatával.

A Windows Intéző meghívja a IShellFolder::CreateViewObject metódust, amikor azt akarja, hogy ugyanazt a fajta információt kapja meg magáról a mappáról.

BindToObject

A Windows Intéző meghívja a IShellFolder::BindToObject metódust, amikor egy felhasználó megkísérli megnyitni a bővítmény egyik almappáját. Ha riid IID_IShellFolder van beállítva, létre kell hoznia és inicializálnia kell egy olyan mappaobjektumot, amely az almappát jelöli, és visszaadja az objektum IShellFolder felületét.

Jegyzet

A Windows Intéző jelenleg csak egy IShellFolder interfész kérésére hívja meg ezt a módszert. Ne feltételezzük azonban, hogy ez mindig így lesz. A folytatás előtt mindig ellenőrizze a riid értékét.

 

GetDisplayNameOf

A Windows Intéző meghívja a IShellFolder::GetDisplayNameOf metódust a mappa egyik objektumának PIDL-jének névvé alakításához. Ennek a PIDL-nek az objektum szülőmappájához viszonyítva kell lennie. Más szóval egyetlen nemNULLSHITEMID struktúrát kell tartalmaznia. Mivel az objektumok elnevezésének több módja is van, a Windows Intéző egy vagy több SHGDNF jelző beállításával adja meg a név típusát az uFlags paraméterben. A két érték (SHGDN_NORMAL vagy SHGDN_INFOLDER) egyikének meg kell adnia, hogy a név a mappához vagy az asztalhoz viszonyítva legyen-e. A másik három érték egyike, SHGDN_FOREDITING, SHGDN_FORADDRESSBARvagy SHGDN_FORPARSINGmegadhatja, hogy a név mire lesz használva.

A nevet STRRET szerkezet formájában kell visszaadnia. Ha SHGDN_FOREDITING, SHGDN_FORADDRESSBARés SHGDN_FORPARSING nincs beállítva, adja vissza az objektum megjelenítendő nevét. Ha a SHGDN_FORPARSING jelző be van állítva, a Windows Intéző elemzési nevet kér. Elemző nevek IShellFolder::ParseDisplayName kapják meg az objektum PIDL-jét, annak ellenére, hogy egy vagy több szinttel lejjebb található az aktuális mappa alatt a névtér hierarchiában. Például egy fájlrendszer-objektum elemzési neve az elérési útja. A fájlrendszer bármely objektumának teljes elérési útját átadhatja a rendszer asztalának IShellFolder::ParseDisplayName metódusának, és visszaadja az objektum teljes elérési úttal rendelkező PIDL-jét.

Bár a nevek elemzésekor a szövegstringek nem kell feltétlenül tartalmazni a megjelenítendő nevet. Elemzési neveket kell hozzárendelnie annak alapján, hogy mi működik a leghatékonyabban, amikor az IShellFolder::ParseDisplayName meghívásra kerül. A Shell számos virtuális mappája például nem része a fájlrendszernek, és nem rendelkezik teljes elérési útokkal. Ehelyett minden mappához guid azonosító van rendelve, és az elemzés neve a következő formában történik: :{GUID}. Függetlenül attól, hogy milyen sémát használ, képesnek kell lennie megbízhatóan "oda-vissza". Ha például egy hívó egy elemzési nevet ad át IShellFolder::P arseDisplayName az objektum PIDL-jének lekéréséhez, majd átadja a PIDL-t IShellFolder::GetDisplayNameOf a SHGDN_FORPARSING jelzőkészlettel, a hívónak helyre kell állítania az eredeti elemzési nevet.

GetAttributesOf

A Windows Intéző meghívja a IShellFolder::GetAttributesOf metódust egy vagy több mappaobjektum által tartalmazott elem attribútumainak meghatározásához. A cidl értéke adja meg a lekérdezés elemeinek számát, és aPidl a PIDL-ek listájára mutat.

Mivel bizonyos attribútumok tesztelése időigényes lehet, a Windows Intéző általában az elérhető jelzők egy részhalmazára korlátozza a lekérdezést úgy, hogy rfgInOutértékeket állít be. A metódusnak csak azokat az attribútumokat kell tesztelnie, amelyeknek a jelzői rfgInOutvannak beállítva. Hagyja meg az érvényes jelzőket, és törölje a többit. Ha a lekérdezés egynél több elemet tartalmaz, csak az összes elemre érvényes jelzőket állítsa be.

Jegyzet

Az attribútumokat megfelelően kell beállítani ahhoz, hogy egy elem megfelelően jelenjen meg. Például, ha egy elem olyan mappa, amely almappákat tartalmaz, be kell állítania a SFGAO_HASSUBFOLDER jelzőt. Ellenkező esetben a Windows Intéző nem jelenít meg + jelet az elem ikonjának oldalán a fa nézetben.

 

ParseDisplayName

Az IShellFolder::ParseDisplayName metódus bizonyos értelemben tükrözött képe IShellFolder::GetDisplayNameOf. Ennek a módszernek a leggyakoribb módja az objektum elemzési nevének konvertálása a társított PIDL-be. Az elemzési név hivatkozhat bármely objektumra, amely a névtérhierarchia mappája alatt található. A visszaadott PIDL a metódust közzétesző mappaobjektumhoz képest van, és általában nem teljes mértékben minősített. Más szóval, bár a PIDL számos SHITEMID struktúrát tartalmazhat, az első vagy az objektum önmagában lesz, vagy az objektum elérési útjának első almappája. A hívónak hozzá kell fűznie ezt a PIDL-t a mappa teljes mértékben minősített PIDL-éhez, hogy beszerezze az objektumhoz tartozó teljes PIDL-t.

IShellFolder::P arseDisplayName is meghívható egy objektum attribútumainak lekéréséhez. Mivel az összes alkalmazható attribútum meghatározása időigényes lehet, a hívó csak azokat a SFGAO_XXX jelzőket állítja be, amelyek a hívó érdeklődésére vonatkozó információkat jelölik. Meg kell határoznia, hogy ezek közül az attribútumok közül melyik igaz az objektumra, és törölje a többi jelölőt.

IEnumIDList felület

Amikor a Windows Intézőnek számba kell vennie a mappa által tartalmazott objektumokat, meghívja IShellFolder::EnumObjects. A mappaobjektumnak létre kell hoznia egy enumerálási objektumot, amely elérhetővé teszi az IEnumIDList felületet, és visszaadja az illesztőmutatót. A Windows Intéző ezután általában IEnumIDList használatával számba veszi a mappa által tartalmazott összes objektum PIDL-jeit.

IEnumIDList egy szabványos OLE enumerálási felület, és a szokásos módon implementálva van. Ne feledje azonban, hogy a visszaadott PIDL-nek a mappához képest kell lennie, és csak az objektum SHITEMID szerkezetét és egy terminátort kell tartalmaznia.

Az opcionális felületek implementálása

A bővítmény mappaobjektumai számos választható Shell-felületet támogathatnak. Számos közülük, például IExtractIcon, lehetővé teszi a felhasználó által a bővítmény megtekintésének különböző aspektusainak testreszabását. Mások, például IDataObject, lehetővé teszik, hogy a bővítmény támogassa az olyan funkciókat, mint a húzás.

Az opcionális felületek egyikét sem teszi elérhetővé közvetlenül egy mappaobjektum. Ehelyett a Windows Intéző két IShellFolder függvény egyikét hívja meg egy felület lekéréséhez.

  • A Windows Intéző meghívja a mappaobjektum IShellFolder::GetUIObjectOf függvényét, hogy lekérjen egy interfészt a mappa által tartalmazott objektumok egyikéhez.
  • A Windows Intéző felhívja a mappa objektum IShellFolder::CreateViewObject-t a mappa felületének lekéréséhez.

Az információk megadásához a mappaobjektum létrehoz egy objektumot, amely elérhetővé teszi a kért felületet, és visszaadja a felület mutatóját. A Windows Intéző ezután meghívja ezt a felületet a szükséges információk lekéréséhez. Ez a szakasz a leggyakrabban használt opcionális felületeket ismerteti.

IExtractIcon

A Windows Intéző egy IExtractIcon interfészt kér, mielőtt megjelenítené a mappa tartalmát. A felület lehetővé teszi, hogy a bővítmény egyéni ikonokat adjon meg a mappa által tartalmazott objektumokhoz. Ellenkező esetben a szabványos fájl- és mappaikonok lesznek használatban. Egyéni ikon megadásához hozzon létre egy ikonkinyerési objektumot, amely elérhetővé teszi IExtractIcon, és visszaad egy mutatót az adott felületre. További információért tekintse meg az IExtractIcon referenciadokumentációját, vagy Ikonkezelők létrehozása.

IContextMenu

Amikor egy felhasználó jobb gombbal kattint egy objektumra, a Windows Intéző IContextMenu interfészt kér. Ha gyorsmenüket szeretne biztosítani az objektumokhoz, hozzon létre egy menükezelő objektumot, és adja meg a IContextMenu interfészt.

A menükezelő objektum létrehozásának eljárásai nagyon hasonlóak a menükezelő Shell-bővítményének létrehozásához használt eljárásokhoz. További információ: Helyi menükezelők létrehozása vagy az IContextMenu, IContextMenu2vagy IContextMenu3 hivatkozás.

IQueryInfo

A Windows Intéző meghívja az IQueryInfo felületet egy infotip szöveges sztring lekéréséhez.

IDataObject és IDropTarget

Amikor a Windows Intéző megjeleníti az objektumokat, a mappaobjektumoknak nincs közvetlen módja annak, hogy megtudják, mikor próbál meg kivágni, másolni vagy húzni egy objektumot. Ehelyett a Windows Intéző egy IDataObject felületet kér. Az objektum átvitelének engedélyezéséhez hozzon létre egy adatobjektumot, és adjon vissza egy mutatót a IDataObject felületére.

Hasonlóképpen, előfordulhat, hogy a felhasználó megpróbál egy adatobjektumot az egyik objektumOt ábrázoló Windows Intézőbe dobni, például egy ikont vagy egy címsor elérési útját. A Windows Intéző ezután egy IDropTarget interfészt kér. Az adatobjektum elvetéséhez hozzon létre egy objektumot, amely elérhetővé tesz egy IDropTarget felületet, és adja vissza a felület mutatóját.

Az adatátvitel kezelése a névtérbővítmények írásának egyik trükkösebb aspektusa. Részletes ismertetésért lásd: Shell-objektumok átvitele húzással és vágólap.

Az Alapértelmezett shell mappa nézetének implementációjával való munka

Az alapértelmezett Shell-mappanézeti objektumot (DefView) használó adatforrásoknak a következő interfészeket kell implementálniuk:

Opcionálisan, implementálhatják a IPersistFolder3.