Aracılığıyla paylaş


Kapsayıcı Tarayıcısı

Bir uygulama DsBrowseForContainer işlevini kullanarak Active Directory Etki Alanı Hizmeti'ndeki kapsayıcılara göz atmak için kullanılabilecek bir iletişim kutusu görüntüleyebilir. İletişim kutusu kapsayıcıları ağaç biçiminde görüntüler ve kullanıcının klavye ve fare kullanarak ağaçta gezinmesini sağlar. Kullanıcı iletişim kutusunda bir öğe seçtiğinde, kullanıcı tarafından seçilen kapsayıcının ADsPath'i sağlanır.

DsBrowseForContainer, iletişim kutusu hakkındaki verileri içeren bir DSBROWSEINFO yapısının işaretçisini alır ve seçili öğenin ADsPath değerini döndürür.

pszRoot üyesi, ağacın kök kapsayıcısını içeren bir Unicode dizesinin işaretçisidir. pszRoot null ise, ağaç tüm ağacı içerir.

pszPath üyesi seçilen nesnenin ADsPath'ini alır. İletişim kutusu ilk kez görüntülendiğinde görünür ve seçili olacak belirli bir kapsayıcı belirtmek mümkündür. Bu, pszPath seçilecek öğenin ADsPath'ine ayarlanarak ve dwFlagsiçinde DSBI_EXPANDONOPEN bayrağı ayarlanarak gerçekleştirilir.

İletişim kutusunun içeriği ve davranışı çalışma zamanında BFFCallBack işlevi uygulanarak da denetlenebilir. BFFCallBack işlevi uygulama tarafından uygulanır ve belirli olaylar gerçekleştiğinde çağrılır. Bir uygulama, iletişim kutusundaki öğelerin ve iletişim kutusunun gerçek içeriğinin nasıl görüntüleneceğini denetlemek için bu olayları kullanabilir. Örneğin, bir uygulama DSBM_QUERYINSERT bildirimini işleyebilen bir BFFCallBack işlevi uygulayarak iletişim kutusunda görüntülenen öğeleri filtreleyebilir. DSBM_QUERYINSERT bildirimi alındığında, eklenecek öğeyi belirlemek için DSBITEM yapısının pszADsPath üyesini kullanın. Uygulama öğenin görüntülenmemesi gerektiğini belirlerse, aşağıdaki adımları uygulayarak öğeyi gizleyebilir.

  1. DSBITEM yapısının dwMask üyesine DSBF_STATE bayrağını ekleyin.
  2. DSBITEM yapısının dwStateMask üyesine DSBS_HIDDEN bayrağını ekleyin.
  3. DSBITEM yapısının dwState üyesine DSBS_HIDDEN bayrağını ekleyin.
  4. BFFCallBack işlevinden sıfır olmayan bir değer döndürür.

Bir uygulama, belirli öğeleri gizlemeye ek olarak, DSBM_QUERYINSERT bildirimini işleyerek öğe için görüntülenen metni ve simgeyi değiştirebilir. Daha fazla bilgi için bkz. DSBITEM.

BFFCallBack işlevi, iletişim kutusunun tutamacını almak için BFFM_INITIALIZED bildirimini kullanabilir. Uygulama, BFFM_ENABLEOKgibi iletileri iletişim kutusuna göndermek için bu tutamacı kullanabilir. İletişim kutusuna gönderilebilen iletiler hakkında daha fazla bilgi için bkz. BFFCallBack.

İletişim kutusu tutamacı, iletişim kutusundaki denetimlere doğrudan erişim elde etmek için de kullanılabilir. DSBID_BANNER, DSBROWSEINFO yapısının pszTitle üyesinin görüntülendiği statik metin denetiminin tanımlayıcısıdır. DSBID_CONTAINERLIST, ağaç içeriğini görüntülemek için kullanılan ağaç görünümü denetiminin tanımlayıcısıdır. Uygulama uyumluluğu sorunlarını önlemek için mümkünse bu öğelerin kullanımından kaçınılmalıdır.

Aşağıdaki C++ kod örneği, kapsayıcı tarayıcısı iletişim kutusunu oluşturmak ve bir BFFCallBack işlevi uygulamak için DsBrowseForContainer işlevinin nasıl kullanılacağını gösterir. BFFCallBack, her öğenin görünen adını öğenin ayırt edici adıyla değiştirmek için DSBM_QUERYINSERT bildirimini kullanır.

#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;
}