속성 페이지 COM 개체 구현
속성 시트 확장은 in-proc 서버로 구현된 COM 개체입니다. 속성 시트 확장은 IShellExtInit 및 IShellPropSheetExt 인터페이스를 구현해야 합니다. 속성 시트 확장은 사용자가 속성 시트 확장이 클래스의 표시 지정자에 등록된 클래스의 개체에 대한 속성 시트를 표시할 때 인스턴스화됩니다.
- IShellExtInit 구현
- IShellPropSheetExt 구현
- 속성 페이지에 확장 개체 전달
- Notification 개체 작업
- 기타
- 다중 선택 속성 시트
- Windows Server 2003의 새로운 기능
- 관련 항목
IShellExtInit 구현
속성 시트 확장 COM 개체가 인스턴스화되면 IShellExtInit::Initialize 메서드가 호출됩니다. IShellExtInit::Initialize 는 속성 시트가 적용되는 디렉터리 개체와 관련된 데이터를 포함하는 IDataObject 개체를 속성 시트 확장에 제공합니다.
IDataObject에는 CFSTR_DSOBJECTNAMES 형식의 데이터가 포함되어 있습니다. CFSTR_DSOBJECTNAMES 데이터 형식은 DSOBJECTNAMES 구조를 포함하는 HGLOBAL입니다. DSOBJECTNAMES 구조체에는 속성 시트 확장이 적용되는 디렉터리 개체 데이터가 포함됩니다.
IDataObject에는 CFSTR_DS_DISPLAY_SPEC_OPTIONS 형식의 데이터도 포함됩니다. CFSTR_DS_DISPLAY_SPEC_OPTIONS 데이터 형식은 DSDISPLAYSPECOPTIONS 구조를 포함하는 HGLOBAL입니다. DSDISPLAYSPECOPTIONS에는 확장에서 사용할 구성 데이터가 포함되어 있습니다.
IShellExtInit::Initialize에서 S_OK 이외의 값이 반환되면 속성 시트가 표시되지 않습니다.
IShellExtInit::Initialize 메서드의 pidlFolder 및 hkeyProgID 매개 변수는 사용되지 않습니다.
IDataObject의 참조 수를 증가시켜 확장에서 IDataObject 포인터를 저장할 수 있습니다. 이 인터페이스는 더 이상 필요하지 않은 경우 해제해야 합니다.
IShellPropSheetExt 구현
IShellExtInit::Initialize가 반환되면 IShellPropSheetExt::AddPages 메서드가 호출됩니다. 속성 시트 확장은 이 메서드 중에 페이지 또는 페이지를 추가해야 합니다. 속성 페이지는 PROPSHEETPAGE 구조를 채운 다음 이 구조를 CreatePropertySheetPage 함수에 전달하여 만듭니다. 그런 다음 lpfnAddPage 매개 변수에서 IShellPropSheetExt::AddPages에 전달된 콜백 함수를 호출하여 속성 페이지가 속성 시트에 추가됩니다.
IShellPropSheetExt::AddPages에서 S_OK 이외의 값이 반환되면 속성 시트가 표시되지 않습니다.
속성 시트 확장이 속성 시트에 페이지를 추가할 필요가 없는 경우 lpfnAddPage 매개 변수에서 IShellPropSheetExt::AddPages에 전달된 콜백 함수를 호출하면 안 됩니다.
IShellPropSheetExt::ReplacePage 메서드가 사용되지 않습니다.
속성 페이지에 확장 개체 전달
속성 시트 확장 개체는 속성 페이지와 독립적입니다. 대부분의 경우 속성 페이지에서 확장 개체 또는 다른 개체를 사용할 수 있어야 합니다. 이렇게 하려면 PROPSHEETPAGE 구조체의 lParam 멤버를 개체 포인터로 설정합니다. 그러면 속성 페이지에서 WM_INITDIALOG 메시지를 처리할 때 이 값을 검색할 수 있습니다. 속성 페이지의 경우 WM_INITDIALOG 메시지의 lParam 매개 변수는 PROPSHEETPAGE 구조체에 대한 포인터입니다. WM_INITDIALOG 메시지의 lParam을 PROPSHEETPAGE 포인터로 캐스팅한 다음 PROPSHEETPAGE 구조체의 lParam 멤버를 검색하여 개체 포인터를 검색합니다.
다음 C++ 코드 예제에서는 개체를 속성 페이지에 전달하는 방법을 보여줍니다.
case WM_INITDIALOG:
{
LPPROPSHEETPAGE pPage = (LPPROPSHEETPAGE)lParam;
if(NULL != pPage)
{
CPropSheetExt *pPropSheetExt;
pPropSheetExt = (CPropSheetExt*)pPage->lParam;
if(pPropSheetExt)
{
return pPropSheetExt>OnInitDialog(wParam, lParam);
}
}
}
break;
IShellPropSheetExt::AddPages가 호출된 후 속성 시트는 속성 시트 확장 개체를 해제하고 다시는 사용하지 않습니다. 즉, 속성 페이지가 표시되기 전에 확장 개체가 삭제됩니다. 페이지가 개체 포인터에 액세스하려고 하면 메모리가 해제되고 포인터가 유효하지 않습니다. 이 문제를 해결하려면 페이지가 추가될 때 확장 개체에 대한 참조 수를 증분한 다음 속성 페이지 대화 상자가 제거되면 개체를 해제합니다. 이렇게 하면 페이지가 처음 표시될 때까지 속성 페이지 대화 상자가 만들어지지 않으므로 또 다른 문제가 발생합니다. 사용자가 확장 페이지를 선택하지 않으면 페이지가 만들어지고 제거되지 않습니다. 이로 인해 확장 개체가 해제되지 않으므로 메모리 누수가 발생합니다. 이를 방지하려면 속성 페이지 콜백 함수를 구현합니다. 이렇게 하려면 PROPSHEETPAGE 구조체의 dwFlags 멤버에 PSP_USECALLBACK 플래그를 추가하고 PROPSHEETPAGE 구조체의 pfnCallback 멤버를 구현된 PropSheetPageProc 함수의 주소로 설정합니다. PropSheetPageProc 함수가 PSPCB_RELEASE 알림을 받으면 PropSheetPageProc의 ppsp 매개 변수에 PROPSHEETPAGE 구조체에 대한 포인터가 포함됩니다. PROPSHEETPAGE 구조체의 lParam 멤버에는 개체를 해제하는 데 사용할 수 있는 확장 포인터가 포함되어 있습니다.
다음 C++ 코드 예제에서는 확장 개체를 해제하는 방법을 보여줍니다.
UINT CALLBACK CPropSheetExt::PageCallbackProc( HWND hWnd,
UINT uMsg,
LPPROPSHEETPAGE ppsp)
{
switch(uMsg)
{
case PSPCB_CREATE:
// Must return TRUE to enable the page to be created.
return TRUE;
case PSPCB_RELEASE:
{
/*
Release the object. This is called even if the page dialog box was
never actually created.
*/
CPropSheetExt *pPropSheetExt = (CPropSheetExt*)ppsp->lParam;
if(pPropSheetExt)
{
pPropSheetExt->Release();
}
}
break;
}
return FALSE;
}
Notification 개체 작업
속성 시트 확장 페이지는 확장에 알 수 없는 구성 요소에서 만든 속성 시트 내에 표시되므로 확장 페이지와 속성 시트 간의 데이터 전송을 처리하려면 "manager"를 사용해야 합니다. 이 "관리자"를 알림 개체라고 합니다. 알림 개체는 개별 페이지와 속성 시트 간에 중재자로 작동합니다.
속성 시트 확장 개체가 초기화되면 확장은 ADsPropCreateNotifyObj를 호출하고 IShellExtInit::Initialize 및 디렉터리 개체 이름에서 가져온 IDataObject를 전달하여 알림 개체를 만들어야 합니다. ADsPropCreateNotifyObj 함수에서 만든 알림 개체가 이 작업을 수행하므로 IDataObject 인터페이스의 참조 수를 증분할 필요가 없습니다. 나중에 사용하기 위해 ADsPropCreateNotifyObj 에서 제공하는 알림 개체 핸들을 저장해야 합니다. ADsPropCreateNotifyObj 는 IShellExtInit::Initialize 또는 IShellPropSheetExt::AddPages 중에 호출할 수 있습니다. 속성 시트 확장이 종료되면 알림 개체에 WM_ADSPROP_NOTIFY_EXIT 메시지를 보내야 합니다. 이로 인해 알림 개체가 자체 삭제됩니다. PropSheetPageProc 함수가 PSPCB_RELEASE 알림을 받을 때 가장 좋습니다.
속성 시트 확장은 ADsPropGetInitInfo를 호출하여 CFSTR_DSOBJECTNAMES 클립보드 형식에서 제공하는 데이터 외에 데이터를 가져올 수 있습니다. ADsPropGetInitInfo를 사용하는 장점 중 하나는 디렉터리 개체를 프로그래밍 방식으로 작업하는 데 사용되는 IDirectoryObject 개체를 제공한다는 것입니다.
참고
대부분의 COM 메서드 및 함수와 달리 ADsPropGetInitInfo 는 IDirectoryObject 개체에 대한 참조 수를 증가시키지 않습니다. 참조 수가 먼저 수동으로 증가하지 않는 한 IDirectoryObject 를 해제하면 안 됩니다.
속성 페이지를 처음 만들 때 확장은 페이지의 창 핸들을 사용하여 ADsPropSetHwnd 를 호출하여 페이지를 알림 개체에 등록해야 합니다.
ADsPropCheckIfWritable 은 속성 시트 확장에서 속성을 쓸 수 있는지 확인하는 데 사용할 수 있는 유틸리티 함수입니다.
기타
속성 페이지의 핸들이 페이지 대화 상자 프로시저에 전달됩니다. 속성 시트는 속성 페이지의 직접 부모이므로 속성 페이지 핸들을 사용하여 GetParent 함수를 호출하여 속성 시트의 핸들을 가져올 수 있습니다.
확장 페이지의 내용이 변경되면 확장은 PropSheet_Changed 매크로를 사용하여 속성 시트에 변경 내용을 알려야 합니다. 그러면 속성 시트에서 적용 단추를 사용하도록 설정합니다.
Multiple-Selection 속성 시트
Windows Server 2003 이상 운영 체제에서 Active Directory 관리 MMC 스냅인은 여러 디렉터리 개체에 대한 속성 시트 확장을 지원합니다. 이러한 속성 시트는 속성이 한 번에 둘 이상의 항목에 대해 볼 때 표시됩니다. 단일 선택 속성 시트 확장과 다중 선택 속성 시트 확장의 주요 차이점은 IShellExtInit::Initialize의 CFSTR_DSOBJECTNAMES 클립보드 형식에서 제공하는 DSOBJECTNAMES 구조체에 둘 이상의 DSOBJECT 구조체가 포함된다는 점입니다.
알림 개체를 만들 때 다중 선택 속성 시트 확장은 확장에서 만든 이름이 아니라 스냅인에서 제공하는 고유한 이름을 전달해야 합니다. 고유한 이름을 가져오려면 IShellExtInit::Initialize에서 가져온 IDataObject에서 CFSTR_DS_MULTISELECTPROPPAGE 클립보드 형식을 요청합니다. 이 데이터는 고유한 이름인 null로 끝나는 유니코드 문자열을 포함하는 HGLOBAL 입니다. 그런 다음 이 고유한 이름이 ADsPropCreateNotifyObj 함수에 전달되어 알림 개체를 만듭니다. 속성 시트 COM 개체의 구현을 위한 예제 코드의CreateADsNotificationObject 예제 함수는 다중 선택 속성 시트를 지원하지 않는 이전 버전의 스냅인과 호환될 뿐만 아니라 이 작업을 올바르게 수행하는 방법을 보여 줍니다.
다중 선택 속성 시트의 경우 시스템은 DSOBJECT 배열의 첫 번째 개체에만 바인딩됩니다. 이 때문에 ADsPropGetInitInfo 는 배열의 첫 번째 개체에 대한 IDirectoryObject 및 쓰기 가능한 특성만 제공합니다. 배열의 다른 개체는 바인딩되지 않습니다.
다중 선택 속성 시트 확장은 adminMultiselectPropertyPages 특성 아래에 등록됩니다.
Windows Server 2003의 새로운 기능
Windows Server 2003의 새로운 기능은 다음과 같습니다.
속성 페이지에 오류가 발생하면 적절한 오류 데이터를 사용하여 ADsPropSendErrorMessage 를 호출할 수 있습니다. ADsPropSendErrorMessage 는 모든 오류 메시지를 큐에 저장합니다. 이러한 메시지는 다음에 ADsPropShowErrorDialog 가 호출될 때 표시됩니다. ADsPropShowErrorDialog가 반환되면 큐에 대기 중인 메시지가 삭제됩니다.
Windows Server 2003에는 ADsPropSetHwndWithTitle 함수가 도입되었습니다 . 이 함수는 ADsPropSetHwnd와 유사하지만 페이지 제목을 포함합니다. 이렇게 하면 ADsPropShowErrorDialog 가 표시하는 오류 대화 상자가 사용자에게 더 유용한 데이터를 제공할 수 있습니다. 속성 시트 확장에서 ADsPropShowErrorDialog 함수를 사용하는 경우 확장은 ADsPropSetHwnd 대신 ADsPropSetHwndWithTitle을 사용해야 합니다.
관련 항목