Navigace v jmenném prostoru

Teď máte všechny základní prvky potřebné k navigaci kdekoli v oboru názvů. Nejjednodušší způsob, jak začít, je nechat aplikaci zavolat SHGetDesktopFolder pro získání rozhraní pracovní plochy IShellFolder. Aby vaše aplikace mohla procházet oborem názvů směrem dolů, může postupovat takto:

  1. Zobrazí výčet obsahu složky.
  2. Určete, které objekty jsou podsložky, a vyberte jeden objekt.
  3. Vytvořte vazbu k podsložce a načtěte její rozhraní IShellFolder.

Tento postup opakujte tak často, jak je to potřeba k dosažení cíle.

Jednoduchý příklad navigace v jmenném prostoru

Následující část vzorového kódu je jednoduchá konzolová aplikace, která znázorňuje řadu postupů popsaných v předchozích částech. Kvůli přehlednosti byla vynechána kontrola chyb. Aplikace provádí následující úlohy:

  1. Načte rozhraní IShellFolder složky Program Files (pomocí rozhraní IShellFolder).
  2. Vytvoří výčet obsahu složky (výčet obsahu složky).
  3. Určuje všechny zobrazované názvy a vytiskne je (Určení zobrazovaných názvů a dalších vlastností).
  4. Prohledá podsložku (Získávání ukazatele na rozhraní IShellFolder pro podsložku).
  5. Naváže se na první podsložku, kterou najde (Získání ukazatele na rozhraní IShellFolder podsložky).
  6. Vytiskne zobrazované názvy objektů v podsložce.
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>

main()
{
    LPITEMIDLIST pidlProgFiles = NULL;
    LPITEMIDLIST pidlItems = NULL;
    IShellFolder *psfFirstFolder = NULL;
    IShellFolder *psfDeskTop = NULL;
    IShellFolder *psfProgFiles = NULL;
    LPENUMIDLIST ppenum = NULL;
    ULONG celtFetched;
    HRESULT hr;
    STRRET strDispName;
    TCHAR pszDisplayName[MAX_PATH];
    ULONG uAttr;
   
    CoInitialize( NULL );
    
    hr = SHGetFolderLocation(NULL, CSIDL_PROGRAM_FILES, NULL, 0, &pidlProgFiles);

    hr = SHGetDesktopFolder(&psfDeskTop);

    hr = psfDeskTop->BindToObject(pidlProgFiles, NULL, IID_IShellFolder, (LPVOID *) &psfProgFiles);
    psfDeskTop->Release();

    hr = psfProgFiles->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &ppenum);

    while( hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)
    {
        psfProgFiles->GetDisplayNameOf(pidlItems, SHGDN_INFOLDER, &strDispName);
        StrRetToBuf(&strDispName, pidlItems, pszDisplayName, MAX_PATH);
        cout << pszDisplayName << '\n';
        if(!psfFirstFolder)
        {
            uAttr = SFGAO_FOLDER;
            psfProgFiles->GetAttributesOf(1, (LPCITEMIDLIST *) &pidlItems, &uAttr);
            if(uAttr & SFGAO_FOLDER)
            {
                hr = psfProgFiles->BindToObject(pidlItems, NULL, IID_IShellFolder, (LPVOID *) &psfFirstFolder);
            }
        }
        CoTaskMemFree(pidlItems);
    }

    cout << "\n\n";

    ppenum->Release();

    if(psfFirstFolder)
    {
        hr = psfFirstFolder->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &ppenum);

        while( hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)
        {
            psfFirstFolder->GetDisplayNameOf(pidlItems, SHGDN_INFOLDER, &strDispName);
            StrRetToBuf(&strDispName, pidlItems, pszDisplayName, MAX_PATH);
            cout << pszDisplayName << '\n';
            CoTaskMemFree(pidlItems);
        }
    }

    ppenum->Release();
    CoTaskMemFree(pidlProgFiles);
    psfProgFiles->Release();
    psfFirstFolder->Release();

    CoUninitialize();
    return 0;
}