您的位置:首页 > 其它

关于 IDispatch 接口的 LPDispatch 属性的实现

2012-06-19 11:33 176 查看
文章概要:
在我们自己写的自动化组件中,当然你可以把所有的方法都用唯一的一个自动化接口表现出来,但是这样好吗?所有的方法都处于一个层次上,没有适当的分类,显然不是个优秀的组件。好了,下面看看我们如何实现分层次的自动化组件吧。

好象是绕口令一样的标题。呵呵,看看下面的这个例子,我想大家就知道是什么意思了吧。
在脚本语言中,我们经常看到类似这样的语句:obj.Document.Write(...),obj显然是一个自动化的对象(IDispatch),它可以拥有方法和属性。但 Document 到底是什么那?如果说它是方法,那么就无法解释 Document.Write 了;如果说他是属性,那么属性怎么还有Write方法那?答案是Document是一个LPDispatch类型的属性(具有自动化类型的属性),当然,这样的属性拥有方法就不奇怪了吧。
在我们自己写的自动化组件中,当然你可以把所有的方法都用唯一的一个自动化接口表现出来,但是这样好吗?所有的方法都处于一个层次上,没有适当的分类,显然不是个优秀的组件。好了,下面看看我们如何实现分层次的自动化组件吧。
MFC(CCmdTarget) 和 ATL(DUAL 双接口)都可以实现组件自动化的接口。下面分别来实现。(VC6编译测试通过)
一、用MFC实现LPDispatch自动化接口属性
1.产生一个支持自动化(Automation)的程序(例子程序中,使用的是DLL)
2.添加一个自动化类 CAAA ,派生于CCmdTarget。选择Createable by type ID。注意,只有选择这项,才能被外部程序(VB)CreateObject或(VC)CreateDispatch等方法建立对象
3.添加另一个自动化类CBBB,派生于CCmdTarget。选择Automation

4.在CAAA中,添加的成员对象,CBBB m_bbb

5.在IAAA中,添加名称为BBB,类型为LPDispatch的属性,使用Get/Set类型

6.完成BBB属性的Get/Set代码

1.
LPDISPATCH CAAA::GetBBB()

2.
{

3.
return
m_bbb.GetIDispatch(TRUE);

4.
}

5.
void
CAAA::SetBBB(LPDISPATCH newValue)

6.
{

7.
SetNotSupported();

8.
}


7.在IBBB中,添加方法(例子程序中,实现了一个数值加法)

8.修改CBBB的析构函数,从protected移动到public中

二、用ATL实现LPDispatch自动化接口属性

1.产生一个ATL的组件程序框架(例子程序中,使用的是DLL)

2.添加一个IAAA的双接口

3.手工添加另一个IBBB的双接口

IDL文件修改如下:

01.
... ...

02.
[

03.
object,

04.
uuid
(D17A119E-0FEC-4737-8EBD-4AA040393A36),
//这里是例子程序中的IID,你需要自己产生

05.
dual,

06.
helpstring(
"IBBB Interface"
),

07.
pointer_default(unique)

08.
]

09.
interface IBBB : IDispatch

10.
{

11.
};

12.
... ...

13.
coclass AAA

14.
{

15.
[
default
] interface IAAA;

16.
interface IBBB;
//这是手工添加的第2个接口

17.
};


头文件,修改如下:

添加派生关系

1.
class
ATL_NO_VTABLE CAAA :

2.
public
CComObjectRootEx,

3.
public
CComCoClass,

4.
public
IDispatchImpl,

5.
public
IDispatchImpl
//新增


添加并修改接口入口宏

1.
BEGIN_COM_MAP(CAAA)

2.
COM_INTERFACE_ENTRY(IAAA)

3.
COM_INTERFACE_ENTRY(IBBB)
//新增

4.

5.
 
//修改,使用ENTRY2方式,这样VB才能知道默认使用哪个IDispatch接口

6.
COM_INTERFACE_ENTRY2(IDispatch,IAAA)

7.
END_COM_MAP()


4.在IAAA中,添加属性BBB,类型为LPDispatch,只实现Get方法

1.
STDMETHODIMP CAAA::get_BBB(LPDISPATCH *pVal)

2.

3.
{

4.
QueryInterface(IID_IBBB,(
LPVOID
*)pVal);

5.
return
S_OK;

6.
}


5.在IBBB中,添加方法(例子程序中,实现了一个数值加法)

1.
HRESULT
Add([in]
long
n1,[in]
long

n2, [out,retval]
long
*pnSum);


三、测试

下载代码后,在Release目录中有两个DLL和两个VBS的测试程序。用Regsvr32.exe注册两个组件后,双点VBS文件就可以执行了。
http://www.vckbase.com/index.php/wv/894
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: