Поделиться через


Получение идентификатора папки

Прежде чем использовать объект пространства имен, вам потребуется способ его идентификации. Это означает получение указателя на список идентификаторов элементов (PIDL) или, в случае объектов файловой системы, его путь. В этом разделе рассматриваются два более простых способа получения идентификаторов объектов.

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

Диалоговое окно OpenFiles

Чтобы пользователь мог перемещаться по пространству имен и выбирать папку, приложение может использовать интерфейс IFileDialog . Вызов этого интерфейса с флагом FOS_PICKFOLDERS запускает общее диалоговое окно Открыть файлы в режиме выбора папок.

Для Windows Vista и более поздних версий это рекомендуемый способ выбора папок.

Диалоговое окно SHBrowseForFolder

Чтобы пользователь мог перемещаться по пространству имен и выбирать папку, приложение может просто вызвать SHBrowseForFolder. При вызове этой функции открывается диалоговое окно с пользовательским интерфейсом, которое работает примерно так же, как общие диалоговые окна "Открыть" или "Сохранить".

Когда пользователь выбирает папку, SHBrowseForFolder возвращает полное значение PIDL папки и ее отображаемое имя. Если папка находится в файловой системе, приложение может преобразовать PIDL в путь, вызвав SHGetPathFromIDList. Приложение также может ограничить диапазон папок, которые пользователь может выбрать, указав корневую папку. Будут отображаться только папки, расположенные под этим корнем в пространстве имен. На следующем рисунке показано диалоговое окно SHBrowseForFolder с корневой папкой с параметром Program Files.

Снимок экрана: диалоговое окно

Простой пример использования SHBrowseForFolder приведен ниже.

Специальные папки и CSIDL

Ряд часто используемых папок обозначены системой как специальные . Эти папки имеют четко определенное назначение, и большинство из них присутствуют во всех системах. Даже если они отсутствуют изначально, их имена и расположения по-прежнему определяются, поэтому их можно добавить позже. Коллекция специальных папок включает все стандартные виртуальные папки системы, такие как Принтеры, Мои документы и Сетевое окружение. Он также включает ряд стандартных папок файловой системы, таких как Program Files и System.

Несмотря на то, что папки являются стандартным компонентом всех систем, их имена и расположения в пространстве имен могут отличаться. Например, каталог System — C:\Winnt\System32 в некоторых системах и C:\Windows\System32 в других. В прошлом переменные среды предоставляли способ определения имени и расположения специальной папки в любой конкретной системе. Оболочка теперь предоставляет более надежный и гибкий способ идентификации специальных папок, CSIDL. Как правило, их следует использовать вместо переменных среды.

CSIDL предоставляют единый способ идентификации и поиска специальных папок независимо от их имени или расположения в конкретной системе. В отличие от переменных среды, CSIDL можно использовать как с виртуальными папками, так и с папками файловой системы. Каждой специальной папке назначен уникальный CSIDL. Например, папка файловой системы Program Files содержит CSIDL CSIDL_PROGRAM_FILES, а виртуальная папка "Сетевое окружение" — CSIDL CSIDL_NETWORK.

CSIDL используется в сочетании с одной из нескольких функций оболочки для получения PIDL специальной папки или пути к папке специальной файловой системы. Если папка не существует в системе, приложение может принудительно создать ее, объединив CSIDL с CSIDL_FLAG_CREATE. CSIDL можно передать в следующие функции:

  • SHGetFolderLocation, который извлекает PIDL специальной папки.
  • SHGetFolderPath, который извлекает путь к специальной папке файловой системы.

Обратите внимание, что эти две функции появились в оболочке версии 5.0 и заменены функциями SHGetSpecialFolderLocation и SHGetSpecialFolderPath .

Простой пример использования CSIDL и SHBrowseForFolder

В следующем примере функции PidlBrowse показано, как использовать CSIDL для получения PIDL папки и использовать SHBrowseForFolder , чтобы пользователь выбирал папку. Он возвращает ЗНАЧЕНИЕ PIDL и отображаемое имя выбранной папки.

LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL, LPSTR pszDisplayName)
{
    LPITEMIDLIST pidlRoot = NULL;
    LPITEMIDLIST pidlSelected = NULL;
    BROWSEINFO bi = {0};

    if(nCSIDL)
    {
        SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);
    }

    else
    {
        pidlRoot = NULL;
    }

    bi.hwndOwner = hwnd;
    bi.pidlRoot = pidlRoot;
    bi.pszDisplayName = pszDisplayName;
    bi.lpszTitle = "Choose a folder";
    bi.ulFlags = 0;
    bi.lpfn = NULL;
    bi.lParam = 0;

    pidlSelected = SHBrowseForFolder(&bi);

    if(pidlRoot)
    {
        CoTaskMemFree(pidlRoot);
    }

    return pidlSelected;
}

Вызывающее приложение передает дескриптор окна, необходимый для SHBrowseForFolder. Параметр nCSIDL является необязательным CSIDL, который используется для указания корневой папки. Будут отображаться только папки под корневой папкой в иерархии. Показанная выше иллюстрация была создана путем вызова этой функции с параметромnCSIDL, для CSIDL_PROGRAM_FILES. Вызывающее приложение также передает буфер строки pszDisplayName для хранения отображаемого имени выбранной папки при возврате PidlBrowse. Вызывающее приложение отвечает за освобождение списка IDList, возвращаемого SHBrowseForFolder с помощью CoTaskMemFree.