Fonction SHBrowseForFolderA (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 les informations utilisées pour afficher la boîte de dialogue.
Valeur retournée
Type : PIDLIST_ABSOLUTE
Retourne un 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 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. Cela utilise la boîte de dialogue Ouvrir des fichiers en mode Choisir des dossiers et constitue 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 d’une fonctionnalité glisser-déplacer, OleInitialize est recommandé, car il initialise l’ole requis ainsi que COM.
Deux styles de boîte de dialogue sont disponibles. L’ancien style est affiché par défaut et n’est pas redimensionnable. Le style le plus récent offre un certain nombre de 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, elle est plus grande que l’ancienne boîte de dialogue, mais l’utilisateur peut la redimensionner. Pour spécifier une boîte de dialogue à l’aide du style le plus récent, définissez l’indicateur BIF_USENEWUI dans le membre ulFlags de la structure BROWSEINFO .
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 est de modifier la disposition ou le contenu de la boîte de dialogue. Étant donné qu’elle 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 de 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 membre ulFlags de la structure BROWSEINFO , le bouton OK reste activé pour les éléments « \server », ainsi que pour « \server\share » et les éléments d’annuaire. Toutefois, si l’utilisateur sélectionne un élément « \server », la transmission du PIDL retourné par SHBrowseForFolder à SHGetPathFromIDList échoue.
Filtrage personnalisé
À partir 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 vers laquelle pointe 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 lParam de la fonction de rappel contient un pointeur vers l’implémentation de IUnknown dans la boîte de dialogue. Appelez QueryInterface sur ce IUnknown pour obtenir un pointeur vers un instance de IFolderFilterSite.
- Créez un objet qui implémente IFolderFilter.
- Appelez IFolderFilterSite ::SetFilter, en lui passant un pointeur vers votre IFolderFilter. Les 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 plus d’utilisation pour elle.
Gestion des 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;
}
Notes
L’en-tête shlobj_core.h définit SHBrowseForFolder en tant qu’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. La combinaison 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.
Configuration requise
Condition requise | Valeur |
---|---|
Client minimal pris en charge | Windows XP [applications de bureau uniquement] |
Serveur minimal pris en charge | Windows 2000 Server [applications de bureau uniquement] |
Plateforme cible | Windows |
En-tête | shlobj_core.h (inclure Shlobj.h, Shlobj_core.h) |
Bibliothèque | Shell32.lib |
DLL | Shell32.dll (version 4.0 ou ultérieure) |
Voir aussi
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour