Функция SHBrowseForFolderA (shlobj_core.h)
Отображает диалоговое окно, позволяющее пользователю выбрать папку Оболочки.
Синтаксис
PIDLIST_ABSOLUTE SHBrowseForFolderA(
[in] LPBROWSEINFOA lpbi
);
Параметры
[in] lpbi
Тип: LPBROWSEINFO
Указатель на структуру BROWSEINFO, содержащую сведения, используемые для отображения диалогового окна.
Возвращаемое значение
Тип: PIDLIST_ABSOLUTE
Возвращает PIDL, указывающий расположение выбранной папки относительно корневого каталога пространства имен. Если пользователь выбирает кнопку "Отмена
Возможно, возвращенный PIDL является ярлыком папки, а не папкой. Полное обсуждение этого дела см. в разделе "Примечания".
Замечания
Для Windows Vista или более поздней версии рекомендуется использовать IFileDialog с параметром FOS_PICKFOLDERS, а не функцией SHBrowseForFolder. Это использует диалоговое окно "Открыть файлы" в режиме выбора папок и является предпочтительной реализацией.
Перед вызовом SHBrowseForFolder необходимо инициализировать объектную модель компонента (COM). При инициализации COM с помощью
Доступно два стиля диалогового окна. Старый стиль отображается по умолчанию и не изменяется. Новый стиль предоставляет ряд дополнительных функций, включая возможность перетаскивания в диалоговом окне, переупорядочение, удаление, контекстное меню, возможность создания новых папок и других команд контекстного меню. Изначально оно больше, чем более старое диалоговое окно, но пользователь может изменить его размер. Чтобы указать диалоговое окно с помощью нового стиля, задайте флаг
Если вы реализуете функцию обратного вызова, указанную в
Если флаг BIF_RETURNONLYFSDIRS установлен в элементе ulFlags член структуры BROWSEINFO, кнопка OK остается включенной для элементов "\server\server\share" и элементов каталога. Однако если пользователь выбирает элемент "\server", передав piDL, возвращенный SHBrowseForFolder, в SHGetPathFromIDList завершается ошибкой.
настраиваемую фильтрацию
По состоянию на Windows XP SHBrowseForFolder поддерживает настраиваемую фильтрацию содержимого диалогового окна. Чтобы создать пользовательский фильтр, выполните следующие действия.- Задайте флаг BIF_NEWDIALOGSTYLE в элементе
ulFlags структуры BROWSEINFO, на которую указывает параметр lpbi . - Укажите функцию обратного вызова в lpfn члена той же структуры BROWSEINFO.
- Код функции обратного вызова для получения BFFM_INITIALIZED и BFFM_IUNKNOWN сообщений. При получении сообщения BFFM_IUNKNOWN параметр функции обратного вызова lParam содержит указатель на реализацию IUnknownдиалогового окна. Вызовите QueryInterface для этого IUnknown, чтобы получить указатель на экземпляр IFolderFilterSite.
- Создайте объект, реализующий IFolderFilter.
- Вызовите IFolderFilterSite::SetFilter, передав указатель на IFolderFilter. методы IFolderFilter затем можно использовать для включения и исключения элементов из дерева.
- После создания фильтра интерфейс IFolderFilterSite больше не нужен. Вызовите IFolderFilterSite::Release, если для него нет дальнейшего использования.
работе с ярлыками
#include
// Macros for interface casts
#ifdef __cplusplus
#define IID_PPV_ARG(IType, ppType) IID_##IType, reinterpret_cast(static_cast(ppType))
#else
#define IID_PPV_ARG(IType, ppType) &IID_##IType, (void**)(ppType)
#endif
// Retrieves the UIObject interface for the specified full PIDL
STDAPI SHGetUIObjectFromFullPIDL(LPCITEMIDLIST pidl, HWND hwnd, REFIID riid, void **ppv)
{
LPCITEMIDLIST pidlChild;
IShellFolder* psf;
*ppv = NULL;
HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlChild);
if (SUCCEEDED(hr))
{
hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
psf->Release();
}
return hr;
}
#define ILSkip(pidl, cb) ((LPITEMIDLIST)(((BYTE*)(pidl))+cb))
#define ILNext(pidl) ILSkip(pidl, (pidl)->mkid.cb)
HRESULT SHILClone(LPCITEMIDLIST pidl, LPITEMIDLIST *ppidl)
{
DWORD cbTotal = 0;
if (pidl)
{
LPCITEMIDLIST pidl_temp = pidl;
cbTotal += sizeof (pidl_temp->mkid.cb);
while (pidl_temp->mkid.cb)
{
cbTotal += pidl_temp->mkid.cb;
pidl_temp += ILNext (pidl_temp);
}
}
*ppidl = (LPITEMIDLIST)CoTaskMemAlloc(cbTotal);
if (*ppidl)
CopyMemory(*ppidl, pidl, cbTotal);
return *ppidl ? S_OK: E_OUTOFMEMORY;
}
// Get the target PIDL for a folder PIDL. This also deals with cases of a folder
// shortcut or an alias to a real folder.
STDAPI SHGetTargetFolderIDList(LPCITEMIDLIST pidlFolder, LPITEMIDLIST *ppidl)
{
IShellLink *psl;
*ppidl = NULL;
HRESULT hr = SHGetUIObjectFromFullPIDL(pidlFolder, NULL, IID_PPV_ARG(IShellLink, &psl));
if (SUCCEEDED(hr))
{
hr = psl->GetIDList(ppidl);
psl->Release();
}
// It's not a folder shortcut so get the PIDL normally.
if (FAILED(hr))
hr = SHILClone(pidlFolder, ppidl);
return hr;
}
// Get the target folder for a folder PIDL. This deals with cases where a folder
// is an alias to a real folder, folder shortcuts, the My Documents folder, and
// other items of that nature.
STDAPI SHGetTargetFolderPath(LPCITEMIDLIST pidlFolder, LPWSTR pszPath, UINT cchPath)
{
LPITEMIDLIST pidlTarget;
*pszPath = 0;
HRESULT hr = SHGetTargetFolderIDList(pidlFolder, &pidlTarget);
if (SUCCEEDED(hr))
{
SHGetPathFromIDListW(pidlTarget, pszPath); // Make sure it is a path
CoTaskMemFree(pidlTarget);
}
return *pszPath ? S_OK : E_FAIL;
}
// Retrieves the UIObject interface for the specified full PIDLstatic
HRESULT SHGetUIObjectFromFullPIDL(LPCITEMIDLIST pidl, HWND hwnd, REFIID riid, void **ppv)
{
LPCITEMIDLIST pidlChild;
IShellFolder* psf;
*ppv = NULL;
HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psf, &pidlChild);
if (SUCCEEDED(hr))
{
hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
psf->Release();
}
return hr;
}
static HRESULT SHILClone(LPCITEMIDLIST pidl, LPITEMIDLIST *ppidl)
{
DWORD cbTotal = 0;
if (pidl)
{
LPCITEMIDLIST pidl_temp = pidl;
cbTotal += pidl_temp->mkid.cb;
while (pidl_temp->mkid.cb)
{
cbTotal += pidl_temp->mkid.cb;
pidl_temp = ILNext(pidl_temp);
}
}
*ppidl = (LPITEMIDLIST)CoTaskMemAlloc(cbTotal);
if (*ppidl)
CopyMemory(*ppidl, pidl, cbTotal);
return *ppidl ? S_OK: E_OUTOFMEMORY;
}
// Get the target PIDL for a folder PIDL. This also deals with cases of a folder
// shortcut or an alias to a real folder.
static HRESULT SHGetTargetFolderIDList(LPCITEMIDLIST pidlFolder, LPITEMIDLIST *ppidl)
{
IShellLink *psl;
*ppidl = NULL;
HRESULT hr = SHGetUIObjectFromFullPIDL(pidlFolder, NULL, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hr))
{
hr = psl->GetIDList(ppidl);
psl->Release();
}
// It's not a folder shortcut so get the PIDL normally.
if (FAILED(hr))
hr = SHILClone(pidlFolder, ppidl);
return hr;
}
// Get the target folder for a folder PIDL. This deals with cases where a folder
// is an alias to a real folder, folder shortcuts, the My Documents folder,
// and so on.
STDAPI SHGetTargetFolderPath(LPCITEMIDLIST pidlFolder, LPWSTR pszPath, UINT cchPath)
{
LPITEMIDLIST pidlTarget;
*pszPath = 0;
HRESULT hr = SHGetTargetFolderIDList(pidlFolder, &pidlTarget);
if (SUCCEEDED(hr))
{
SHGetPathFromIDListW(pidlTarget, pszPath);
// Make sure it is a path
CoTaskMemFree(pidlTarget);
}
return *pszPath ? S_OK : E_FAIL;
}
Заметка
Заголовок shlobj_core.h определяет SHBrowseForFolder как псевдоним, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОДа. Сочетание использования псевдонима, нейтрального для кодирования, с кодом, не зависящим от кодирования, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в соглашениях о прототипах функций.
Требования
Требование | Ценность |
---|---|
минимальные поддерживаемые клиентские | Windows XP [только классические приложения] |
минимальный поддерживаемый сервер | Windows 2000 Server [только классические приложения] |
целевая платформа | Виндоус |
заголовка | shlobj_core.h (include Shlobj.h, Shlobj_core.h) |
библиотеки |
Shell32.lib |
DLL | Shell32.dll (версия 4.0 или более поздняя версия) |