Funzione SHBrowseForFolderA (shlobj_core.h)
Visualizza una finestra di dialogo che consente all'utente di selezionare una cartella shell.
Sintassi
PIDLIST_ABSOLUTE SHBrowseForFolderA(
[in] LPBROWSEINFOA lpbi
);
Parametri
[in] lpbi
Tipo: LPBROWSEINFO
Puntatore a una struttura BROWSEINFO che contiene informazioni utilizzate per visualizzare la finestra di dialogo.
Valore restituito
Tipo: PIDLIST_ABSOLUTE
Restituisce un PIDL che specifica il percorso della cartella selezionata rispetto alla radice dello spazio dei nomi. Se l'utente sceglie il pulsante annulla
È possibile che il PIDL restituito sia quello di un collegamento a una cartella anziché di una cartella. Per una descrizione completa di questo caso, vedere la sezione Osservazioni.
Osservazioni
Per Windows Vista o versione successiva, è consigliabile usare IFileDialog con l'opzione FOS_PICKFOLDERS anziché la funzione SHBrowseForFolder. In questo modo viene utilizzata la finestra di dialogo Apri file in modalità di selezione cartelle ed è l'implementazione preferita.
È necessario inizializzare Component Object Model (COM) prima di chiamare SHBrowseForFolder. Se si inizializza COM utilizzando CoInitializeEx, è necessario impostare il flag COINIT_APARTMENTTHREADED nel relativo parametro dwCoInit. È anche possibile usare CoInitialize o OleInitialize, che usano sempre il threading apartment. Se è necessaria la funzionalità di trascinamento della selezione, è consigliabile OleInitialize perché inizializza il ole necessario e COM.
Sono disponibili due stili di finestra di dialogo. Lo stile precedente viene visualizzato per impostazione predefinita e non è ridimensionabile. Lo stile più recente offre numerose funzionalità aggiuntive, tra cui la funzionalità di trascinamento della selezione all'interno della finestra di dialogo, il riordinamento, l'eliminazione, i menu di scelta rapida, la possibilità di creare nuove cartelle e altri comandi di menu di scelta rapida. Inizialmente, è più grande della finestra di dialogo precedente, ma l'utente può ridimensionarlo. Per specificare una finestra di dialogo utilizzando lo stile più recente, impostare il flag di
Se si implementa una funzione di callback, specificata nel
Se il flag di BIF_RETURNONLYFSDIRS è impostato nel membro ulFlags
filtro personalizzato
A partire da Windows XP, SHBrowseForFolder supporta filtri personalizzati sul contenuto della finestra di dialogo. Per creare un filtro personalizzato, seguire questa procedura.- Impostare il flag BIF_NEWDIALOGSTYLE nel membro ulFlags
della struttura BROWSEINFO a cui punta il parametro lpbi . - Specificare una funzione di callback nel membro lpfn
della stessa struttura BROWSEINFO . - Codificare la funzione di callback per ricevere i messaggi BFFM_INITIALIZED e BFFM_IUNKNOWN. Alla ricezione del messaggio di BFFM_IUNKNOWN, il parametro lParam della funzione di callback contiene un puntatore all'implementazione della finestra di dialogo di IUnknown. Chiamare queryInterface in tale IUnknown per ottenere un puntatore a un'istanza di IFolderFilterSite.
- Creare un oggetto che implementa IFolderFilter.
- Chiamare IFolderFilterSite::SetFilter, passando un puntatore al IFolderFilter. metodi di IFolderFilter possono quindi essere usati per includere ed escludere elementi dall'albero.
- Dopo aver creato il filtro, l'interfaccia IFolderFilterSite non è più necessaria. Chiamare IFolderFilterSite::Release se non è più necessario usarlo.
gestire i tasti di scelta rapida
#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
L'intestazione shlobj_core.h definisce SHBrowseForFolder come alias che seleziona automaticamente la versione ANSI o Unicode di questa funzione in base alla definizione della costante del preprocessore UNICODE. La combinazione dell'utilizzo dell'alias indipendente dalla codifica con il codice non indipendente dalla codifica può causare mancate corrispondenze che generano errori di compilazione o di runtime. Per altre informazioni, vedere convenzioni di per i prototipi di funzioni.
Fabbisogno
Requisito | Valore |
---|---|
client minimo supportato | Windows XP [solo app desktop] |
server minimo supportato | Windows 2000 Server [solo app desktop] |
piattaforma di destinazione | Finestre |
intestazione |
shlobj_core.h (includere Shlobj.h, Shlobj_core.h) |
libreria |
Shell32.lib |
dll | Shell32.dll (versione 4.0 o successiva) |