Навигация по пространству имен

Теперь у вас есть все необходимые элементы, необходимые для навигации в любом месте пространства имен. Самый простой способ запустить приложение — вызвать SHGetDesktopFolder , чтобы получить интерфейс IShellFolder рабочего стола. Затем, чтобы перейти вниз по пространству имен, приложение может выполнить следующие действия:

  1. Перечисление содержимого папки.
  2. Определите, какие объекты являются вложенными папками, и выберите одну из них.
  3. Привяжите к вложенной папке, чтобы получить интерфейс IShellFolder .

Повторяйте эти действия так часто, как это необходимо, чтобы достичь целевого объекта.

Простой пример навигации по пространству имен

Следующий пример кода представляет собой простое консольное приложение, иллюстрирующий ряд процедур, рассмотренных в предыдущих разделах. Проверка ошибок была опущена для ясности. Приложение выполняет такие задачи:

  1. Извлекает интерфейс IShellFolder папки Program Files (с помощью интерфейса IShellFolder).
  2. Перечисляет содержимое папки (перечисление содержимого папки).
  3. Определяет все отображаемые имена и выводит их (Определение отображаемых имен и других свойств).
  4. Ищет вложенную папку (получение указателя на интерфейс IShellFolder вложенной папки).
  5. Привязывается к первой найденной вложенной папке (получение указателя на интерфейс IShellFolder вложенной папки).
  6. Выводит отображаемые имена объектов во вложенной папке.
#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;
}