Navigating the Namespace

You now have all the essential elements needed to navigate anywhere in the namespace. The simplest way to start is to have your application call SHGetDesktopFolder to get the desktop's IShellFolder interface. Then, to navigate downward through the namespace, your application can follow these steps:

  1. Enumerate the folder's contents.
  2. Determine which objects are subfolders, and select one.
  3. Bind to the subfolder to get its IShellFolder interface.

Repeat these steps as often as necessary to reach the target.

A Simple Example of Namespace Navigation

The following piece of sample code is a simple console application that illustrates a number of the procedures discussed in the preceding sections. Error checking has been omitted for clarity. The application performs the following tasks:

  1. Gets the Program Files folder's IShellFolder interface (Using the IShellFolder Interface).
  2. Enumerates the contents of the folder (Enumerating the Contents of a Folder).
  3. Determines all the display names and prints them (Determining Display Names and Other Properties).
  4. Looks for a subfolder (Determining Display Names and Other Properties).
  5. Binds to the first subfolder it finds (Getting a Pointer to a Subfolder's IShellFolder Interface).
  6. Prints the display names of the objects in the subfolder.
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>

main()
{
    LPMALLOC pMalloc;
    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();
    hr = SHGetMalloc(&pMalloc);
	
    hr = SHGetFolderLocation(NULL, CSIDL_PROGRAM_FILES, NULL, NULL, &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);
            }
        }
        pMalloc->Free(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';
            pMalloc->Free(pidlItems);
        }
    }

    ppenum->Release();
    pMalloc->Free(pidlProgFiles);
    psfProgFiles->Release();
    psfFirstFolder->Release();

    return 0;
    CoUninitialize;
}