共用方式為


容器瀏覽器

應用程式可以使用 DsBrowseForContainer 函式來顯示對話框,可用來瀏覽 Active Directory 網域 服務中的容器。 對話框會以樹狀結構格式顯示容器,並讓使用者使用鍵盤和滑鼠瀏覽樹狀結構。 當使用者在對話框中選取專案時,會提供使用者所選取容器的 ADsPath。

DsBrowseForContainer 會取得 DSBROWSEINFO 結構的指標,其中包含對話框的相關數據,並傳回所選專案的 ADsPath。

pszRoot 成員是 Unicode 字串的指標,其中包含樹狀結構的根容器。 如果 pszRootNULL,樹狀結構將會包含整個樹狀結構。

pszPath 成員會接收所選物件的 ADsPath。 當對話框第一次顯示時,可以指定顯示並選取特定的容器。 這可藉由將 pszPath 設定為要選取之專案的 ADsPath,並在 dwFlags設定DSBI_EXPANDONOPEN旗標來完成。

您也可以藉由實 作 BFFCallBack 函式,在運行時間控制對話框的內容和行為。 BFFCallBack 函式是由應用程式實作,並在發生特定事件時呼叫。 應用程式可以使用這些事件來控制對話框中的項目顯示方式,以及對話框的實際內容。 例如,應用程式可以實作可處理DSBM_QUERYINSERT通知的 BFFCallBack 函式,以篩選對話框中顯示的專案。 收到DSBM_QUERYINSERT通知時,請使用 DSBITEM 結構的 pszADsPath 成員來判斷即將插入的專案。 如果應用程式判斷不應該顯示專案,則可以執行下列步驟來隱藏專案。

  1. DSBF_STATE旗標新增至 DSBITEM 結構的 dwMask 成員
  2. DSBS_HIDDEN旗標新增至 DSBITEM 結構的 dwStateMask 成員
  3. DSBS_HIDDEN旗標新增至 DSBITEM 結構的 dwState 成員
  4. 從 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;
}