Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1852405
  • 博文数量: 909
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 12260
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-06 20:50
文章分类

全部博文(909)

文章存档

2008年(909)

我的朋友

分类:

2008-05-06 22:10:18

一起学习
关于 IDispatch 接口的 LPDispatch 属性的实现

作者:杨老师


下载源代码

  好象是绕口令一样的标题。呵呵,看看下面的这个例子,我想大家就知道是什么意思了吧。
在脚本语言中,我们经常看到类似这样的语句: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代码
  7. LPDISPATCH CAAA::GetBBB()
    
    {
    
      return m_bbb.GetIDispatch(TRUE);
    
    }
    
    void CAAA::SetBBB(LPDISPATCH newValue)
    
    {
    
      SetNotSupported();
    
    }
  8. 在IBBB中,添加方法(例子程序中,实现了一个数值加法)
  9. 修改CBBB的析构函数,从protected移动到public中
二、用ATL实现LPDispatch自动化接口属性
  1. 产生一个ATL的组件程序框架(例子程序中,使用的是DLL)
  2. 添加一个IAAA的双接口
  3. 手工添加另一个IBBB的双接口
    IDL文件修改如下:
  4. ... ...
    
    [
    
      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()
  5. 在IAAA中,添加属性BBB,类型为LPDispatch,只实现Get方法
    STDMETHODIMP CAAA::get_BBB(LPDISPATCH *pVal)
    
    
    
    {
    
      QueryInterface(IID_IBBB,(LPVOID *)pVal);
    
      return S_OK;
    
    }
  6. 在IBBB中,添加方法(例子程序中,实现了一个数值加法)
    HRESULT Add([in] long n1,[in] long n2, [out,retval] long *pnSum);
三、测试

  
下载代码后,在Release目录中有两个DLL和两个VBS的测试程序。用Regsvr32.exe注册两个组件后,双点VBS文件就可以执行了。
下载本文示例代码


关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现关于 IDispatch 接口的 LPDispatch 属性的实现
阅读(556) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~