ImageVerifierCode 换一换
格式:DOCX , 页数:14 ,大小:459.59KB ,
资源ID:2939031      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/2939031.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(COM 组件设计与应用09IDispatch 接口VC6.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

COM 组件设计与应用09IDispatch 接口VC6.docx

1、COM 组件设计与应用09IDispatch 接口VC6COM组件设计与应用(九)IDispatch 接口 for vc6.0作者:杨老师下载源代码 一、前言 终于写到了第九回,我也一直期盼着写这回的内容耶,为啥呢?因为自动化(automation)是非常常用、非常有用、非常精彩的一个 COM 功能。由于 WORD、EXCEL 等 OFFICE 软件提供了“宏”的功能,就连我们使用的VC开发环境也提供了“宏”功能,更由于 HTML、ASP、JSP 等都要依靠脚本(Script)的支持,更体现出了自动化接口的重要性。 如果你使用 vc6.0 的开发环境,请继续阅读。 如果你使用 2003,请阅读

2、下一回。 二、IDispatch接口 如果是编译型语言,那么我们可以让编译器在编译的时候装载类型库,也就是装载接口的描述。在第七回文章当中,我们分别使用了 #include 方法和 #import 方法来实现的。装载了类型库后,编译器就知道应该如何编译接口函数的调用了-这叫“前绑定”。但是,如果想在脚本语言中使用组件,问题就大了,因为脚本语言是解释执行的,它执行的时候不会知道具体的函数地址,怎么办?自动化接口就为此诞生了-“后绑定”。 自动化组件,其实就是实现了 IDispatch 接口的组件。IDispatch 接口有4个函数,解释语言的执行器就通过这仅有的4个函数来执行组件所提供的功能。I

3、Dispatch 接口用 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); / 有关类型库的这两个函数

4、,咱们以后再说 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( / 根据函数序号,解释

5、执行函数功能 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 dwF

6、lags, 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 都帮我

7、们已经完成了。本回我们着重介绍组件的编写,下回则介绍组件的调用方法。三、用 MFC 实现自动化组件 我写的这整个系列文章-COM 组件设计与应用,多是用 ATL 写组件程序,但由于自动化非常有用,在后续的文章中,还要给大家介绍组件的“事件”功能,还要介绍如何在 MFC 的程序中象 WORD 一样支持“宏”的功能。这些都要用到 MFC,所以就给读者唠一唠啦:-) 3-1:建立一个工作区(Workspace) 3-2:建立一个 MFC DLL 工程(Project),工程名称为“Simple5” 3-3:一定要选择 automation,切记!切记! 3-4:建立新类 3-5:在新建类中支持aut

8、omationClass information - Name 你随便写个类名子啦Class information - Base class 一定要从 CComTarget 派生呀,只有它才提供了 IDispatch 的支持Automation - None 表示不支持自动化,你要选择了它,那就白干啦Automation - Automation 支持自动化,但不能被直接实例化。后面在讲解多个 IDispatch 的时候就用到它了,现在先不要着急。Automation - Createable by type ID 一定要选择这个项目,这样我们在后面的调用中,VB就能够CreateObjec

9、t(),VC就能够CreateDispatch()对组件对象实例化了。注意一点,这个 ID 其实就是组件的 ProgID 啦。 3-6:启动 ClassWizard,选择 Automation 卡片,准备建立函数 3-7:添加函数。我们要写一个整数加法函数Add()。 3-8:再增加一个转换字符串大小写的函数 Upper()。函数返回值是 BSTR,这个没有什么疑问,但参数类型怎么居然是 LPCTSTR?在 COM 中,字符串不是应该使用 BSTR 吗?是的,是应该使用 BSTR,但由于我们是用 MFC 写自动化组件,它帮我们进行 BSTR 和 LPCTSTR 之间的转换了。 3-9:好了,下

10、面开始输入程序代码:long CDispSimple:Add(long n1, long n2) return n1 + n2;BSTR CDispSimple:Upper(LPCTSTR str) CString strResult(str); strResult.MakeUpper(); return strResult.AllocSysString(); 3-10:编译注册 如果上面的操作由于疏忽而发生了错误,那么你可以手工进行改正。其一、步骤的对话窗中有“Delete”操作;其二、你可以打开 ODL 文件(注2)进行修改,修改时要特别小心函数的声明中,有一个id(n) 的函数序号,可不

11、要乱了;其三、同步修改 H/CPP 中的函数声明和函数体;其四、在CPP文件中,根据情况也要修改 BEGIN_DISPATCH_MAP/END_DISPATCH_MAP()函数影射宏。 正确编译后,MFC不象ATL那样会自动注册。你需要手工执行 regsvr32.exe 进行注册,或者执行菜单“ToolsRegister control”四、用 ATL 实现双接口组件(操作方法和步骤,请参考COM 组件设计与应用(五) 4-1:建立一个 ATL 工程(Project),工程名称为“Simple6” 4-2:按默认进行。选择 DLL 类型、不合并代理和存根代码、不支持MFC、不支持MTS 4-3

12、:New Atl Object. 选择Simple Object 4-4:输入名称和属性,属性按默认进行,也就是 dual(双接口)方式(注3) 4-5:增加函数。在 ClassView 卡片中,选择接口、鼠标右键菜单、Add Method.Add(in VARIANT v1, in VARIANT v2, out, retval VARIANT * pVal);Upper(in BSTR str, out,retval BSTR * pVal); 关于Add()函数,你依然可以使用 Add(in long n1, in long n2, out,retval long * pVal) 方式。

13、但这次我们没有使用 long ,而是使用了 VARIANT 做参数和返回值。这里我先卖个关子,往下看,就知道使用 VARIANT 的精彩之处了。 4-6:完成代码STDMETHODIMP CDispSimple:Add(VARIANT v1, VARIANT v2, VARIANT *pVal) :VariantInit( pVal ); / 永远初始化返回值是个好习惯 CComVariant v_1( v1 ); CComVariant v_2( v2 ); if(v1.vt & VT_I4) & (v2.vt & VT_I4) ) / 如果都是整数类型 / 这里比较没有使用 = ,而使用了

14、运算符 & ,你知道这是为什么吗? v_1.ChangeType( VT_I4 ); / 转换为整数 v_2.ChangeType( VT_I4 ); / 转换为整数 pVal-vt = VT_I4; pVal-lVal = v_1.lVal + v_2.lVal; / 加法 else v_1.ChangeType( VT_BSTR ); / 转换为字符串 v_2.ChangeType( VT_BSTR ); / 转换为字符串 CComBSTR bstr( v_1.bstrVal ); bstr.AppendBSTR( v_2.bstrVal ); / 字符串连接 pVal-vt = VT_BSTR; pVal-bstrVal = bstr.Detach(); return S_OK;STDMETHODIMP CDispSimple:Upper(BSTR str, BSTR *pVal) *pVal = NULL; / 永远初始化返回值是个好习惯 CComBSTR s(str); s.ToUpper(); / 转换为大写 *pVal = s.Copy(); return S_OK; 刚才卖的关子,现在开始揭密了.加法函数Add()不使用long类型,而使用VARIANT的

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1