SHBrowseForFolderA, fonction (shlobj_core.h)
Affiche une boîte de dialogue qui permet à l’utilisateur de sélectionner un dossier Shell.
Syntaxe
PIDLIST_ABSOLUTE SHBrowseForFolderA(
[in] LPBROWSEINFOA lpbi
);
Paramètres
[in] lpbi
Type : LPBROWSEINFO
Pointeur vers une structure BROWSEINFO qui contient des informations utilisées pour afficher la boîte de dialogue.
Valeur de retour
Type : PIDLIST_ABSOLUTE
Retourne un code PIDL qui spécifie l’emplacement du dossier sélectionné par rapport à la racine de l’espace de noms. Si l’utilisateur choisit le bouton Annuler dans la boîte de dialogue, la valeur de retour est NULL.
Il est possible que le code PIDL retourné soit celui d’un raccourci de dossier plutôt que d’un dossier. Pour une discussion complète de ce cas, consultez la section Remarques.
Remarques
Pour Windows Vista ou version ultérieure, il est recommandé d’utiliser IFileDialog avec l’option FOS_PICKFOLDERS plutôt que la fonction SHBrowseForFolder. Cette opération utilise la boîte de dialogue Ouvrir des fichiers en mode Choisir des dossiers et est l’implémentation préférée.
Vous devez initialiser com (Component Object Model) avant d’appeler SHBrowseForFolder. Si vous initialisez COM à l’aide de CoInitializeEx, vous devez définir l’indicateur COINIT_APARTMENTTHREADED dans son paramètre dwCoInit. Vous pouvez également utiliser CoInitialize ou OleInitialize, qui utilisent toujours le thread d’appartement. Si vous avez besoin de fonctionnalités de glisser-déplacer, OleInitialize est recommandé, car il initialise l’OLE requis ainsi que COM.
Il existe deux styles de boîte de dialogue disponibles. L’ancien style est affiché par défaut et n’est pas redimensionnable. Le style plus récent fournit plusieurs fonctionnalités supplémentaires, notamment la fonctionnalité glisser-déplacer dans la boîte de dialogue, la réorganisation, la suppression, les menus contextuels, la possibilité de créer de nouveaux dossiers et d’autres commandes de menu contextuel. Initialement, il est supérieur à l’ancienne boîte de dialogue, mais l’utilisateur peut le redimensionner. Pour spécifier une boîte de dialogue à l’aide du style plus récent, définissez l’indicateur de
Si vous implémentez une fonction de rappel, spécifiée dans le membre lpfn de la structure BROWSEINFO, vous recevez un handle dans la boîte de dialogue. L’une des utilisations de ce handle de fenêtre consiste à modifier la disposition ou le contenu de la boîte de dialogue. Étant donné qu’il n’est pas redimensionnable, la modification de l’ancienne boîte de dialogue de style est relativement simple. La modification de la boîte de dialogue de style plus récente est beaucoup plus difficile et n’est pas recommandée. Non seulement il a une taille et une disposition différentes que l’ancien style, mais ses dimensions et les positions de ses contrôles changent chaque fois qu’il est redimensionné par l’utilisateur.
Si l’indicateur BIF_RETURNONLYFSDIRS est défini dans le ulFlags membre de la structure BROWSEINFO, le bouton OK reste activé pour les éléments « \server », ainsi que « \server\share » et les éléments de répertoire. Toutefois, si l’utilisateur sélectionne un élément « \server », le passage du code PIDL retourné par SHBrowseForFolder à SHGetPathFromIDList échoue.
filtrage personnalisé
À compter de Windows XP, SHBrowseForFolder prend en charge le filtrage personnalisé sur le contenu de la boîte de dialogue. Pour créer un filtre personnalisé, procédez comme suit.- Définissez l’indicateur BIF_NEWDIALOGSTYLE dans le membre
ulFlags de la structure BROWSEINFO pointée par le paramètre lpbi. - Spécifiez une fonction de rappel dans le membre lpfn de cette même structure BROWSEINFO.
- Codez la fonction de rappel pour recevoir les messages BFFM_INITIALIZED et BFFM_IUNKNOWN. À la réception du message BFFM_IUNKNOWN, le paramètre de la fonction de rappel
lParam contient un pointeur vers l’implémentation de IUnknown de boîte de dialogue. Appelez QueryInterface sur ce IUnknown pour obtenir un pointeur vers une instance de IFolderFilterSite. - Créez un objet qui implémente IFolderFilter.
- Appelez IFolderFilterSite ::SetFilter, en lui transmettant un pointeur vers votre IFolderFilter. méthodes IFolderFilter peuvent ensuite être utilisées pour inclure et exclure des éléments de l’arborescence.
- Une fois le filtre créé, l’interface IFolderFilterSite n’est plus nécessaire. Appelez IFolderFilterSite ::Release si vous n’avez pas d’autre utilisation pour celle-ci.
traiter les raccourcis
#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;
}
Note
L’en-tête shlobj_core.h définit SHBrowseForFolder comme alias qui sélectionne automatiquement la version ANSI ou Unicode de cette fonction en fonction de la définition de la constante de préprocesseur UNICODE. Le mélange de l’utilisation de l’alias neutre en encodage avec du code qui n’est pas neutre en encodage peut entraîner des incompatibilités qui entraînent des erreurs de compilation ou d’exécution. Pour plus d’informations, consultez Conventions pour les prototypes de fonction.
Exigences
Exigence | Valeur |
---|---|
client minimum pris en charge | Windows XP [applications de bureau uniquement] |
serveur minimum pris en charge | Windows 2000 Server [applications de bureau uniquement] |
plateforme cible | Windows |
d’en-tête | shlobj_core.h (include Shlobj.h, Shlobj_core.h) |
bibliothèque | Shell32.lib |
DLL | Shell32.dll (version 4.0 ou ultérieure) |