Função SHBrowseForFolderA (shlobj_core.h)
Exibe uma caixa de diálogo que permite que o usuário selecione uma pasta shell.
Sintaxe
PIDLIST_ABSOLUTE SHBrowseForFolderA(
[in] LPBROWSEINFOA lpbi
);
Parâmetros
[in] lpbi
Tipo: LPBROWSEINFO
Um ponteiro para uma estrutura BROWSEINFO
Valor de retorno
Tipo: PIDLIST_ABSOLUTE
Retorna um PIDL que especifica o local da pasta selecionada em relação à raiz do namespace. Se o usuário escolher o botão Cancelar na caixa de diálogo, o valor retornado será NULL.
É possível que o PIDL retornado seja o de um atalho de pasta em vez de uma pasta. Para obter uma discussão completa sobre esse caso, consulte a seção Comentários.
Observações
Para o Windows Vista ou posterior, é recomendável que você use IFileDialog com a opção FOS_PICKFOLDERS em vez da função SHBrowseForFolder. Isso usa a caixa de diálogo Abrir Arquivos no modo de pastas de seleção e é a implementação preferencial.
Você deve inicializar o COM (Component Object Model) antes de chamar SHBrowseForFolder. Se você inicializar COM usando CoInitializeEx, deverá definir o sinalizador COINIT_APARTMENTTHREADED em seu parâmetro dwCoInit. Você também pode usar CoInitialize ou OleInitialize, que sempre usam threading de apartamento. Se você precisar de funcionalidade de arrastar e soltar, OleInitialize será recomendado porque inicializa o OLE necessário, bem como o COM.
Há dois estilos de caixa de diálogo disponíveis. O estilo mais antigo é exibido por padrão e não é redimensionável. O estilo mais recente fornece uma série de recursos adicionais, incluindo recursos de arrastar e soltar dentro da caixa de diálogo, reordenação, exclusão, menus de atalho, a capacidade de criar novas pastas e outros comandos de menu de atalho. Inicialmente, ele é maior que a caixa de diálogo mais antiga, mas o usuário pode redimensioná-la. Para especificar uma caixa de diálogo usando o estilo mais recente, defina o sinalizador
Se você implementar uma função de retorno de chamada, especificada no
Se o sinalizador de BIF_RETURNONLYFSDIRS estiver definido no
filtragem personalizada
A partir do Windows XP, SHBrowseForFolder dá suporte à filtragem personalizada no conteúdo da caixa de diálogo. Para criar um filtro personalizado, siga estas etapas.- Defina o sinalizador BIF_NEWDIALOGSTYLE no
membro ulFlags da estruturaBROWSEINFO apontada pelo parâmetro lpbi . - Especifique uma função de retorno de chamada no
lpfn membro da mesma estrutura BROWSEINFO. - Codificar a função de retorno de chamada para receber as mensagens BFFM_INITIALIZED e BFFM_IUNKNOWN. Ao receber a mensagem BFFM_IUNKNOWN, o parâmetro lParam da função de retorno de chamada contém um ponteiro para a implementação da caixa de diálogo de IUnknown. Chame QueryInterface nesse IUnknown para obter um ponteiro para uma instância de IFolderFilterSite.
- Criar um objeto que implementa IFolderFilter.
- Chame
IFolderFilterSite::SetFilter , passando para ele um ponteiro para oIFolderFilter. métodos IFolderFilter podem ser usados para incluir e excluir itens da árvore. - Depois que o filtro é criado, a interface IFolderFilterSite
não é mais necessária. Chame IFolderFilterSite::Release se você não tiver mais uso para ele.
lidando com atalhos
#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
O cabeçalho shlobj_core.h define SHBrowseForFolder como um alias que seleciona automaticamente a versão ANSI ou Unicode dessa função com base na definição da constante do pré-processador UNICODE. A combinação do uso do alias neutro de codificação com código que não é neutro em codificação pode levar a incompatibilidades que resultam em erros de compilação ou de runtime. Para obter mais informações, consulte Conventions for Function Prototypes.
Requisitos
Requisito | Valor |
---|---|
de cliente com suporte mínimo | Windows XP [somente aplicativos da área de trabalho] |
servidor com suporte mínimo | Windows 2000 Server [somente aplicativos da área de trabalho] |
da Plataforma de Destino |
Windows |
cabeçalho | shlobj_core.h (inclua Shlobj.h, Shlobj_core.h) |
biblioteca | Shell32.lib |
de DLL |
Shell32.dll (versão 4.0 ou posterior) |