コンテナブラウザ

アプリケーションは DsBrowseForContainer 関数を使用して、Active Directory ドメインサービス内のコンテナを参照するためのダイアログボックスを表示することができます。 ダイアログボックスはコンテナをツリー形式で表示し、キーボードとマウスを使ってツリー内を移動できる。 ユーザーがダイアログボックスで項目を選択すると、ユーザーが選択したコンテナの ADsPath が提供される。

DsBrowseForContainer へのポインタを取る。 DSBROWSEINFO ダイアログボックスに関するデータを含み、選択された項目のADSPathを返す構造体。

について pszRoot メンバは、ツリーのルート・コンテナを含む Unicode 文字列へのポインタです。 もし pszRoot is NULL, の場合、ツリーはツリー全体を含むことになる。

について pszPath メンバは、選択されたオブジェクトの ADsPath を受け取ります。 ダイアログボックスが最初に表示されるときに、特定のコンテナを表示して選択するように指定することができる。 これは pszPath を選択されるアイテムのADSPathに設定する。 DSBI_EXPANDONOPEN フラグ dwFlags.

ダイアログボックスの内容や動作は、実行時に BFFCallBack 機能. について BFFCallBack 関数はアプリケーションによって実装され、特定のイベントが発生したときに呼び出される。 アプリケーションは、これらのイベントを使用して、ダイアログ・ボックスの実際の内容だけでなく、ダイアログ・ボックス内の項目の表示方法を制御することができます。 例えば、アプリケーションは、ダイアログボックスに表示される項目をフィルタリングするために BFFCallBack を扱うことができる。 DSBM_QUERYINSERT 通知. となると DSBM_QUERYINSERT 通知を受け取った場合は pszADsPath のメンバーである。 DSBITEM 構造体を使って、どの項目が挿入されようとしているかを判断する。 アプリケーションがその項目を表示すべきでないと判断した場合、以下の手順でその項目を非表示にすることができます。

  1. を追加する。 DSBF_STATE フラグを dwMask のメンバーである。 DSBITEM 構造.
  2. を追加する。 DSBS_HIDDEN フラグを dwStateMask のメンバーである。 DSBITEM 構造.
  3. を追加する。 DSBS_HIDDEN フラグを dwState のメンバーである。 DSBITEM 構造.
  4. からゼロ以外の値を返す。 BFFCallBack 機能.

特定の項目を非表示にするだけでなく、アプリケーションは DSBM_QUERYINSERT 通知. 詳しくは DSBITEM.

について BFFCallBack 関数は BFFM_INITIALIZED 通知を使用して、ダイアログ・ボックスのハンドルを取得します。 アプリケーションはこのハンドルを使って、次のようなメッセージを送ることができる。 BFFM_ENABLEOK, をダイアログボックスに追加する。 ダイアログボックスに送信できるメッセージの詳細については、以下を参照。BFFCallBack.

ダイアログボックスハンドルは、ダイアログボックス内のコントロールに直接アクセスするためにも使用できる。 DSBID_BANNER が使用する静的テキストコントロールの識別子です。 pszTitle のメンバーである。 DSBROWSEINFO 構造が表示される。 DSBID_CONTAINERLIST は、ツリーの内容を表示するために使用されるツリービューコントロールの識別子です。 将来的なアプリケーションの互換性の問題を防ぐため、これらのアイテムの使用は可能であれば避けるべきである。

次の C++ コード例は DsBrowseForContainer function to create the container browser dialog box and implement a 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;
}