Получение идентификатора папки
Прежде чем использовать объект пространства имен, вам потребуется способ его идентификации. Это означает получение указателя на список идентификаторов элементов (PIDL) или, в случае объектов файловой системы, его путь. В этом разделе рассматриваются два более простых способа получения идентификаторов объектов.
Для более эффективного подхода, который будет работать с любой папкой, используйте интерфейс IShellFolder . Дополнительные сведения см. в разделе Получение сведений о содержимом папки .
- Диалоговое окно OpenFiles
- Диалоговое окно SHBrowseForFolder
- Специальные папки и CSIDL
- Простой пример использования CSIDL и SHBrowseForFolder
Диалоговое окно 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.