Sdílet prostřednictvím


Získání informací o obsahu složky

V oddílu Získání ID složky byly projednány dva přístupy k získání ukazatele objektu oboru názvů na seznam identifikátorů položek (PIDL). Jednou z jevných otázek je: Jakmile máte PIDL, co s tím můžete dělat? Související otázka je: Co když ani jeden z přístupů nefunguje nebo je vhodný pro vaši aplikaci? Odpověď na obě otázky vyžaduje bližší pohled na to, jak je obor názvů implementován. Klíčem je rozhraní IShellFolder.

Použití rozhraní IShellFolder

Dříve v této dokumentaci se složky oboru názvů označovaly jako objekty. I když se v tomto okamžiku termín používal ve volném smyslu, je ve skutečnosti pravdivý i v přísném smyslu. Každá složka oboru názvů je reprezentována objektem Component Object Model (COM). Každý objekt složky zveřejňuje řadu rozhraní, která lze použít pro širokou škálu úloh. Některá rozhraní, která jsou volitelná, nemusí být dostupná ve všech složkách. Všechny složky však musí vystavit základní rozhraní, IShellFolder.

Prvním krokem při použití objektu složky je načtení ukazatele na jeho IShellFolder rozhraní. Kromě poskytování přístupu k ostatním rozhraním objektu IShellFolder zveřejňuje skupinu metod, které zpracovávají řadu běžných úloh, z nichž několik je popsáno v této části.

Chcete-li získat ukazatel na rozhraní objektu oboru názvů IShellFolder, musíte nejprve použít funkci SHGetDesktopFolder. Tato funkce vrátí ukazatel na rozhraní IShellFolder kořenového adresáře oboru názvů desktopu. Jakmile budete mít desktopové rozhraní IShellFolder, můžete pokračovat různými způsoby.

Pokud již máte PIDL složky, o kterou máte zájem – například voláním SHGetFolderLocation– můžete načíst její IShellFolder rozhraní voláním IShellFolder::BindToObject metody desktopu. Pokud máte cestu k objektu systému souborů, musíte nejprve získat jeho PIDL voláním desktopové IShellFolder::P arseDisplayName metoda a potom volat IShellFolder::BindToObject. Pokud není možné použít žádný z těchto přístupů, můžete k procházení oboru názvů použít jiné IShellFolder metody. Další informace naleznete v tématu Navigace ve jmenném prostoru.

Vytvoření výčtu obsahu složky

První věc, kterou obvykle chcete udělat se složkou, je zjistit, co obsahuje. Nejprve je nutné zavolat metodu IShellFolder::EnumObjects. Složka vytvoří standardní objekt výčtu OLE a vrátí jeho IEnumIDList rozhraní. Toto rozhraní zveřejňuje čtyři standardní metody –Clone, Next, Reseta Skip– které lze použít k vytvoření výčtu obsahu složky.

Základním postupem vytvoření výčtu obsahu složky je:

  1. Zavolejte metodu složek IShellFolder::EnumObjects pro získání ukazatele na rozhraní IEnumIDList objektu výčtu.
  2. Předat nepřidělený PIDL IEnumIDList::Next. Funkce se postará o přidělení PIDL, ale aplikace ji musí uvolnit, když už ji nepotřebuje. Když funkce Next vrátí hodnotu, PIDL bude obsahovat pouze ID položky objektu a koncové znaky NULL. Jinými slovy, jedná se o jednoúrovňové PIDL relativně vzhledem ke složce, nikoli plně kvalifikované PIDL.
  3. Opakujte krok 2, dokud Next nevrátí S_FALSE, aby bylo označeno, že všechny položky byly vyjmenovány.
  4. Zavolejte IEnumIDList::Release, abyste uvolnili objekt výčtu.

Poznámka

Je důležité sledovat, jestli pracujete s úplným nebo relativním PIDL. Některé funkce a metody přijmou obě možnosti, ale jiné akceptují pouze jednu z nich.

 

Zbývající tři metody IEnumIDList (Reset, Přeskočita Clone) jsou užitečné, pokud potřebujete provést opakované výčty složky. Umožňují obnovit výčet, přeskočit jeden nebo více objektů a vytvořit kopii objektu výčtu pro zachování jeho stavu.

Určení zobrazovaného názvu a dalších vlastností

Jakmile vyčíslíte všechny kódy PID, které jsou obsaženy ve složce, můžete zjistit, jaký druh objektů představují. Rozhraní IShellFolder poskytuje řadu užitečných metod, z nichž dva jsou zde popsány. Další IShellFolder metody a další rozhraní složek prostředí jsou popsány později.

Jednou z nejužitečnějších vlastností je zobrazovaný název objektu. Chcete-li načíst zobrazovaný název objektu, předejte jeho PIDL IShellFolder::GetDisplayNameOf. I když se objekt může nacházet kdekoli pod nadřazenou složkou v oboru názvů, musí být jeho PIDL relativní vzhledem ke složce.

IShellFolder::GetDisplayNameOf vrátí zobrazovaný název jako součást struktury STR RET. Vzhledem k tomu, že extrahování zobrazeného názvu ze struktury STRRET může být trochu složité, Shell poskytuje dvě funkce, které to za vás udělají, StrRetToStr a StrRetToBuf. Obě funkce mají strukturu STRRET a vrátí zobrazovaný název jako normální řetězec. Liší se pouze v tom, jak je řetězec přidělen.

Kromě zobrazovaného názvu může mít objekt řadu atributů, například jestli se jedná o složku nebo jestli se dá přesunout. Atributy objektu můžete načíst předáním jeho PIDL IShellFolder::GetAttributesOf. Úplný seznam atributů je poměrně velký, takže byste měli vidět odkaz na podrobnosti. Všimněte si, že PIDL, který předáváte do GetAttributesOf musí být jednoúrovňové. Konkrétně IShellFolder::GetAttributesOf bude akceptovat PIDL vrácené IEnumIDList::Next. Můžete předat pole PIDLs a GetAttributesOf vrátí atributy, které mají všechny objekty v poli společné.

Pokud máte plně kvalifikovanou cestu nebo PIDL objektu, SHGetFileInfo poskytuje jednoduchý způsob, jak načíst informace o objektu, který je dostatečný pro mnoho účelů. SHGetFileInfo přebírá plně kvalifikovanou cestu nebo PIDL a vrací řadu informací o objektu, včetně:

  • Zobrazovaný název objektu
  • Atributy objektu
  • Úchyty pro ikony objektu
  • Popisovač seznamu systémových obrazů
  • Cesta k souboru obsahujícímu ikonu objektu

Získání ukazatele na rozhraní IShellFolder podsložky

Pokud chcete zjistit, jestli složka obsahuje nějaké podsložky, můžete volat IShellFolder::GetAttributesOf a zkontrolovat, jestli je nastavený příznak SFGAO_FOLDER. Pokud je objekt složkou, můžete s ním vytvořit vazbu, která poskytuje ukazatel na jeho IShellFolder rozhraní.

Chcete-li vytvořit vazbu k podsložce, zavolejte metodu IShellFolder::BindToObject nadřazené složky. Tato metoda vezme PIDL podsložky a vrátí ukazatel na jeho IShellFolder rozhraní. Jakmile budete mít tento ukazatel, můžete použít metody IShellFolder k vytvoření výčtu obsahu podsložek, určení jejich vlastností atd.

Určení nadřazené složky objektu

Pokud máte PIDL objektu, možná budete potřebovat povolení k jednomu z rozhraní, která poskytuje jeho nadřazená složka. Pokud například chcete určit zobrazovaný název přidružený k PIDL pomocí IShellFolder::GetDisplayNameOf, musíte nejprve načíst rozhraní IShellFolder rodičovského objektu. Můžete to provést pomocí technik probíraných v předchozích částech. Mnohem jednodušší je však použít funkci Shell, SHBindToParent. Tato funkce přebírá plně kvalifikovaný PIDL objektu a vrátí zadaný ukazatel rozhraní nadřazené složky. Volitelně také vrátí jednoúrovňové PIDL položky pro použití v metodách, jako je IShellFolder::GetAttributesOf.

Následující ukázková konzolová aplikace načte PIDL systémové speciální složky a vrátí její zobrazovaný název.

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

Aplikace nejprve používá SHGetFolderLocation k načtení PIDL systémové složky. Potom volá SHBindToParent, který vrátí ukazatel na nadřazenou složku IShellFolder rozhraní a PIDL systémové složky vzhledem k nadřazenému objektu. Potom použije metodu IShellFolder::GetDisplayNameOf pro načtení zobrazovaného názvu systémové složky. Protože GetDisplayNameOf vrací STRRET strukturu, StrRetToBuf se používá k převodu zobrazovaného názvu na běžný řetězec. Po zobrazení zobrazovaného názvu se uvolní ukazatele rozhraní a systémový PIDL se uvolní. Všimněte si, že nesmíte uvolnit relativní PIDL vrácený SHBindToParent.