Megosztás:


Információk lekérése egy mappa tartalmáról

A Mappa azonosítójának lekérése szakasz két módszert tárgyalt egy névtérobjektum mutatójának egy elemazonosító-listához (PIDL) való lekéréséhez. Az egyik nyilvánvaló kérdés: Ha már van egy PIDL, mit tehet vele? Egy kapcsolódó kérdés a következő: Mi a teendő, ha egyik megközelítés sem működik, vagy megfelel az alkalmazásnak? A mindkét kérdésre adott válaszhoz közelebbről meg kell vizsgálni a névtér implementálását. A kulcs az IShellFolder felület.

Az IShellFolder felület használata

A dokumentáció korábbi részében a névtérmappákat objektumoknak nevezték. Bár ezen a ponton a kifejezést laza értelemben használták, valójában szigorú értelemben is igaz. Minden névtérmappát egy komponensobjektum-modell (COM) objektum jelöl. Minden mappaobjektum számos olyan felületet tesz elérhetővé, amelyek sokféle feladathoz használhatók. Előfordulhat, hogy egyes választható interfészeket nem minden mappa fedi fel. Azonban minden mappának el kell fednie az alapvető felületet, IShellFolder.

A mappaobjektumok használatának első lépése egy mutató lekérése a IShellFolder felületére. Amellett, hogy hozzáférést biztosít az objektum többi felületéhez, IShellFolder olyan metódusok egy csoportját teszi elérhetővé, amelyek számos gyakori feladatot kezelnek, amelyek közül többről ebben a szakaszban olvashat.

Ha egy névtérobjektum IShellFolder felületére szeretne mutatót lekérni, először meg kell hívnia SHGetDesktopFolder. Az asztali névtér-gyökér, a desktop, IShellFolder felületére mutató mutatót ad vissza ez a függvény. Ha már rendelkezik az asztal IShellFolder felületével, többféleképpen is továbbléphet.

Ha már rendelkezik a kívánt mappa PIDL-jével – például az SHGetFolderLocationmeghívásával –, lekérheti a IShellFolder felületét az asztal IShellFolder::BindToObject metódus meghívásával. Ha rendelkezik egy fájlrendszer-objektum elérési útjával, először be kell szereznie a PIDL-t az asztal IShellFolder::ParseDisplayName metódus meghívásával, majd meg kell hívnia a IShellFolder::BindToObject. Ha egyik módszer sem alkalmazható, más IShellFolder metódusokkal navigálhat a névtérben. További információ: A névtérnavigálása.

Mappa tartalmának számbavétele

Általában az első dolog, amit egy mappával szeretne elvégezni, az, hogy megtudja, mit tartalmaz. Először meg kell hívnia a mappa IShellFolder::EnumObjects metódust. A mappa létrehoz egy szabványos OLE enumerálási objektumot, és visszaadja IEnumIDList felületét. Ez a felület négy szabványos metódust biztosít:Klónozás, Következő, Visszaállításés Átlépés, amelyek a mappa tartalmának felsorolására használhatók.

A mappa tartalmának felsorolásának alapművelete a következő:

  1. Hívja meg a IShellFolder::EnumObjects metódust, hogy lekérjen egy mutatót egy enumerációs objektum IEnumIDList interfészére.
  2. Adj egy nem allokált PIDL-t IEnumIDList::Next. Következő gondoskodik a PIDL kiosztásáról, de az alkalmazásnak fel kell szabadítania, ha már nincs rá szükség. Amikor következő visszatér, a PIDL csak az objektum elemazonosítóját és a lezáró NULL karaktereket tartalmazza. Más szóval ez egy egyszintű PIDL a mappához képest, nem pedig egy teljes körű PIDL.
  3. Ismételje meg a 2. lépést, amíg a visszaadja az S_FALSE értéket, jelezve, hogy minden elem felsorolása befejeződött.
  4. Hívja meg IEnumIDList::Release a számbavételi objektum kiadásához.

Jegyzet

Fontos nyomon követni, hogy teljes vagy relatív PIDL-lel dolgozik-e. Egyes függvények és metódusok bármelyiket elfogadják, míg mások csak egyet vagy egyet.

 

A fennmaradó három IEnumIDList metódus (Visszaállítás, Kihagyásés Klónozás) akkor hasznos, ha a mappa ismételt felsorolását kell elvégeznie. Lehetővé teszik az enumerálás alaphelyzetbe állítását, egy vagy több objektum kihagyását, és az állapot megőrzése érdekében másolatot készíthet az enumerálási objektumról.

Megjelenítendő nevek és egyéb tulajdonságok meghatározása

Miután számba vett minden olyan PIDL-t, amelyet egy mappa tartalmaz, megtudhatja, hogy milyen típusú objektumokat jelölnek. Az IShellFolder felület számos hasznos módszert kínál, amelyek közül kettőt itt tárgyalunk. Az egyéb IShellFolder metódusokról és más Shell-mappaillesztőkről később lesz szó.

Az egyik leg hasznosabb tulajdonság az objektum megjelenítendő neve. Egy objektum megjelenítési nevének eléréséhez adja át PIDL-jét a IShellFolder::GetDisplayNameOffüggvénynek. Bár az objektum a névtér szülőmappája alatt bárhol elhelyezhető, a PIDL-nek a mappához viszonyítva kell lennie.

IShellFolder::GetDisplayNameOf egy STRRET struktúra részeként adja vissza a megjelenítendő nevet. Mivel a megjelenítendő név kinyerése egy STRRET struktúrából kissé bonyolult lehet, a Shell két függvényt biztosít, amelyek elvégezik a feladatot, StrRetToStr és StrRetToBuf. Mindkét függvény STRRET struktúrát használ, és a megjelenítendő nevet normál sztringként adja vissza. Ezek csak a sztring lefoglalásában különböznek.

A megjelenítendő név mellett az objektumok számos attribútummal is rendelkezhetnek, például azt, hogy mappa vagy áthelyezhető-e. Az objektum attribútumai lekérhetők úgy, hogy a PIDL-t átadja IShellFolder::GetAttributesOf. Az attribútumok teljes listája meglehetősen nagy, ezért a részletekért tekintse meg a hivatkozást. Vegye figyelembe, hogy az GetAttributesOf-nak átadott PIDL-nek egyszintűnek kell lennie. Különösen, az IShellFolder::GetAttributesOf elfogadja az IEnumIDList::Nextáltal visszaadott PIDL-eket. Egy PIDL-ekből álló tömböt megadhatsz, és a GetAttributesOf visszaadja azokat az attribútumokat, amelyekben a tömbben lévő összes objektum megegyezik.

Ha rendelkezik egy objektum teljes elérési útjával vagy PIDL-jával, SHGetFileInfo egyszerűen lekérhet egy olyan objektumra vonatkozó információt, amely számos célra elegendő. SHGetFileInfo egy teljesen minősített elérési utat vagy PIDL-t használ, és számos információt ad vissza az objektumról, például:

  • Az objektum megjelenítendő neve
  • Az objektum attribútumai
  • Az objektum ikonjainak fogantyúi
  • A rendszerképek listájának fogantyúja
  • Az objektum ikonját tartalmazó fájl elérési útja

Mutató lekérése egy almappa IShellFolder interfészére

Az IShellFolder::GetAttributesOf meghívásával és a SFGAO_FOLDER jelző beállításának ellenőrzésével megállapíthatja, hogy a mappa tartalmaz-e almappákat. Ha egy objektum egy mappa, akkor csatlakozhat hozzá, amely mutatót biztosít a IShellFolder felületére.

Egy almappához való kötéshez hívja meg a szülőmappa IShellFolder::BindToObject metódust. Ez a módszer az almappa PIDL-jét használja, és egy mutatót ad vissza a IShellFolder felületére. Miután megkapta ezt a mutatót, az IShellFolder metódusokkal számba veheti az almappák tartalmát, meghatározhatja azok tulajdonságait stb.

Objektum szülőmappájának meghatározása

Ha rendelkezik egy objektum PIDL-jával, szükség lehet egy fogópontra a szülőmappája által közzétett felületek egyikéhez. Ha például az IShellFolder::GetDisplayNameOf használatával szeretné meghatározni a PIDL-hez társított megjelenítendő nevet, először le kell kérnie az objektum szülőfelületének IShellFolder felületét. Ezt az előző szakaszokban tárgyalt technikákkal lehet megtenni. Sokkal egyszerűbb módszer azonban a Shell függvény használata, SHBindToParent. Ez a függvény egy objektum teljes mértékben minősített PIDL-ját használja, és visszaad egy megadott illesztőmutatót a szülőmappában. Opcionálisan az elem egyszintű PIDL-jét is visszaadja olyan metódusokban való használatra, mint például IShellFolder::GetAttributesOf.

Az alábbi mintakonzolalkalmazás lekéri a Rendszer speciális mappájának PIDL-jét, és visszaadja annak megjelenítendő nevét.

#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>
#include <objbase.h>

int main()
{
    IShellFolder *psfParent = NULL;
    LPITEMIDLIST pidlSystem = NULL;
    LPCITEMIDLIST pidlRelative = NULL;
    STRRET strDispName;
    TCHAR szDisplayName[MAX_PATH];
    HRESULT hr;

    hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);

    hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);

    if(SUCCEEDED(hr))
    {
        hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);
        hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));
        cout << "SHGDN_NORMAL - " <<szDisplayName << '\n';
    }

    psfParent->Release();
    CoTaskMemFree(pidlSystem);

    return 0;
}

Az alkalmazás először SHGetFolderLocation használja a rendszermappa PIDL-jének lekéréséhez. Ezután meghívja a `SHBindToParent`függvényt, amely visszaad egy mutatót a szülőmappa `IShellFolder` felületére, valamint a rendszermappa PIDL-jét a szülőhöz viszonyítva. Ezután a szülőmappa IShellFolder::GetDisplayNameOf metódust használja a rendszermappa megjelenítendő nevének lekéréséhez. Mivel GetDisplayNameOf egy STRRET struktúrát ad vissza, StrRetToBuf a megjelenítendő név normál sztringgé alakítására szolgál. A megjelenítendő név megjelenítése után a rendszer felszabadítja a felület mutatóit, és felszabadítja a rendszer PIDL-jét. Vegye figyelembe, hogy a(z) SHBindToParent által visszaadott relatív PIDL-t nem szabad felszabadítani.