SHBrowseForFolderA-Funktion (shlobj_core.h)
Zeigt ein Dialogfeld an, in dem der Benutzer einen Shellordner auswählen kann.
Syntax
PIDLIST_ABSOLUTE SHBrowseForFolderA(
[in] LPBROWSEINFOA lpbi
);
Parameter
[in] lpbi
Typ: LPBROWSEINFO
Ein Zeiger auf eine BROWSEINFO-Struktur , die Informationen enthält, die zum Anzeigen des Dialogfelds verwendet werden.
Rückgabewert
Typ: PIDLIST_ABSOLUTE
Gibt eine PIDL zurück, die den Speicherort des ausgewählten Ordners relativ zum Stammverzeichnis des Namespace angibt. Wenn der Benutzer im Dialogfeld die Schaltfläche Abbrechen auswählt, ist der Rückgabewert NULL.
Es ist möglich, dass die zurückgegebene PIDL die einer Ordnerverknüpfung und nicht eines Ordners ist. Eine vollständige Erläuterung dieses Falls finden Sie im Abschnitt Hinweise.
Hinweise
Für Windows Vista oder höher wird empfohlen, IFileDialog mit der Option FOS_PICKFOLDERS anstelle der SHBrowseForFolder-Funktion zu verwenden. Dies verwendet das Dialogfeld Dateien öffnen im Ordnerauswahlmodus und ist die bevorzugte Implementierung.
Sie müssen das Component Object Model (COM) initialisieren, bevor Sie SHBrowseForFolder aufrufen. Wenn Sie COM mit CoInitializeEx initialisieren, müssen Sie das COINIT_APARTMENTTHREADED-Flag im dwCoInit-Parameter festlegen. Sie können auch CoInitialize oder OleInitialize verwenden, die immer Apartmentthreading verwenden. Wenn Sie Drag-and-Drop-Funktionen benötigen, wird OleInitialize empfohlen, da es sowohl den erforderlichen OLE als auch COM initialisiert.
Es stehen zwei Arten von Dialogfelder zur Verfügung. Die ältere Formatvorlage wird standardmäßig angezeigt und kann nicht geändert werden. Der neuere Stil bietet eine Reihe zusätzlicher Features, einschließlich Drag-and-Drop-Funktionen innerhalb des Dialogfelds, Neuanordnung, Löschen, Kontextmenüs, die Möglichkeit zum Erstellen neuer Ordner und andere Kontextmenübefehle. Anfangs ist es größer als das ältere Dialogfeld, aber der Benutzer kann seine Größe ändern. Um ein Dialogfeld mithilfe des neueren Stils anzugeben, legen Sie das flag BIF_USENEWUI im ulFlags-Element der BROWSEINFO-Struktur fest.
Wenn Sie eine Rückruffunktion implementieren, die im lpfn-Element der BROWSEINFO-Struktur angegeben ist, erhalten Sie ein Handle für das Dialogfeld. Eine Verwendung dieses Fensterhandles besteht darin, das Layout oder den Inhalt des Dialogfelds zu ändern. Da die Größe nicht geändert werden kann, ist das Ändern des Dialogfelds für die ältere Formatvorlage relativ einfach. Das Ändern des Neueren Stildialogfelds ist viel schwieriger und wird nicht empfohlen. Es hat nicht nur eine andere Größe und ein anderes Layout als der alte Stil, sondern auch seine Abmessungen und die Positionen seiner Steuerelemente ändern sich bei jeder Größenänderung durch den Benutzer.
Wenn das flag BIF_RETURNONLYFSDIRS im ulFlags-Element der BROWSEINFO-Struktur festgelegt ist, bleibt die Schaltfläche OK für "\server"-Elemente sowie "\server\share" und Verzeichniselemente aktiviert. Wenn der Benutzer jedoch ein Element "\server" auswählt, schlägt das Übergeben der von SHBrowseForFolder zurückgegebenen PIDL an SHGetPathFromIDList fehl.
Benutzerdefinierte Filterung
Ab Windows XP unterstützt SHBrowseForFolder benutzerdefinierte Filterung für den Inhalt des Dialogfelds. Führen Sie die folgenden Schritte aus, um einen benutzerdefinierten Filter zu erstellen.- Legen Sie das BIF_NEWDIALOGSTYLE-Flag im ulFlags-Element der BROWSEINFO-Struktur fest, auf die der lpbi-Parameter verweist.
- Geben Sie eine Rückruffunktion im lpfn-Member derselben BROWSEINFO-Struktur an.
- Codieren Sie die Rückruffunktion, um die BFFM_INITIALIZED und BFFM_IUNKNOWN Nachrichten zu empfangen. Beim Empfang der BFFM_IUNKNOWN Meldung enthält der lParam-Parameter der Rückruffunktion einen Zeiger auf die Implementierung von IUnknown im Dialogfeld. Rufen Sie QueryInterface für diese IUnknown auf, um einen Zeiger auf eine instance von IFolderFilterSite abzurufen.
- Erstellen Sie ein -Objekt, das IFolderFilter implementiert.
- Rufen Sie IFolderFilterSite::SetFilter auf, und übergeben Sie einen Zeiger auf Ihren IFolderFilter. IFolderFilter-Methoden können dann verwendet werden, um Elemente aus der Struktur einzu- und auszuschließen.
- Nachdem der Filter erstellt wurde, wird die IFolderFilterSite-Schnittstelle nicht mehr benötigt. Rufen Sie IFolderFilterSite::Release auf, wenn Sie keine weitere Verwendung dafür haben.
Umgang mit Tastenkombinationen
#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;
}
Hinweis
Der shlobj_core.h-Header definiert SHBrowseForFolder als Alias, der die ANSI- oder Unicode-Version dieser Funktion basierend auf der Definition der UNICODE-Präprozessorkonstante automatisch auswählt. Das Mischen der Verwendung des codierungsneutralen Alias mit Code, der nicht Codierungsneutral ist, kann zu Nichtübereinstimmungen führen, die zu Kompilierungs- oder Laufzeitfehlern führen. Weitere Informationen finden Sie unter Konventionen für Funktionsprototypen.
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Client) | Windows XP [nur Desktop-Apps] |
Unterstützte Mindestversion (Server) | Windows 2000 Server [nur Desktop-Apps] |
Zielplattform | Windows |
Kopfzeile | shlobj_core.h (einschließlich Shlobj.h, Shlobj_core.h) |
Bibliothek | Shell32.lib |
DLL | Shell32.dll (Version 4.0 oder höher) |