分类: C/C++
2008-04-23 21:49:35
关于 IDispatch 接口的 LPDispatch 属性的实现
作者:
好象是绕口令一样的标题。呵呵,看看下面的这个例子,我想大家就知道是什么意思了吧。
在脚本语言中,我们经常看到类似这样的语句:obj.Document.Write(...),obj显然是一个自动化的对象(IDispatch),它可以拥有方法和属性。但 Document 到底是什么那?如果说它是方法,那么就无法解释 Document.Write 了;如果说他是属性,那么属性怎么还有Write方法那?答案是Document是一个LPDispatch类型的属性(具有自动化类型的属性),当然,这样的属性拥有方法就不奇怪了吧。
在我们自己写的自动化组件中,当然你可以把所有的方法都用唯一的一个自动化接口表现出来,但是这样好吗?所有的方法都处于一个层次上,没有适当的分类,显然不是个优秀的组件。好了,下面看看我们如何实现分层次的自动化组件吧。
MFC(CCmdTarget) 和 ATL(DUAL 双接口)都可以实现组件自动化的接口。下面分别来实现。(VC6编译测试通过)
一、用MFC实现LPDispatch自动化接口属性
LPDISPATCH CAAA::GetBBB() { return m_bbb.GetIDispatch(TRUE); } void CAAA::SetBBB(LPDISPATCH newValue) { SetNotSupported(); }
... ... [ object, uuid(D17A119E-0FEC-4737-8EBD-4AA040393A36), //这里是例子程序中的IID,你需要自己产生 dual, helpstring("IBBB Interface"), pointer_default(unique) ] interface IBBB : IDispatch { }; ... ... coclass AAA { [default] interface IAAA; interface IBBB; //这是手工添加的第2个接口 };头文件,修改如下:
class ATL_NO_VTABLE CAAA : public CComObjectRootEx添加并修改接口入口宏, public CComCoClass , public IDispatchImpl , public IDispatchImpl //新增
BEGIN_COM_MAP(CAAA) COM_INTERFACE_ENTRY(IAAA) COM_INTERFACE_ENTRY(IBBB) //新增 //修改,使用ENTRY2方式,这样VB才能知道默认使用哪个IDispatch接口 COM_INTERFACE_ENTRY2(IDispatch,IAAA) END_COM_MAP()
STDMETHODIMP CAAA::get_BBB(LPDISPATCH *pVal) { QueryInterface(IID_IBBB,(LPVOID *)pVal); return S_OK; }
HRESULT Add([in] long n1,[in] long n2, [out,retval] long *pnSum);