Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2012824
  • 博文数量: 960
  • 博客积分: 52560
  • 博客等级: 大将
  • 技术积分: 13131
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-31 14:15
文章分类

全部博文(960)

文章存档

2011年(1)

2008年(959)

我的朋友

分类: C/C++

2008-08-01 17:07:50

下载本文示例代码
下载源代码

一、前言
前段时间,由于工作比较忙,没有能及时地写作。其间收到了很多网友的来信询问和鼓励,在此一并表示感谢。咳......我也需要工作来养家糊口呀......
上回书介绍了两种方法来写自动化
(IDispatch)接口的组件程序,一是用 MFC 方式编写“纯粹”的 IDispatch 接口;二是用 ATL 方式编写“双接口”的组件。

二、IDispatch 接口和双接口
使用者要想调用普通的 COM 组件功能,必须要加载这个组件的类型库(Type library)文件 tlb(比如在 VC 中使用 #import)。然而,在脚本程序中,由于脚本是被解释执行的,所以无法使用加载类型库的方式进行预编译。那么脚本解释器如何使用 COM 组件那?这就是自动化(IDispatch)组件大显身手的地方了。IDispatch 接口需要实现4个函数,调用者只通过这4个函数,就能实现调用自动化组件中所有的函数。这4个函数功能如下:
 

下载本文示例代码
HRESULT GetTypeInfoCount(
[out] UINT * pctinfo)
组件中提供几个类型库?当然一般都是一个啦。
但如果你在一个组件中实现了多个
IDispatch 接口,那就不一定啦(注1)
HRESULT GetTypeInfo(
[in] UINT iTInfo,
[in] LCID lcid,
[out] ITypeInfo ** ppTInfo)
调用者通过该函数取得他想要的类型库。
幸好,在 99% 的情况下,我们都不用关心这两个函数的实现,因为 MFC/ATL 都帮我们完成了默认的一个实现,如果是自己完成函数代码,甚至可以直接返回 E_NOTIMPL 表示没有实现。(注2)
HRESULT GetIDsOfNames(
[in] REFIID riid,
[in,size_is(cNames)] LPOLESTR * rgszNames,
[
in] UINT cNames,
[in] LCID lcid,
[out,size_is(cNames)] DISPID * rgDispId)
根据函数名称取得函数序号,为调用 Invoke() 做准备。
所谓函数序号,大家去观察双接口 IDL 文件和 MFC 的 ODL 文件,每一个函数和属性都会有
[id(序号)....] 这样的描述。
HRESULT Invoke(
[in] DISPID dispIdMember,
[in] REFIID riid,
[in] LCID lcid,
[in] WORD wFlags,
[in,out] DISPPARAMS * pDispParams,
[out] VARIANT * pVarResult,
[out] EXCEPINFO * pExcepInfo,
[out] UINT * puArgErr)
根据序号,执行函数。
使用 MFC/ATL 写的组件程序,我们也不必关心这个函数的实现。如果是自己写代码,则该函数类似如下实现:
switch(dispIdMember)
{
case 1: .....; break;
case 2: .....; break;
....
}
其实,就是根据序号进行分支调用啦。(注3)
 
阅读(373) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~