《MFC Windows程序设计》第18章(2):MFC和COM

  

     用C++类来编写COM对象有两种技术:“多重继承”和”嵌套类“。MFC使用“嵌套类”技术来实现COM接口。

1、嵌套类

以下为嵌套类技术实例,CComClass类为实现了IMath和ISpelling接口的MFC类,并且每个接口都有方法InIt,需要定义两个子类,每个子类实现一个接口:

class CComClass:public IUnknown
{
protected:
	long m_lRef;
	class CMath:public IMath
	{
		[...]
	};
	CMath m_objMath;
	class CSpelling:public ISpelling
	{
		[...]
	};
	CSpelling m_obgSpell;
public:
	CComClass();
	virtual ~CComClass()
	//IUnknown methods
	virtual HRESULT__stdcall QueryInterface(REFIID riid, void**ppv);
	virtual ULONG__stdcall AddRef();
	virtual ULONG__stdcall Release();
};

class CMath:public IMath
{
protected:
	CComClass* m_pParent;
public:
	CMath();
	virtual ~CMath();
	//IUnknown methods
	virtual HRESULT__stdcall QueryInterface(REFIID riid, void**ppv);
	virtual ULONG__stdcall AddRef();
	virtual ULONG__stdcall Release();
	//IMath methods
	virtual HRESULT__stdcall Add(int a, int b, int *pResult);
	virtual HRESULT__stdcall Subtract(int a, int b, int *pResult);
	virtual HRESULT__stdcall Init() = 0;
};

class CSpelling:public ISpelling
{
protected:
	CComClass* m_pParent;
public:
	CSpelling();
	virtual ~CSpelling();
	//IUnknown methods
	virtual HRESULT__stdcall QueryInterface(REFIID riid, void**ppv);
	virtual ULONG__stdcall AddRef();
	virtual ULONG__stdcall Release();
	//ISpelling methods
	virtual HRESULT__stdcall CheckSpelling(wchar_t pString);
	virtual HRESULT__stdcall Init() = 0;
};
如果调用CComClall的QueryInterface来请求IMath指针,则会获得指向CMath对象的指针:

*ppv = (IMath*)&m_objMath;
同样, 如果调用CComClall的QueryInterface来请求ISpelling指针,则会获得指向CSpelling对象的指针:
*ppv = (ISpelling*)&m_objSpell;
子对象会将对它的IUnknown方法的调用委派给父类中同样的方法,因为每个嵌套类都保存了一个CComClass指针,该指针是一个回溯指针,指向子对象的父亲,通过回溯指针调用CComClass的IUnknown方法,从而实现了委派。

通常在父亲的构造函数中初始化回溯指针:

CComClass::CComClass()
{
	[...]
	m_objMath.m_pParent = this;
	m_obgSpell.m_pParent = this;
}
嵌套类的IUnknown代码:

HRESULT__stdcall CComClass::CMath::QueryInterface(REFIID riid, void**ppv)
{
	return m_pParent->QueryInterface(riid, ppv);	
}

ULONG__stdcall CComClass::CMath::AddRef()
{
	return m_pParent->AddRef();
}

ULONG__stdcall CComClass::CMath::Release()
{
	return m_pParent->release();
}
2、MFC中的嵌套类

MFC类中利用宏隐藏了嵌套类。如MFC COM类COleDropTarget,它只实现了一个标准接口IDropTarget。在COleDropTarget类声明的结尾处有以下代码:

	BEGIN_INTERFACE_PART(DropTarget, IDropTarget)
		INIT_INTERFACE_PART(COleDropTarget, DropTarget)
		STDMETHOD(DragEnter)(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
		STDMETHOD(DragOver)(DWORD, POINTL, LPDWORD);
		STDMETHOD(DragLeave)();
		STDMETHOD(Drop)(LPDATAOBJECT, DWORD, POINTL pt, LPDWORD);
	END_INTERFACE_PART(DropTarget)
其中,BEGIN_INTERFACE_PART宏定义实现了一个COM接口的嵌套类,类名称是参数列表中第一个参数加上X,即XDropTarget,END_INTERFACE_PART宏声明了一个成员变量,它是这个嵌套类的实例。 BEGIN_INTERFACE_PARTEND_INTERFACE_PART之间为嵌套类的方法:包含三个IUnknown方法以及DragEnter、DragOver、DragLeave、Drop。

3、MFC和类厂






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值