Fungsi SHBrowseForFolderA (shlobj_core.h)
Menampilkan kotak dialog yang memungkinkan pengguna memilih folder Shell.
Sintaks
PIDLIST_ABSOLUTE SHBrowseForFolderA(
[in] LPBROWSEINFOA lpbi
);
Parameter
[in] lpbi
Jenis: LPBROWSEINFO
Penunjuk ke struktur BROWSEINFO yang berisi informasi yang digunakan untuk menampilkan kotak dialog.
Nilai kembali
Jenis: PIDLIST_ABSOLUTE
Mengembalikan PIDL yang menentukan lokasi folder yang dipilih relatif terhadap akar namespace. Jika pengguna memilih tombol Batalkan dalam kotak dialog, nilai yang dikembalikan adalah NULL.
Ada kemungkinan bahwa PIDL yang dikembalikan adalah pintasan folder daripada folder. Untuk diskusi lengkap tentang kasus ini, lihat bagian Keterangan.
Keterangan
Untuk Windows Vista atau yang lebih baru, disarankan agar Anda menggunakan IFileDialog dengan opsi FOS_PICKFOLDERS daripada fungsi SHBrowseForFolder. Ini menggunakan dialog Buka File dalam mode pilih folder dan merupakan implementasi yang disukai.
Anda harus menginisialisasi Model Objek Komponen (COM) sebelum memanggil SHBrowseForFolder. Jika Anda menginisialisasi COM menggunakan CoInitializeEx, Anda harus mengatur bendera COINIT_APARTMENTTHREADED dalam parameter dwCoInit-nya . Anda juga dapat menggunakan CoInitialize atau OleInitialize, yang selalu menggunakan utas apartemen. Jika Anda memerlukan fungsionalitas seret dan letakkan, OleInitialize disarankan karena menginisialisasi OLE yang diperlukan serta COM.
Ada dua gaya kotak dialog yang tersedia. Gaya yang lebih lama ditampilkan secara default dan tidak dapat diubah ukurannya. Gaya yang lebih baru menyediakan sejumlah fitur tambahan, termasuk kemampuan seret dan letakkan dalam kotak dialog, penyusunan ulang, penghapusan, menu pintasan, kemampuan untuk membuat folder baru, dan perintah menu pintasan lainnya. Awalnya, ini lebih besar dari kotak dialog yang lebih lama, tetapi pengguna dapat mengubah ukurannya. Untuk menentukan kotak dialog menggunakan gaya yang lebih baru, atur bendera BIF_USENEWUI di anggota ulFlags dari struktur BROWSEINFO .
Jika Anda menerapkan fungsi panggilan balik, yang ditentukan dalam anggota lpfn struktur BROWSEINFO , Anda menerima handel ke kotak dialog. Salah satu penggunaan handel jendela ini adalah untuk mengubah tata letak atau isi kotak dialog. Karena tidak dapat diubah, memodifikasi kotak dialog gaya yang lebih lama relatif mudah. Mengubah kotak dialog gaya yang lebih baru jauh lebih sulit, dan tidak disarankan. Tidak hanya memiliki ukuran dan tata letak yang berbeda dari gaya lama, tetapi dimensi dan posisi kontrolnya berubah setiap kali diubah ukurannya oleh pengguna.
Jika bendera BIF_RETURNONLYFSDIRS diatur di anggota ulFlags dari struktur BROWSEINFO , tombol OK tetap diaktifkan untuk item "\server", serta "\server\share" dan item direktori. Namun, jika pengguna memilih item "\server", meneruskan PIDL yang dikembalikan oleh SHBrowseForFolder ke SHGetPathFromIDList gagal.
Pemfilteran Kustom
Pada Windows XP, SHBrowseForFolder mendukung pemfilteran kustom pada konten kotak dialog. Untuk membuat filter kustom, ikuti langkah-langkah ini.- Atur bendera BIF_NEWDIALOGSTYLE di anggota ulFlags struktur BROWSEINFO yang diarahkan oleh parameter lpbi .
- Tentukan fungsi panggilan balik di anggota lpfn dari struktur BROWSEINFO yang sama.
- Kode fungsi panggilan balik untuk menerima pesan BFFM_INITIALIZED dan BFFM_IUNKNOWN. Pada penerimaan pesan BFFM_IUNKNOWN, parameter lParam fungsi panggilan balik berisi pointer ke implementasi kotak dialog IUnknown. Panggil QueryInterface pada IUnknown tersebut untuk mendapatkan pointer ke instans IFolderFilterSite.
- Buat objek yang mengimplementasikan IFolderFilter.
- Panggil IFolderFilterSite::SetFilter, meneruskan ke pointer ke IFolderFilter Anda. Metode IFolderFilter kemudian dapat digunakan untuk menyertakan dan mengecualikan item dari pohon.
- Setelah filter dibuat, antarmuka IFolderFilterSite tidak lagi diperlukan. Panggil IFolderFilterSite::Release jika Anda tidak memiliki penggunaan lebih lanjut untuk itu.
Berurusan dengan Pintasan
#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;
}
Catatan
Header shlobj_core.h mendefinisikan SHBrowseForFolder sebagai alias yang secara otomatis memilih versi ANSI atau Unicode dari fungsi ini berdasarkan definisi konstanta pra-prosesor UNICODE. Mencampur penggunaan alias encoding-netral dengan kode yang tidak mengodekan-netral dapat menyebabkan ketidakcocokan yang mengakibatkan kesalahan kompilasi atau runtime. Untuk informasi selengkapnya, lihat Konvensi untuk Prototipe Fungsi.
Persyaratan
Persyaratan | Nilai |
---|---|
Klien minimum yang didukung | Windows XP [hanya aplikasi desktop] |
Server minimum yang didukung | Windows 2000 Server [hanya aplikasi desktop] |
Target Platform | Windows |
Header | shlobj_core.h (termasuk Shlobj.h, Shlobj_core.h) |
Pustaka | Shell32.lib |
DLL | Shell32.dll (versi 4.0 atau yang lebih baru) |