导航命名空间

现在,你已拥有在命名空间中的任意位置导航所需的所有基本元素。 最简单的启动方法是让应用程序调用 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;
}