容器瀏覽器
應用程式可以使用 DsBrowseForContainer 函式來顯示對話框,可用來瀏覽 Active Directory 網域 服務中的容器。 對話框會以樹狀結構格式顯示容器,並讓使用者使用鍵盤和滑鼠瀏覽樹狀結構。 當使用者在對話框中選取專案時,會提供使用者所選取容器的 ADsPath。
DsBrowseForContainer 會取得 DSBROWSEINFO 結構的指標,其中包含對話框的相關數據,並傳回所選專案的 ADsPath。
pszRoot 成員是 Unicode 字串的指標,其中包含樹狀結構的根容器。 如果 pszRoot 為 NULL,樹狀結構將會包含整個樹狀結構。
pszPath 成員會接收所選物件的 ADsPath。 當對話框第一次顯示時,可以指定顯示並選取特定的容器。 這可藉由將 pszPath 設定為要選取之專案的 ADsPath,並在 dwFlags 中設定DSBI_EXPANDONOPEN旗標來完成。
您也可以藉由實 作 BFFCallBack 函式,在運行時間控制對話框的內容和行為。 BFFCallBack 函式是由應用程式實作,並在發生特定事件時呼叫。 應用程式可以使用這些事件來控制對話框中的項目顯示方式,以及對話框的實際內容。 例如,應用程式可以實作可處理DSBM_QUERYINSERT通知的 BFFCallBack 函式,以篩選對話框中顯示的專案。 收到DSBM_QUERYINSERT通知時,請使用 DSBITEM 結構的 pszADsPath 成員來判斷即將插入的專案。 如果應用程式判斷不應該顯示專案,則可以執行下列步驟來隱藏專案。
- 將DSBF_STATE旗標新增至 DSBITEM 結構的 dwMask 成員。
- 將DSBS_HIDDEN旗標新增至 DSBITEM 結構的 dwStateMask 成員。
- 將DSBS_HIDDEN旗標新增至 DSBITEM 結構的 dwState 成員。
- 從 BFFCallBack 函式傳回非零值。
除了隱藏特定專案之外,應用程式還可以處理 DSBM_QUERYINSERT 通知來修改項目顯示的文字和圖示。 如需詳細資訊,請參閱 DSBITEM。
BFFCallBack 函式可以使用BFFM_INITIALIZED通知來取得對話框的句柄。 應用程式可以使用這個句柄將訊息,例如 BFFM_ENABLEOK傳送至對話方塊。 如需可傳送至對話框之訊息的詳細資訊,請參閱 BFFCallBack。
對話框句柄也可以用來直接存取對話框中的控制件。 DSBID_BANNER是顯示 DSBROWSEINFO 結構之 pszTitle 成員之靜態文字控件的標識符。 DSBID_CONTAINERLIST是用來顯示樹狀目錄內容的樹視圖控件標識碼。 如果可能的話,應避免使用這些專案,以防止未來的應用程式相容性問題。
下列 C++ 程式代碼範例示範如何使用 DsBrowseForContainer 函式來建立容器瀏覽器對話框,並實作 BFFCallBack 函式。 BFFCallBack 會使用DSBM_QUERYINSERT通知,將每個項目的顯示名稱變更為專案的辨別名稱。
#include <shlobj.h>
#include <dsclient.h>
#include <atlbase.h>
/**********
WideCharToLocal()
***********/
int WideCharToLocal(LPTSTR pLocal, LPWSTR pWide, DWORD dwChars)
{
*pLocal = NULL;
size_t nWideLength = 0;
wchar_t *pwszSubstring;
nWideLength = wcslen(pWide);
#ifdef UNICODE
if(nWideLength < dwChars)
{
wcsncpy_s(pLocal, pWide, dwChars);
}
else
{
wcsncpy_s(pLocal, pWide, dwChars-1);
pLocal[dwChars-1] = NULL;
}
#else
if(nWideLength < dwChars)
{
WideCharToMultiByte( CP_ACP,
0,
pWide,
-1,
pLocal,
dwChars,
NULL,
NULL);
}
else
{
pwszSubstring = new WCHAR[dwChars];
wcsncpy_s(pwszSubstring,pWide,dwChars-1);
pwszSubstring[dwChars-1] = NULL;
WideCharToMultiByte( CP_ACP,
0,
pwszSubstring,
-1,
pLocal,
dwChars,
NULL,
NULL);
delete [] pwszSubstring;
}
#endif
return lstrlen(pLocal);
}
/**********
BrowseCallback()
***********/
int CALLBACK BrowseCallback(HWND hWnd,
UINT uMsg,
LPARAM lParam,
LPARAM lpData)
{
switch(uMsg)
{
case DSBM_QUERYINSERT:
{
BOOL fReturn = FALSE;
DSBITEM *pItem = (DSBITEM*)lParam;
/*
If this is to the root item, get the distinguished name
for the object and set the display name to the
distinguished name.
*/
if(!(pItem->dwState & DSBS_ROOT))
{
HRESULT hr;
IADs *pads;
hr = ADsGetObject(pItem->pszADsPath ,
IID_IADs, (LPVOID*)&pads);
if(SUCCEEDED(hr))
{
VARIANT var;
VariantInit(&var);
hr = pads->Get(CComBSTR("distinguishedName"),
&var);
if(SUCCEEDED(hr))
{
if(VT_BSTR == var.vt)
{
WideCharToLocal(pItem->szDisplayName,
var.bstrVal,
DSB_MAX_DISPLAYNAME_CHARS);
pItem->dwMask |= DSBF_DISPLAYNAME;
fReturn = TRUE;
}
VariantClear(&var);
}
pads->Release();
}
}
return fReturn;
}
break;
}
return FALSE;
}
/***********
BrowseForContainer()
************/
HRESULT BrowseForContainer(HWND hwndParent,
LPOLESTR *ppContainerADsPath)
{
HRESULT hr = E_FAIL;
DSBROWSEINFO dsbi;
OLECHAR wszPath[MAX_PATH * 2];
DWORD result;
if(!ppContainerADsPath)
{
return E_INVALIDARG;
}
ZeroMemory(&dsbi, sizeof(dsbi));
dsbi.hwndOwner = hwndParent;
dsbi.cbStruct = sizeof (DSBROWSEINFO);
dsbi.pszCaption = TEXT("Browse for a Container");
dsbi.pszTitle = TEXT("Select an Active Directory container.");
dsbi.pszRoot = NULL;
dsbi.pszPath = wszPath;
dsbi.cchPath = sizeof(wszPath)/sizeof(OLECHAR);
dsbi.dwFlags = DSBI_INCLUDEHIDDEN |
DSBI_IGNORETREATASLEAF|
DSBI_RETURN_FORMAT;
dsbi.pfnCallback = BrowseCallback;
dsbi.lParam = 0;
dsbi.dwReturnFormat = ADS_FORMAT_X500;
// Display the browse dialog box.
// Returns -1, 0, IDOK, or IDCANCEL.
result = DsBrowseForContainer(&dsbi);
if(IDOK == result)
{
// Allocate memory for the string.
*ppContainerADsPath = (OLECHAR*)CoTaskMemAlloc(
sizeof(OLECHAR)*(wcslen(wszPath) + 1));
if(*ppContainerADsPath)
{
wcscpy_s(*ppContainerADsPath, wszPath);
// Caller must free using CoTaskMemFree.
hr = S_OK;
}
else
{
hr = E_FAIL;
}
}
else
{
hr = E_FAIL;
}
return hr;
}