애플리케이션에서 표시 지정자를 사용하는 방법
Active Directory 도메인 Service 개체를 표시하려면 표시 지정자를 사용하여 클래스 및 특성 개체에 대한 지역화된 표시 데이터를 가져옵니다. 이렇게 하면 지역화된 표시 이름 및 아이콘을 사용할 수 있으며 표시 데이터의 불필요한 지역화를 방지할 수 있습니다.
표시 이름
적절한 로캘에 대한 표시 지정자 개체의 classDisplayName 및 attributeDisplayNames 속성을 사용하여 클래스 및 특성 이름에 대한 표시 텍스트를 가져와야 합니다. 이러한 값은 지역화되지 않으므로 classSchema 또는 attributeSchema 개체의 cn, classDisplayName 또는 ldapDisplayName 속성을 사용하여 표시 텍스트 레이블을 가져오지 마세요. 클래스 개체에 대한 지역화된 텍스트를 검색하는 방법에 대한 자세한 내용은 다음 샘플 코드를 참조하세요.
아이콘
적절한 로캘에 대한 표시 지정자 개체의 iconPath 속성을 사용하여 클래스 개체에 대해 표시할 아이콘을 가져와야 합니다. 자세한 내용은 클래스 아이콘을 참조하세요. 클래스 개체에 대해 지역화된 아이콘이 지정되지 않은 경우 항목에 대한 기본 아이콘이 표시되어야 합니다.
새 개체 만들기
가능하면 적절한 개체 만들기 마법사를 사용하여 새 개체를 만듭니다. 자세한 내용은 애플리케이션에서 만들기 마법사 호출을 참조하세요.
다음 코드 예제에서는 클래스 및 클래스의 특성에 대 한 표시 텍스트를 가져오는 방법을 보여 입니다.
#include <atlbase.h>
/**************************************************************************
GetClassDisplaySpecifierContainer()
**************************************************************************/
HRESULT GetClassDisplaySpecifierContainer(LPWSTR pwszClass,
LCID locale,
IADs **ppads)
{
if((NULL == pwszClass) || (NULL == ppads))
{
return E_INVALIDARG;
}
*ppads = NULL;
// If no locale is specified, use the default system locale.
if(0 == locale)
{
locale = GetSystemDefaultLCID();
if(0 == locale)
{
return E_FAIL;
}
}
// Verify that it is a valid locale.
if(!IsValidLocale(locale, LCID_SUPPORTED))
{
return E_INVALIDARG;
}
HRESULT hr;
IADs *padsRoot = NULL;
hr = ADsOpenObject( L"LDAP://rootDSE",
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)&padsRoot);
if(SUCCEEDED(hr))
{
VARIANT var;
VariantInit(&var);
// Get the DN to the configuration container.
hr = padsRoot->Get(CComBSTR(L"configurationNamingContext"), &var);
if(SUCCEEDED(hr))
{
WCHAR wszPath[MAX_PATH * 2];
// Build the string to bind to the container for the
// specified locale in the DisplaySpecifiers container.
swprintf_s(wszPath,
L"LDAP://cn=%s-Display,cn=%x,cn=DisplaySpecifiers,%s",
pwszClass,
locale,
var.bstrVal);
VariantClear(&var);
// Bind to the container.
hr = ADsOpenObject( wszPath,
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)ppads);
}
padsRoot->Release();
}
return hr;
}
/**************************************************************************
GetClassDisplayLabel()
**************************************************************************/
HRESULT GetClassDisplayLabel(LPWSTR pwszClass,
LCID locale,
BSTR *pbstrClassLabel)
{
if((NULL == pwszClass) || (NULL == pbstrClassLabel))
{
return E_INVALIDARG;
}
*pbstrClassLabel = NULL;
HRESULT hr;
IADs *padsDispSpec;
hr = GetClassDisplaySpecifierContainer(pwszClass, locale, &padsDispSpec);
if(SUCCEEDED(hr))
{
VARIANT var;
VariantInit(&var);
// Get the classDisplayName property value.
hr = padsDispSpec->Get(CComBSTR(L"classDisplayName"), &var);
if(SUCCEEDED(hr))
{
if(VT_BSTR == var.vt)
{
// Do not free the BSTR. The caller will handle it.
*pbstrClassLabel = var.bstrVal;
}
else
{
VariantClear(&var);
hr = E_FAIL;
}
}
padsDispSpec->Release();
}
return hr;
}
/**************************************************************************
GetAttributeDisplayLabel()
**************************************************************************/
HRESULT GetAttributeDisplayLabel(LPWSTR pwszClass,
LPWSTR pwszAttribute,
LCID locale,
BSTR *pbstrAttributeLabel)
{
if( (NULL == pwszClass) ||
(NULL == pwszAttribute) ||
(NULL == pbstrAttributeLabel))
{
return E_INVALIDARG;
}
*pbstrAttributeLabel = NULL;
HRESULT hr;
IADs *padsDispSpec;
hr = GetClassDisplaySpecifierContainer(pwszClass, locale, &padsDispSpec);
if(SUCCEEDED(hr))
{
VARIANT var;
VariantInit(&var);
// Get the attributeDisplayNames property values
hr = padsDispSpec->GetEx(CComBSTR(L"attributeDisplayNames"), &var);
if(SUCCEEDED(hr))
{
LONG lStart,
lEnd,
i;
SAFEARRAY *psa;
VARIANT varItem;
VariantInit(&varItem);
psa = V_ARRAY(&var);
// Get the lower and upper bound.
hr = SafeArrayGetLBound(psa, 1, &lStart);
hr = SafeArrayGetUBound(psa, 1, &lEnd);
/*
The attributeDisplayNames values take the form
"<attribute name>,<display name>". Enumerate the values, looking
for the one that begins with the specified attribute name.
*/
for(i = lStart; i <= lEnd; i++)
{
hr = SafeArrayGetElement(psa, &i, &varItem);
if(SUCCEEDED(hr))
{
WCHAR wszTemp[MAX_PATH];
wcsncpy_s(wszTemp,
V_BSTR(&varItem),
lstrlenW(pwszAttribute) + 1);
if(0 == lstrcmpiW(pwszAttribute, wszTemp))
{
LPWSTR pwszDisplayLabel;
/*
The proper value was found. Now, parse the value, looking
for the first comma, which delimits the attribute name
from the display name.
*/
for( pwszDisplayLabel = V_BSTR(&varItem);
*pwszDisplayLabel;
pwszDisplayLabel = CharNextW(pwszDisplayLabel))
{
if(',' == *pwszDisplayLabel)
{
/*
The delimiter was found. Set the string
pointer to the next character, which is the
first character of the display name.
*/
pwszDisplayLabel = CharNextW(pwszDisplayLabel);
break;
}
}
if(*pwszDisplayLabel)
{
// Copy the display name to the output.
*pbstrAttributeLabel = CComBSTR(pwszDisplayLabel).Detach();
hr = S_OK;
}
/*
Release the item variant because the break prevents
it from getting released by the VariantClear call below.
*/
VariantClear(&varItem);
break;
}
VariantClear(&varItem);
}
}
}
padsDispSpec->Release();
}
return hr;
}