Función SHBrowseForFolderA (shlobj_core.h)
Muestra un cuadro de diálogo que permite al usuario seleccionar una carpeta shell.
Sintaxis
PIDLIST_ABSOLUTE SHBrowseForFolderA(
[in] LPBROWSEINFOA lpbi
);
Parámetros
[in] lpbi
Tipo: LPBROWSEINFO
Puntero a una estructura BROWSEINFO que contiene información utilizada para mostrar el cuadro de diálogo.
Valor devuelto
Tipo: PIDLIST_ABSOLUTE
Devuelve un PIDL que especifica la ubicación de la carpeta seleccionada en relación con la raíz del espacio de nombres. Si el usuario elige el botón Cancelar
Es posible que el PIDL devuelto sea el de un acceso directo de carpeta en lugar de una carpeta. Para obtener una explicación completa de este caso, vea la sección Comentarios.
Observaciones
Para Windows Vista o posterior, se recomienda usar IFileDialog con la opción FOS_PICKFOLDERS en lugar de la función SHBrowseForFolder. Esto usa el cuadro de diálogo Abrir archivos en el modo de selección de carpetas y es la implementación preferida.
Debe inicializar el modelo de objetos componentes (COM) antes de llamar a SHBrowseForFolder. Si inicializa COM con CoInitializeEx, debe establecer la marca COINIT_APARTMENTTHREADED en su parámetro dwCoInit. También puede usar CoInitialize o OleInitialize, que siempre usan subprocesos de apartamento. Si necesita la funcionalidad de arrastrar y colocar, se recomienda OleInitialize porque inicializa el OLE necesario, así como COM.
Hay dos estilos de cuadro de diálogo disponibles. El estilo anterior se muestra de forma predeterminada y no se puede cambiar de tamaño. El estilo más reciente proporciona una serie de características adicionales, incluida la funcionalidad de arrastrar y colocar dentro del cuadro de diálogo, reordenar, eliminar, menús contextuales, la capacidad de crear nuevas carpetas y otros comandos de menú contextual. Inicialmente, es mayor que el cuadro de diálogo anterior, pero el usuario puede cambiar su tamaño. Para especificar un cuadro de diálogo con el estilo más reciente, establezca la marca
Si implementa una función de devolución de llamada, especificada en el miembro lpfn del BROWSEINFO estructura, recibirá un identificador para el cuadro de diálogo. Un uso de este identificador de ventana es modificar el diseño o el contenido del cuadro de diálogo. Dado que no se puede cambiar el tamaño, modificar el cuadro de diálogo de estilo anterior es relativamente sencillo. Modificar el cuadro de diálogo de estilo más reciente es mucho más difícil y no se recomienda. No solo tiene un tamaño y un diseño diferentes a los del estilo anterior, sino que sus dimensiones y las posiciones de sus controles cambian cada vez que el usuario cambia de tamaño.
Si la marca de BIF_RETURNONLYFSDIRS está establecida en el miembro
filtrado personalizado
A partir de Windows XP, SHBrowseForFolder admite el filtrado personalizado en el contenido del cuadro de diálogo. Para crear un filtro personalizado, siga estos pasos.- Establezca la marca de BIF_NEWDIALOGSTYLE en el miembro ulFlags del BROWSEINFO que apunta el parámetro lpbi.
- Especifique una función de devolución de llamada en el miembro lpfn de esa misma estructura BROWSEINFO.
- Codigo la función de devolución de llamada para recibir los mensajes BFFM_INITIALIZED y BFFM_IUNKNOWN. Al recibir el mensaje de BFFM_IUNKNOWN, el parámetro lParam de la función de devolución de llamada contiene un puntero a la implementación del cuadro de diálogo de IUnknown. Llame a queryInterface en ese IUnknown para obtener un puntero a una instancia de IFolderFilterSite.
- Cree un objeto que implemente IFolderFilter.
- Llame a IFolderFilterSite::SetFilter, pasándolo a un puntero a su IFolderFilter. métodos IFolderFilter se pueden usar para incluir y excluir elementos del árbol.
- Una vez creado el filtro, ya no se necesita la interfaz
IFolderFilterSite. Llame a IFolderFilterSite::Release si no tiene más uso para él.
tratar con accesos directos
#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;
}
Nota
El encabezado shlobj_core.h define SHBrowseForFolder como alias que selecciona automáticamente la versión ANSI o Unicode de esta función en función de la definición de la constante de preprocesador UNICODE. La combinación del uso del alias neutral de codificación con código que no es neutral de codificación puede dar lugar a errores de coincidencia que dan lugar a errores de compilación o tiempo de ejecución. Para obtener más información, vea Conventions for Function Prototypes.
Requisitos
Requisito | Valor |
---|---|
cliente mínimo admitido | Windows XP [solo aplicaciones de escritorio] |
servidor mínimo admitido | Windows 2000 Server [solo aplicaciones de escritorio] |
de la plataforma de destino de |
Windows |
encabezado de |
shlobj_core.h (incluya Shlobj.h, Shlobj_core.h) |
biblioteca de |
Shell32.lib |
DLL de |
Shell32.dll (versión 4.0 o posterior) |