TN039: MFC/OLE 자동화 구현

OLE IDispatch 인터페이스 개요

IDispatch 인터페이스를 응용 프로그램의 기능 사용 되는 응용 프로그램 노출 메서드와 같은 속성에 의해 다른 언어 또는 Visual BASIC과 같은 다른 응용 프로그램을 만들 수 있습니다 수단 이다. 이 인터페이스의 가장 중요 한 부분은 IDispatch::Invoke 함수입니다. MFC 사용 "디스패치 맵" IDispatch::Invoke를 구현 합니다. 디스패치 맵 레이아웃 또는 "모양" CCmdTarget의 MFC 구현 정보를 제공-직접 개체의 속성을 조작 하거나 멤버 IDispatch::Invoke 요청을 만족 시키기 위해 개체 내에서 함수를 호출할 수 있도록 파생 클래스,。

대부분의 경우, ClassWizard 및 MFC OLE 자동화 응용 프로그램 프로그래머에서 내용의 대부분을 숨길 협조. 프로그래머는 응용 프로그램에서 노출 하는 실제 기능에 집중 하 고 기본 배관에 대해 걱정할 필요 하지 않습니다.

그러나 경우,, MFC 장면 뒤에 무엇을 하 고 이해 해야 하는 경우 이 노트는 프레임 워크에서 DISPID의멤버 함수 및 속성에 할당 하는 방법을 주소 것 이다. MFC를 사용 하 여 s DISPID를 할당 하는 것에 대 한 알고리즘의 지식은 응용 프로그램의 개체에 대 한 "형식 라이브러리"를 만들 때와 같은 Id를 알아야 할 경우에 필요。

MFC DISPID 할당

자동화 속성 및 그들의 코드 (예: obj. 메서드 사용 자동화 (Visual Basic 사용자, 예를 들어), 최종 사용자의 실제 이름을 보고 비록ShowWindow), IDispatch::Invoke 의 구현을 실제 이름을 수신 하지 않습니다. 최적화의 이유로 받으면는 DISPID, 32-비트 "마법의 쿠키" 메서드 또는 속성에 액세스할 수 있는 설명입니다. 이러한 DISPID 값은 IDispatch::GetIDsOfNames라고 하는 다른 메서드를 통해 IDispatch 구현에서 반환 됩니다. 자동화 클라이언트 응용 프로그램 각 멤버 또는 속성에 액세스 하려면, 의도 대 한 이름 두 번 호출 하 고 IDispatch::Invoke에 대 한 이후 호출을 위해 그들을 캐시 합니다. 이 이렇게 비싼 문자열 조회만 이루어집니다 한번 IDispatch::Invoke 통화 당 한 번 대신 개체 사용。

MFC는 각 메서드 및 속성을 기반으로 두 가지에 대 한 DISPIDs를 결정:

DISPID 는 두 부분으로 나뉩니다. DISPID LOWORD 디스패치 맵 위에 거리가 첫 번째 구성 요소를 포함합니다. HIWORD 거리가 가장 많이 파생 된 클래스를 포함합니다. 예를 들어:

cDispPoint 클래스: 공용 CCmdTarget
{
공개:
 nbsp;? 짧은 m_x, m_y;
 ?? ...
 ?? DECLARE_DISPATCH_MAP()
 ?? ...
};

CDisp3DPoint 클래스: 공용 CDispPoint
{
공개:
 ?? 짧은 m_y;
 ?? ...
 ?? DECLARE_DISPATCH_MAP()
 ?? ...
};

BEGIN_DISPATCH_MAP (CDispPoint, CCmdTarget)
 ?? DISP_PROPERTY (CDispPoint, "x", m_x VT_I2)
 ?? DISP_PROPERTY (CDispPoint, "y", m_y, VT_I2)
END_DISPATCH_MAP()

BEGIN_DISPATCH_MAP (CDisp3DPoint, CDispPoint)
 ?? DISP_PROPERTY (CDisp3DPoint, "z", m_z, VT_I2)
END_DISPATCH_MAP()(&N)

보시 다시 피, 거기에 OLE 자동화 인터페이스를 노출 하는 두 개의 클래스. 이러한 클래스 중 하나에서 다른 파생 및 따라서 OLE 자동화 부품을 포함 하 여 기본 클래스의 기능을 활용 ("x" 및 "y"이이 경우에는 속성)。

MFC 클래스 Cdisppoint에 대 한 DISPIDs를 같이 생성:

속성 Xnbsp;?? (DISPID) 0X00000001
Y 속성 (DISPID) 0x00000002(&N)

속성이 기본 클래스, 이후 DISPID HIWORD 는 항상 0 (Cdisppoint에 대 한 가장 많이 파생 된 클래스에서 거리는 0)。

MFC 클래스 Cdisp3dpoint에 대 한 DISPIDs를 같이 생성:

속성 Znbsp;?? (DISPID) 0X00000001
속성 (DISPID) 0x00010001 X
Y 속성 (DISPID) 0x00010002(&N)

Z 속성은 CDisp3DPoint 속성을 노출 하는 클래스에 정의 된 이후 HIWORD 제로 함께 DISPID 주어 집니다. X 및 Y 속성은 기본 클래스에 정의 된 DISPID HIWORD 이므로 1, 가장 많이 파생 된 클래스에서 한 파생의 거리에서 이러한 속성이 정의 된 클래스 이므로。

메모nbsp;??거기에 명시적 DISPID 를 가진 지도 항목에 존재 하는 경우에 LOWORD 은 항상 지도에서 위치에 따라 결정 됩니다 ( DISP_PROPERTY 및 DISP_FUNCTION 매크로의 _ID 버전에 대 한 내용은 다음 섹션 참조)(&N)。

MFC 디스패치 맵 기능 고급

이번 버전의 Visual c + + 클래스 마법사에서 지원 하지 않는 추가 기능의 여러 가지가 있습니다. Classwizard는 DISP_FUNCTION, DISP_PROPERTY및 DISP_PROPERTY_EX 메서드와 멤버 변수 속성 get/set 멤버 함수 속성을 각각 정의 하는 지원 합니다. 이러한 능력은 일반적으로 대부분의 자동화 서버를 만드는 데 필요한 모든。

ClassWizard 지원 매크로 적절 한 때에 다음 추가 매크로 사용할 수 있습니다: DISP_PROPERTY_NOTIFY및 DISP_PROPERTY_PARAM。

DISP_PROPERTY_NOTIFY-매크로 설명

DISP_PROPERTY_NOTIFY (클래스, pszName, 회원명, pfnAfterSet, vtPropType)

클래스

클래스의 이름。

pszName

속성의 외부 이름。

회원명

속성이 저장 하는 멤버 변수의 이름。

pfnAfterSet

속성이 변경 될 때 호출할 멤버 함수 이름。

vtPropType

속성의 유형을 지정 하는 값。

메모nbsp;??이 매크로 DISP_PROPERTY, 처럼 제외 추가 인수를 수락 합니다. 추가 인수 pfnAfterSet, nothing을 반환 하 고 매개 변수를 'void OnPropertyNotify()' 멤버 함수 이어야 합니다. 후 멤버 변수 수정 되었습니다 라는 것입니다(&N).

DISP_PROPERTY_PARAM-매크로 설명

DISP_PROPERTY_PARAM (클래스, pszName, pfnGet, pfnSet, vtPropType, vtsParams)

클래스

클래스의 이름。

pszName

속성의 외부 이름。

memberGet

속성을 가져오는 데 사용 하는 멤버 함수의 이름。

memberSet

속성을 설정 하는 데 사용 하는 멤버 함수의 이름。

vtPropType

속성의 유형을 지정 하는 값。

vtsParams

각 매개 변수에 대 한 VTS_를 구분 하는 문자열 공간。

메모nbsp;DISP_PROPERTY_EX 매크로 처럼이 매크로 별도 Get 및 Set 멤버 함수를 사용 하 여 액세스 하는 속성을 정의 합니다. 그러나,이 매크로 사용 하면 속성에 대 한 매개 변수 목록을 지정할 수 있습니다. 다른 방법으로 인덱싱된 또는 매개 변수가 있는 속성을 구현 하는 경우 유용 합니다. 매개 변수를 항상 배치 됩니다 먼저 뒤에 속성의 새 값. 예를 들어(&N):

DISP_PROPERTY_PARAM (CMyObject, "item", GetItem, SetItem, VT_DISPATCH, VTS_I2 VTS_I2)

get 및 set 멤버 함수에 해당 하는:

LPDISPATCH CMyObject::GetItem(short row, short col)
void CMyObject::SetItem (짧은 행, 짧은 대장균, LPDISPATCH newValue)

DISP_XXXX_ID-매크로 설명

DISP_FUNCTION_ID (클래스, pszName, dispid, pfnMember, vtRetVal, vtsParams)

DISP_PROPERTY_ID (클래스, pszName, dispid, 회원명, vtPropType)

DISP_PROPERTY_NOTIFY_ID (클래스, pszName, dispid, 회원명, pfnAfterSet, vtPropType)

DISP_PROPERTY_EX_ID (클래스, pszName, dispid, pfnGet, pfnSet, vtPropType)

DISP_PROPERTY_PARAM_ID (클래스, pszName, dispid, pfnGet, pfnSet, vtPropType, vtsParams)

클래스

클래스의 이름。

pszName

속성의 외부 이름。

dispid

속성 또는 메서드에 대 한 고정 된 DISPID。

pfnGet

속성을 가져오는 데 사용 하는 멤버 함수의 이름。

pfnSet

속성을 설정 하는 데 사용 하는 멤버 함수의 이름。

회원명

속성을 매핑할 멤버 변수 이름

vtPropType

속성의 유형을 지정 하는 값。

vtsParams

각 매개 변수에 대 한 VTS_를 구분 하는 문자열 공간。

메모nbsp;??이 매크로 사용 하면 MFC 하나에 자동으로 할당 되는 대신 DISPID 를 지정할 수 있습니다. 이러한 고급 매크로 동일한 이름이 제외 하 고는 ID 매크로 이름 (예: DISP_PROPERTY_ID)에 추가 ID를 pszName 매개 변수에 바로 뒤에 지정 된 매개 변수에 의해 결정 됩니다. AFXDISP를 참조 하십시오.이러한 매크로 대 한 자세한 내용은 H입니다. _ID 항목 디스패치 맵 끝에 배치 해야 합니다. 그들은 비와 같은 방식에서 자동 DISPID 생성을 영향을 미칠 것입니다-_ID 버전 매크로의 것 ( DISPID의위치에 의해 결정 됩니다). 예를 들어(&N)

BEGIN_DISPATCH_MAP (CDisp3DPoint, CCmdTarget)
 nbsp;? DISP_PROPERTY (CDisp3DPoint, "y", m_y, VT_I2)
 ?? DISP_PROPERTY (CDisp3DPoint, "z", m_z, VT_I2)
 ?? DISP_PROPERTY_ID (CDisp3DPoint, "x", 0x00020003, m_x VT_I2)
END_DISPATCH_MAP()(&N)

MFC 클래스 Cdisp3dpoint에 대 한 Dispid를 같이 생성 됩니다.:

속성 Xnbsp;?? (DISPID) 0X00020003
Y 속성 (DISPID) 0x00000002
Z 속성 (DISPID) 0x00000001(&N)

이전 버전과 호환성 이전에 기존 디스패치 인터페이스 또는 특정 시스템을 구현 하는 메서드 또는 속성 (일반적으로는 부정적인 DISPID, DISPID_NEWENUM 컬렉션 등으로 표시) 정의 유지 하는 데 유용 고정된 DISPID 를 지정。

Coleclientitem에 대 한 IDispatch 인터페이스를 가져오는 중

대부분의 서버는 자신의 문서 개체 함께 OLE 서버 기능 내에서 자동화를 지원 합니다. 하기 위해서는이 자동화 인터페이스에 대 한 액세스를 얻기 위해 직접 COleClientItem::m_lpObject 멤버 변수를 액세스 하는 데 필요한입니다. 아래 코드는 COleClientItem에서 파생 된 개체에 대 한 IDispatch 인터페이스를 검색 합니다. 경우이 기능이 필요한 응용 프로그램에 아래의 코드를 포함할 수 있습니다.

LPDISPATCH CMyClientItem::GetIDispatch()
{
 nbsp;? ASSERT_VALID(this);
 ?? ASSERT (m_lpObject! = NULL);

LPUNKNOWN lpUnk = m_lpObject;

Run ();??? / / 실행 해야 합니다

LPOLELINK lpOleLink = NULL;
 ?? 경우 (m_lpObject-> QueryInterface (IID_IOleLink, (LPVOID 멀리 *) & lpOleLink) NOERROR =)
 ?? {
 ?????? ASSERT (lpOleLink! = NULL);
 ?????? lpUnk = NULL;
 ?????? 경우 (lpOleLink-> GetBoundSource(&lpUnk)! = NOERROR)
 ?????? {
 ?????????? TRACE0 ("경고: 링크에 연결 되어 있지 않습니다! \n");
 ?????????? lpOleLink-> Release();
 ?????????? NULL; 반환
 ?????? }
 ?????? ASSERT (lpUnk! = NULL);
 ?? }

LPDISPATCH lpDispatch = NULL;
 ?? 경우 (lpUnk-> QueryInterface (IID_IDispatch, & lpDispatch)! = NOERROR)
 ?? {
 ?????? TRACE0 ("경고: Idispatch를 지원 하지 않습니다! \n");
 ?????? NULL; 반환
 ?? }

ASSERT (lpDispatch! = NULL);
 ?? 반환 lpDispatch;
}

디스패치 인터페이스에서 반환이 함수 직접 사용 하거나 형식이 안전한 액세스를 위해 COleDispatchDriver 에 연결 된 다음 수 있습니다. 그것은 작업을 직접 사용 하는 경우 해당 릴리스 멤버를 호출 하는 있는지 확인 할 때 포인터 ( COleDispatchDriver 소멸자는이 기본적으로)를 통해。

기술 노트 번호로 |nbsp; 카테고리별 기술 노트(&N)

Index