COM组件设计与应用
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
IDispatch 接口for vc6.0
作者:杨老师
下载源代码
一、前言
终于写到了第九回,我也一直期盼着写这回的内容耶,为啥呢?因为自动化(automation)是非常常用、非常有用、非常精彩的一个COM 功能。由于WORD、EXCEL 等OFFICE 软件提供了“宏”的功能,就连我们使用的VC开发环境也提供了“宏”功能,更由于HTML、ASP、JSP 等都要依靠脚本(Script)的支持,更体现出了自动化接口的重要性。
如果你使用vc6.0 的开发环境,请继续阅读。
如果你使用 2003,请阅读下一回。
二、IDispatch接口
如果是编译型语言,那么我们可以让编译器在编译的时候装载类型库,也就是装载接口的描述。在第七回文章当中,我们分别使用了#include 方法和#import 方法来实现的。装载了类型库后,编译器就知道应该如何编译接口函数的调用了---这叫“前绑定”。但是,如果想在脚本语言中使用组件,问题就大了,因为脚本语言是解释执行的,它执行的时候不会知道具体的函数地址,怎么办?自动化接口就为此诞生了---“后绑定”。
自动化组件,其实就是实现了IDispatch 接口的组件。IDispatch 接口有4个函数,解释语言的执行器就通过这仅有的4个函数来执行组件所提供的功能。IDispatch 接口用IDL 形式说明如下:(注1)
[
object,
uuid(00020400-0000-0000-C000-000000000046), // IDispatch 接口的 IID = IID_IDispatch
pointer_default(unique)
]
interface IDispatch : IUnknown
{
typedef [unique] IDispatch * LPDISPATCH; // 转定义IDispatch * 为 LPDISPATCH
HRESULT GetTypeInfoCount([out] UINT * pctinfo); // 有关类型库的这两个函数,咱们以后再说
HRESULT GetTypeInfo([in] UINT iTInfo,[in] LCID lcid,[out] ITypeInfo ** ppTInfo);
HRESULT GetIDsOfNames( // 根据函数名字,取得函数序号(DISPID)
[in] REFIID riid,
[in, size_is(cNames)] LPOLESTR * rgszNames,
[in] UINT cNames,
[in] LCID lcid,
[out, size_is(cNames)] DISPID * rgDispId
);
[local] // 本地版函数
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
);
[call_as(Invoke)] // 远程版函数
HRESULT RemoteInvoke(
[in] DISPID dispIdMember,
[in] REFIID riid,
[in] LCID lcid,
[in] DWORD dwFlags,
[in] DISPPARAMS * pDispParams,
[out] VARIANT * pVarResult,
[out] EXCEPINFO * pExcepInfo,
[out] UINT * pArgErr,
[in] UINT cVarRef,
[in, size_is(cVarRef)] UINT * rgVarRefIdx,
[in, out, size_is(cVarRef)] VARIANTARG * rgVarRef );
}
以上IDispatch 接口函数的讲解,我们留到后回中进行介绍。如何在组件程序中实现这些函数那?还好,还好,就象IUnknown 一样,MFC 和ATL 都帮我们已经完成了。本回我们着重介绍组件的编写,下回则介绍组件的调用方法。
三、用MFC 实现自动化组件
我写的这整个系列文章---《COM 组件设计与应用》,多是用ATL 写组件程序,但由于自动化非常有用,在后续的文章中,还要给大家介绍组件的“事件”功能,还要介绍如何在MFC 的程序中象WORD 一样支持“宏”的功能。这些都要用到MFC,所以就给读者唠一唠啦:-)
3-1:建立一个工作区(Workspace)
3-2:建立一个MFC DLL 工程(Project),工程名称为“Simple5”
3-3:一定要选择automation,切记!切记!
3-4:建立新类
3-5:在新建类中支持automation
Class information - Name你随便写个类名子啦
Class information - Base class一定要从CComTarget 派生呀,只有它才提供了IDispatch 的支持
Automation - None表示不支持自动化,你要选择了它,那就白干啦
Automation - Automation支持自动化,但不能被直接实例化。后面在讲解多个IDispatch 的时候就用到它了,现在先不要着急。
Automation - Createable by type ID一定要选择这个项目,这样我们在后面的调用中,VB就能够CreateObject(),VC 就能够CreateDispatch()对组件对象实例化了。注意一点,这个ID 其实就是组件的ProgID 啦。
3-6:启动ClassWizard,选择Automation 卡片,准备建立函数