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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

COM原理及代码实例.docx

1、COM原理及代码实例1. COM原理1.1. COM基本概念介绍1.什么是COM(Component Object Modal)COM(Component Object Modal)是Microsoft组件对象模型的简称。是一个说明如何建立可动态交替更新组件的规范。简单地说,COM是一种跨应用和语言共享二进制代码的方法。与C+不同,它提倡源代码重用。ATL便是一个很好的例证。源码级重用虽然好,但只能用于C+。它还带来了名字冲突的可能性,更不用说不断拷贝重用代码而导致工程膨胀和臃肿。2 .COM组件COM组件是由以Win32动态链接库(DLL)或可执行文件(EXE)发布的代码所组成。3为什么要学

2、习COM传统的软件开发模式:传统的软件应用程序发布以后,使用者想得到更完善的软件或者去掉其中的某些内容,只有等软件提供商发布新的版本以后,使用者的这一梦想才能得以实现。使用COM组件以后:软件开发人员可以在软件版本发布以后修改或者去掉软件某个不需要部分。也及应用程序在更高的层次上定制,使得软件更具灵活性、动态性。是未来应用软件开发的趋势。4 COM的前身是OLE(Object Linking and Embedding)对象链接与嵌入。5组件:如积木一样,具有“块”的概念,可以动态的将他们插入或卸出应用程序。这就需要两个条件:第一,组件必须动态链接(不因自己的位置改变而改变自身形式);第二,组

3、件必须隐藏内部实现细节(独立与具体编程语言,二进制形式发布)。每个组件相当于一个黑盒子,对外提供的只是接口(函数)。如果接口没有发生任何变化时,对组件的修改几乎不会影响应用程序的其它部分。提供服务的组件称为服务器组件,使用服务的组件称为客户组件。1.2. 完整的COM组件的接口实现实例#include #include using namespace std;void trace(const char * pMsg) coutpMsgendl;/ 抽象接口1interface InteX virtual void _stdcall Fx1() = 0; virtual void _stdcal

4、l Fx2() = 0;/ 抽象接口2interface InteY virtual void _stdcall Fy1() = 0; virtual void _stdcall Fy2() = 0;/ 抽象接口实现class CompA:public InteX,public InteYpublic: /实现接口InteX virtual void _stdcall Fx1() coutCompA:Fx1endl; virtual void _stdcall Fx2() coutCompA:Fx2endl; /实现接口InteY virtual void _stdcall Fy1() cou

5、tCompA:Fy1endl; virtual void _stdcall Fy2() coutCompA:Fy2Fx1(); pintex-Fx2(); InteY *pintey = pcompa; trace(客户:使用组件InteY接口。); pintey-Fy1(); pintey-Fy2(); trace(客户:删除组件。); delete pcompa; return 0;增加查询组件接口QueryInterface(),应用计数增加AddRef(),应用技术减少Release()的完整例子。#include #include using namespace std;void t

6、race(const char * pMsg) coutpMsgendl;/ GUID 全局唯一标示符extern const IID IID_InteX;extern const IID IID_InteY;extern const IID IID_InteZ;/ 接口实现interface InteX:IUnknown virtual void _stdcall Fx() = 0;interface InteY:IUnknown virtual void _stdcall Fy() = 0;interface InteZ:IUnknown virtual void _stdcall Fz(

7、) = 0;/ 抽象接口实现class CompA:public InteX,public InteY /IUnknown实现 virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID&iid,void *ppv); virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE Release(); /实现接口InteX virtual void _stdcall Fx() coutCompA:Fxendl; /实现接口InteY virtual v

8、oid _stdcall Fy() coutCompA:Fyendl; ULONG m_cRef;public: CompA():m_cRef(0) CompA()trace(析构CompA自身);HRESULT STDMETHODCALLTYPE CompA:QueryInterface(const IID&iid,void *ppv) if(iid = IID_IUnknown) trace(CompA():QueryInterface:返回指向IUnknown本身的指针.); *ppv = static_cast(this); else if(iid = IID_InteX) trace

9、(CompA():QueryInterface:返回指向InteX的指针.); *ppv = static_cast(this); else if(iid = IID_InteY) trace(CompA():QueryInterface:返回指向InteY的指针.); *ppv = static_cast(this); else trace(CompA():QueryInterface:接口不支持.); *ppv = NULL; return E_NOINTERFACE; reinterpret_cast(*ppv)-AddRef(); return S_OK;ULONG STDMETHOD

10、CALLTYPE CompA:AddRef() coutCompA():AddRef = m_cRef + +:增加接口引用计数.endl; return m_cRef;ULONG STDMETHODCALLTYPE CompA:Release() coutCompA():Release = m_cRef - -减少接口引用计数.endl; if(0 = m_cRef) delete this; return 0; return m_cRef;/ 创建实例函数IUnknown *CreateInstance() IUnknown *pinte = static_cast(new CompA);

11、 pinte-AddRef(); return pinte;/ IIDsconst IID IID_InteX =0x32bb832c,0xb41a,0x11cf,0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82;const IID IID_InteY =0x32bb832d,0xb41a,0x11cf,0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82;const IID IID_InteZ =0x32bb832e,0xb41a,0x11cf,0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82;/ 客户程序int

12、 main() HRESULT hr; trace(客户:获得IUnknown的一个指针); IUnknown *piunknown = CreateInstance(); trace(客户:获得InteX的接口); InteX *pintex = NULL; hr = piunknown-QueryInterface(IID_InteX,(void *)&pintex); if(SUCCEEDED(hr) trace(客户成功获得组件InteX); pintex-Fx(); pintex-Release(); trace(客户:获得InteY的接口); InteY *pintey = NUL

13、L; hr = piunknown-QueryInterface(IID_InteY,(void *)&pintey); if(SUCCEEDED(hr) trace(客户成功获得组件InteY); pintey-Fy(); pintey-Release(); trace(客户尝试获得不支持的InteZ组件接口); InteZ *pintez= NULL; hr = piunknown-QueryInterface(IID_InteZ,(void *)&pintez); if(SUCCEEDED(hr) trace(客户成功获得组件InteZ); pintez-Fz(); pintez-Rel

14、ease(); else trace(客户不能成功获得组件InteZ); trace(客户释放IUnknown借口); piunknown-Release(); return 0;1.3. ATL活动模板库(The Active Template Library)在ATL 产 生 以 前, 开 发COM 组 件 的 方 法 主 要 有 两 种: 一 是 使 用COM SDK 直 接 开 发COM 组 件, 另 一 种 方 式 是 通 过MFC 提 供 的COM 支 持 来 实 现。使 用ATL 开 发COM 应 用 是 一 件 非 常 简 单 的 事 情, 但 是 在ATL 简 单 易 用 的

15、 界 面 后 面 却 包 含 着 复 杂 的 技 术。这些技术包含以下一些方面: COM 技 术 C+ 模 板 类 技 术(Template) C+ 多 继 承 技 术(Multi-Inheritance) 其中,COM技术本文开头有所描述。C+ 模 板 类 技 术(Template)、C+ 多 继 承 技 术(Multi-Inheritance)在C+理论课中已有详尽描述。这里最主要的是介绍使用ATL怎么生成一个自己的COM组件以及怎么使用该组件。1建立一个ATL工程:图 11- 12选择创建的COM类型:图 11- 2该步骤中的一些选项说明:动 态 连 接 库(Dynamic Linkin

16、g Library) 最 终 产 生 一 个 动 态 连 接 库(DLL) 形 式 的COM 服 务 程 序;应 用 程 序(Executable application) 最 终 产 生 一 个 可 执 行 程 序 类 型(EXE) 的COM 服 务 程 序;NT 服 务(NT Service) 产 生 一 个 以NT 服 务 方 式 运 行 的COM 服 务 程 序。允 许 嵌 入Proxy/Stub 代 码。 由Microsoft 提 供 的MIDL 编 译IDL 文 件 以 后, 将 产 生 用 于 对 象 调 度(Marshaling) 的Proxy/Stub 的 代 码。 在 传

17、统 方 式 下, 这 部 分 代 码 与COM 服 务 程 序 的 代 码 是 分 离 的, 但 是 由 于 新 的COM 标 准 支 持 多 线 程 环 境 下 的COM 对 象 服 务, 因 此 在 动 态 连 接 库 的COM 服 务 程 序 中 也 要 有Proxy/Stub 的 支 持。 为 了 支 持 在 网 络 上 的 传 输,ATL 允 许 用 户 选 择 将Proxy/Stub 的 代 码 包 括 在 生 成 的DLL 代 码 中。 这 个 选 项 在EXE 和NT 服 务 类 型 的COM 应 用 条 件 下 不 可 选。 允 许 支 持MFC。 由 于ATL 对 除COM

18、 以 外 的 基 本 的Windows 编 程 方 面 的 支 持 极 为 有 限, 同 时 许 多 程 序 员 对MFC 又 非 常 熟 悉, 因 此 在ATL 的 工 程 设 置 中 允 许 在ATL 工 程 内 部 支 持 使 用MFC, 即 可 以 使 用MFC 定 义 的 类。 这 一 特 点 给 开 发 人 员 提 供 了 许 多 方 便, 特 别 对 于 习 惯 使 用MFC 的 人 来 说, 能 够 使 用MFC 提 供 的 各 种 功 能 强 大 的 类 的 支 持, 而 不 必 直 接 使 用Windows SDK。 从 另 一 个 方 面 来 看, 在ATL 工 程 中

19、使 用MFC 同 时 就 丧 失 了ATL 代 码 轻 量 级 的 特 点。 支 持MTS。MTS 是Microsoft Transaction Server 的 缩 写, 它 是Microsoft 在COM 技 术 方 面 的 一 个 新 的 分 支, 这 里 不 做 详 细 说 明。- 完 成 上 面 的 设 置 以 后, 可 以 选 择Finish 完 成 工 程 的 设 置,ATL 将 创 建 相 应 的 工 程。 3向 工 程 中 加 入 一 个 新 的ATL 类:首 先 通 过 集 成 环 境 的Insert 菜 单 下 的New ATL Object. 命 令 进 入ATL Ob

20、ject Wizard 对 话 框。如下图所示:图 11- 3对 话 框 的 左 边 部 分 说 明 了 待 创 建 对 象 的 基 本 类 型, 这 里 主 要 有 以 下 几 种 类 型: 对 象(Object) 基 本 的COM 对 象 类 型; 控 制(Control) ActiveX Control 类 型 的ATL 对 象; 其 他(Miscellaneous) 辅 助 功 能, 如 对 话 框 的 生 成 等; 数 据 访 问(Data Access) 数 据 访 问, 支 持MTS 等。对于一般的COM 服 务 程 序,选择对 象(Object),点击下一步继续:3输入引入的类

21、名:图 11- 44切换到Attributes(属性)标签页:图 11- 5对 象 的 属 性 设 置 是ATL 对 象 创 建 过 程 中 最 复 杂 的 部 分, 包 括 以 下 几 个 主 要 部 分: 对 象 的 线 程 模 型(Thread Model) :对 象 的 线 程 模 型 是COM 对 象 在 多 线 程 环 境 下 被 访 问 时 对 访 问 方 式 的 控 制, 缺 省 情 况 下 在ATL 中 采 用 的 是 套 间 模 型Apartment, 由 系 统 通 过 消 息 队 列 方 式 提 供 并 发 控 制。 对 象 的 接 口 模 型(Interface):C

22、OM 对 象 的 接 口 可 以 是 双 接 口(Dual Interface)。 双 接 口 不 同 于 普 通 接 口(Custom Interface) 之 处 在 于 双 接 口 是 从Automation 基 本 接 口IDispatch 继 承 的, 而 普 通 接 口 是 从IUnknown 接 口 直 接 继 承 来 的。 缺 省 的 接 口 模 型 是 双 接 口。 对 象 的 聚 合 模 型(Aggregate) :COM 规 范 不 允 许 对 象 的 实 现 继 承, 但 是 可 以 通 过 聚 合 方 式 重 用 其 他 的COM 对 象。ATL 对 象 属 性 设

23、置 中 的 聚 合 模 型 可 以 指 定 待 创 建 的COM 对 象 是 否 支 持 聚 合 模 型。 缺 省 的 选 项 是 支 持 对 象 的 聚 合。 对 象 对 错 误 处 理 的 支 持(Support ISupportErrorInfo) :选 取 这 个 选 项 可 以 在 对 象 的 运 行 过 程 中 支 持 错 误 处 理。 缺 省 情 况 下 这 个 选 项 不 被 选 中。 对 象 对 连 接 点 的 支 持(Support Connection Points) :连 接 点 是COM 对 象 的 事 件 机 制。 选 中 这 个 选 项 可 以 使 待 创 建 的

24、COM 对 象 具 有 发 出 事 件 的 能 力。 缺 省 情 况 下 该 选 项 不 被 选 中。 对 象 对 自 由 线 程 调 度 的 支 持(Free Thread Marshaller, 简 称FTM) :对 象 的 自 由 线 程 调 度 是 对 象 在 处 于 自 由 线 程 模 型 状 态 下, 为 了 简 化 对 象 的 访 问 过 程 而 采 用 的 一 种 优 化 策 略。 缺 省 情 况 下 该 选 项 不 被 选 中。5给引入的类添加方法:图 11- 6图 11- 7给添加的方法加入如下代码:图 11- 8 CComBSTR strSource = InData;

25、CComBSTR tempSource = InData; bool bNeedToUpper = true; int j=(int)strSource.Length()-1; / 实现字符串到大写字母的转换并进行逆序转换 for(int i=0;i=a & strSourcei=z& bNeedToUpper) strSourcei=strSourcei-32; bNeedToUpper = true; if(strSourcei = ) bNeedToUpper = false; tempSourcej=strSourcei; j=j-1; *OutData = tempSource; r

26、eturn *result;6添加工程到当前工程中:图 11- 97添加类到当前工程中:图 11- 108设计如下对话框界面:图 11- 11关联如下变量:图 11- 12对“字符串转换”按钮添加如下响应代码:void CMyComClientDlg:OnTransfer() ICMyStr m_MyString; / 创建COM对象 if(!m_MyString.CreateDispatch(AtlComSample.cmystr.1) MessageBox(Create UserInfo error); / 得到源字符串放到m_SourceString中 UpdateData(true); / 调用COM接口 BSTR bstrDestStr = SysAllocString(L ); m_MyString.StringTransfer(m_SourceString,&bstrDestStr); / 得到转换后结果字符串 m_DestString = bstrDestStr; / 将结果字符串显示到编辑框中 UpdateData(false);运行结果如下:图 11- 13练习:使用同样ATL的方法,建立自己的COM组件并在客户程序中进行使用。

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

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