利用ATL编写COM组件课件_第1页
利用ATL编写COM组件课件_第2页
利用ATL编写COM组件课件_第3页
利用ATL编写COM组件课件_第4页
利用ATL编写COM组件课件_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1利用ATL编写COM组件 1 COM组件与ATL 2 利用ATL创建COM组件 3 在VC和VB中使用COM组件

1利用ATL编写COM组件121 COM组件与ATL目录1.1 COM概述

1.2 COM与软件复用

1.3 与COM有关的概念1.4 ATL简介 21 COM组件与ATL目录231.1 COM概述

COM是组件对象模型,在Windows操作系统下COM组件很多,组件是C++面向对象思想在软件业的应用,它是一种创建二进制软件组件的体系,是一种与平台无关、语言无关、分布式的面向对象的体系。它不是一种面向对象的语言,而是一种标准,COM描述了如何创建对象的一个模型以及在COM对象间进行通讯所需要的内容。因此,从功能上讲COM更像一个协议,一个二进制级别上组件重用的协议。

31.1 COM概述341.2 COM与软件复用

在软件开发过程中,人们提出软件的制造能否像硬件的生产一样,实现规约化的组装。答案是肯定的,利用Microsoft的COM技术编写的组件就可以达到这个目的。软件复用避免了软件开发过程中的重复劳动的解决方案,其出发点是应用系统的开发不再采用一切“从零开始”的模式,每个COM组件有自己的属性和操作,是一个相对独立运行的实体。从软件复用种类的定义看,COM技术实质上是一种模块复用的情况。采用组件开发软件就像搭积木一样容易,组件单独开发并作为软件模块使用,它具有明确的接口,客户通过这些接口调用组件所能提供的服务,将多种组件拼装起来就能构成大型的组件以至建立整个系统。41.2 COM与软件复用 451.3 与COM有关的概念

1.对象

对象代表现实中的某个实体,是类的实例。在COM中,对象也是类的实例,但是COM对象与面向对象模型的类对象有区别。COM是与软件开发语言无关、平台无关,而面向对象模型中的类对象在不同的语言下是有区别的。2.接口

动态链接库DLL是通过导出一系列函数来让客户程序使用的,只有知道了DLL的导出函数列表才能使用它。COM组件的载体也是一个DLL,COM组件是通过接口与客户进行通讯的,但它是一个抽象类(含有纯虚函数的类)。下面是一个接口的简单定义:51.3 与COM有关的概念

1.对象56与COM有关的概念(2)InterfaceIdeposit:Iunknown{virtualHRESULTGetMoney(int*nMoney)=0;};Iunknown接口很重要,其定义如下:StructIunknown{virtualHRESULTQueryInterface(REFIDiid,void**ppvobj)=0;//查询是否支持接口virtualULONGAddRef()=0;//引用计数加1virtualULONGRelease()=0;//引用计数减1}6与COM有关的概念(2)InterfaceIdeposi67与COM有关的概念(3)3.类与类工厂

类是COM接口的实现,所有的COM对象都是COM类的实例。一个COM类也是用一个GUID来标识,在类中称它为“类标识符”(CLSID:ClassIdentifier)。每个类也有一个字符串名称,叫做“编程标识符”.4.组件

组件就是实现了指定接口并被封装在DLL或可执行文件中的软件模块,它能够实现由接口指定的功能,主要用来创建COM对象的。一个组件包括该COM类和实现该类工厂的程序代码,有时也称它为“服务器”。一个组件可以包括多个COM对象,每个COM对象可以实现多个接口。

7与COM有关的概念(3)3.类与类工厂78与COM有关的概念(4)

5.注册与注册表组件编好之后,编译出来的DLL文件还必须在注册表中注册后才能被其它用户使用。因为只有这样,用户在创建COM对象时,系统才能在注册表中获取相应对象的位置,才能创建对象,对于DLL型的组件,需要调用RegSvr32.exe来完成,对于EXE型的组件,只要服务器运行过一次,该组件就会自动进行注册。返回

8与COM有关的概念(4)5.注册与注册表891.4 ATL简介

ATL(ActiveXTemplateLibrary,活动模板库)是一套C++的模板库,利用它可以很方便地建立小型的、基于COM的组件,对COM组件的开发提供了最大限度的代码自动生成以及可视化的支持。模板是ATL的核心技术。1.什么是模板

模板(Template)是基于类型参数产生类和函数的一种机制。模板在不降低类型安全的基础上,可以显著地减少代码量,增加代码的灵活性。模板包括函数模板和类模板,本节只讲类模板。2.类模板类是对问题空间的抽象,而类模板则是对类的抽象,即更高层次上的抽象。使用类模板,可以指定操作于某个数据类型的一族类。在程序中,可以首先定义一个类模板,然后通过使用不同的实参生成不同模板类的对象。91.4 ATL简介 ATL(Act910ATL简介(续)类模板的定义方法为:template<class类型参数>class类名{

……};类模板的具体内容与普通类没有本质的区别,只是其员中要用到类模板的类型参数。【例15-1】一个类模板实例。程序的主文件名为MyTemplate.cpp。10ATL简介(续)类模板的定义方法为:10112 利用ATL创建COM组件

本节以一个字符串处理的组件为例来阐述如何利用ATL来制作COM组件。编程的思路为:(1)在VC下创建一个ATL工程,并对工程的可选项进行设置;(2)向工程中添加ATL对象,并对该对象进行一些初始配置工作;(3)根据COM组件的功能,向新的ATL对象中加入新的接口定义,包括方法和事件的定义,并实现相应的接口成员函数;(4)编译链接该工程,注册COM组件;(5)编写组件测试程序,验证组件的功能。112 利用ATL创建COM组件 本节以一个字符串处理的组1112利用ATL创建COM组件目录2.1 创建ATL应用程序框架2.2 在工程中添加ATL对象2.3 在COM组件中添加方法2.4 ATL中的字符串数据类型2.5 编译IDL并注册COM组件

12利用ATL创建COM组件目录12132.1 创建ATL应用程序框架

1.在VC开发环境下,选择File|New菜单,将弹出的New对话框切换到Projects选项卡后,选择ATLCOMAppWizard项,在Projectname编辑框中输入MyCom工程名称,并设置好工程所在的文件夹。如图右图所示。

132.1 创建ATL应用程序框架

1.在VC开发环境下,1314创建ATL应用程序框架(续)2.单击“OK”按钮,进入图2所示的选择ATL组件类型对话框。

2选择COM组件类型对话框14创建ATL应用程序框架(续)2.单击“OK”按钮,进入图1415创建ATL应用程序框架(续) ATL组件类型一共有三种:第一种是DLL类型;第二种是EXE类型;第三种是Service类型,它也是一个典型的进程外组件。Service是Windows2000的一种应用服务,当操作系统启动的时候,该Server自动运行。由于进程外组件的执行效率较低,我们选择DLL类型的。选择完后,按“Finish”按钮,结束ATL创建组件的向导生成步骤,最终在磁盘上生成了组件的框架代码。表1列出了该工程中的主要文件的信息。15创建ATL应用程序框架(续) ATL组件类型一共有三种1516表1AppWizard生成的MyCom工程中的文件

return文件名文件说明MyCom.cpp工程的主文件,其中有组件的接口函数和注册函数MyCom.def工程的DLL模块定义文件,它与前面讲的DLL库中的Def文件的含义相同MyCom.idl工程的接口定义语言文件,COM是靠接口定义语言来定义组件间、组件与客户间的接口定义,它是COM组件的入口点MyCom.rc工程的资源文件,与别的MFC程序的资源文件类似Resouce.h工程的资源文件的头文件,与别的MFC程序的resource.h类似Stdafx.h工程的标准头文件,与别的MFC程序的stdafx.h类似Stdafx.cpp工程的标准实现文件,与别的MFC程序的stdafx.cpp类似Str.rgs工程的注册脚本文件16表1AppWizard生成的MyCom工程中的文件16172.2 在工程中添加ATL对象1.选择Insert|NewATLObject,弹出如图3所示的对话框,从Objects列表框中选择SimpleObject项后,单击“Next”按钮继续。图3插入一个基于ATL的COM类

前面已经创建了一个MyCom工程,接下来,使用VC的ATLObjectWizard工具,可以方便地往工程中添加ATL对象。172.2 在工程中添加ATL对象1.选择Insert|Ne17182.2 在工程中添加ATL对象(续)2.系统弹出一个ATLObjectWizardProperties对话框。在ShortName中输入Str,在COClass编辑框中输入StrCom,如图4所示。注意在Name选项卡中,可以键入类与文件名。默认情况在,ShortName名字是其它名字的词根。可以不接收默认的名字而键入自己的名称。图4窗口中的Class是对象所实现的类的名称,CoClass为包含对象支持的一些接口的名称,Interface为对象创建的接口名字,Type为有关注册对象的描述性字符串,ProgID为容器所使用的名字以代替对象的CLSID。

图4设置COM类的属性182.2 在工程中添加ATL对象(续)2.系统弹出一个AT18192.2 在工程中添加ATL对象(续)3.切换到图5所示的Attribute选项卡,设置StrCom对象的属性,如组件的线程模式、接口类以及是否支持聚集等属性。我们使用系统的默认属性。单击“OK”按钮,就生成了一个StrCom组件对象。图5设置组件对象的属性图192.2 在工程中添加ATL对象(续)3.切换到图5所示的19202.3 在COM组件中添加方法

1.方法的添加进入Workspace窗口的ClassView面板,在IStr接口上右击鼠标,选择AddMethod菜单项后,弹出如图6所示的增加方法接口对话框,在MethodName编辑框中输入FirstToUpper,在Parameters编辑框中输入“[in]BSTRInData,[out]BSTR*OutData,[out,retval]long*result”后,按OK按钮结束方法的添加。

图6添加FirstToUpper方法202.3 在COM组件中添加方法

1.方法的添加20212.3 在COM组件中添加方法(续)第一个参数为InData,它是具有“in”属性的字符串变量,它是输入参数,代表欲转换的字符串;第二个参数为outData,它是具有“out”属性的字符串变量,它是输出参数,代表转换完后的的字符串;第三个参数为result,它是具有“out”和“retval”属性,意思是说该参数是作为返回值来用的输出参数,其类型是指向长整型的指针变量。此时用户在ClassView中就可以看到Istr接口中的FirstToUpper的方法。如图7所示。

图7Istr接口的方法FirstToUpper212.3 在COM组件中添加方法(续)21222.3 在COM组件中添加方法(续)2.方法的实现在Workspace窗口的ClassView面板中,将类CStr展开,接着,再将该类中的Istr接口展开,双击方法FirstToUpper(char*source,char*destion),光标定位到该类的实现文件处,在其中添加代码。STDMETHODIMPCStr::FirstToUpper(BSTRInData,BSTR*OutData,long*result){ CComBSTRstrSource=InData;boolbMayUpper=true;//是否可以大写的标志 for(inti=0;i<strSource.Length();i++) { if(strSource[i]>='a'&&strSource[i]<='z'&&bMayUpper) { strSource[i]=strSource[i]-32; bMayUpper=false; } if(strSource[i]=='')bMayUpper=true; } return*result;}222.3 在COM组件中添加方法(续)2.方法的实现22232.4 ATL中的字符串数据类型

由于COM组件是跨平台与开发语言的,利用ATL开发出来的组件在VB等别的开发工具下也可以使用。ATL中使用的是C++语言,别的开发工具所使用的语言和C++的数据类型是有区别的,那么在不同的语言之间如何进行数据的交换呢?这要靠组件接口中提供的多语言通用类型的数据类型,规定通用类型也是COM组件的一个组成部分。232.4 ATL中的字符串数据类型 23242.4 ATL中的字符串数据类型(续)1.BSTR

用COM技术来设计组件以及构件系统时,字符串常用BSTR来表示。BSTR是BASICString的简称,常用于BASIC的编程中。该类型是包含长度前缀的,以0结束的字符串,长度前缀表示该字符串所包含的字节数。COM提供了一些API函数来管理BSTR。如SysAllocString()(创建并初始化一个字符串),SysAllocStringLen()(创建一个指定长度的字符串),SysFreeString()(释放一个字符串),SysReAllocString()(改变字符串的长度),SysStringLen()(返回字符串的长度)等。在VC客户端一般调用SysAllocString()创建字符串,以[In]参数方式传递给组件中的方法,调用完成后用SysFreeString()来释放字符串的缓冲区。

BSTRstr=SysAllocString(”areyouready?”);HRESULThr=p->FirstToUpper(str);SysFreeString(str);242.4 ATL中的字符串数据类型(续)1.BSTR24252.4 ATL中的字符串数据类型(续)2.CComBSTR CComBSTR是ATL封装的一个来使用BSTR数据类型的类,如果把BSTR看作各种语言都可以使用的共同数据类型的话,那么CComBSTR则就是在C++下操纵COM中的一个数据类型。

CComBSTR类中有一些重要的函数,如Append()(增加一个字符串),AppendBSTR()(增加一个BSTR字符串),Copy()(返回成员变量m_str的值),Empty()(释放成员变量m_str的值),Length()(返回BSTR的长度)等。252.4 ATL中的字符串数据类型(续)2.CComBST25262.5 编译IDL并注册COM组件1.IDL简介

COM接口通常用“接口定义语言”IDL来定义,IDL是一种类似于C++的语言,前一节设计了一个MyCom组件,下面是其接口MyCom.idl的内容:2.编译IDL

上述Mycom.idl文件我们并未编写,这完全归功于ATL工具,是它帮助我们自动完成了IDL接口文件。前面在给组件中添加方法的过程中,向导自动完成了IDL文件。 切换到WorkSpace的FileView面板中,在MyCom.idl文件上右键单击鼠标,选择CompileMyCom.idl菜单项,于是在磁盘上生成了接口定义文件对应的二进制文件Mycom.tlb。该文件中含有接口中所定义的方法的记录,定义了组件的虚函数指针表。.tlb可以看作是二进制的接口定义语言。262.5 编译IDL并注册COM组件1.IDL简介26272.5 编译IDL并注册COM组件(续)//MyCom.idl:IDLsourceforMyCom.dll//ThisfilewillbeprocessedbytheMIDLtoolto//producethetypelibrary(MyCom.tlb)andmarshallingcode.import"oaidl.idl";import"ocidl.idl"; [object, uuid(F1CDC043-28E4-44D0-A4A6-BB8654CD7C02), dual, helpstring("IStrInterface"), pointer_default(unique) ] interfaceIStr:IDispatch {[id(1),helpstring("methodFirstToUpper")]HRESULTFirstToUpper([in]BSTRInData,[out]BSTR*OutData,[out,retval]long*result);};[uuid(D30786A1-E559-43D4-A62B-9A9FA0C559B1), version(1.0), helpstring("MyCom1.0TypeLibrary")]272.5 编译IDL并注册COM组件(续)//MyCom27282.5 编译IDL并注册COM组件(续)libraryMYCOMLib{ importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(9618DF64-B84E-43BF-8A9C-3634E6A9F88F), helpstring("StrClass") ] coclassStrCom { [default]interfaceIStr; };};282.5 编译IDL并注册COM组件(续)library28292.5编译IDL并注册COM组件(续)3.注册MyCom.dll要想让用户能够“透明”地使用创建的组件,首先必须将该组件注册。单击Build|BuildMycom.dll菜单项,VC编译器将生成该组件文件MyCom.dll,并且自动完成注册。其中注册的代码在MyCom.cpp中。还有一种手工注册组件的方法是利用RegSvr32.exe来进行,请参阅1.3中的5小节注册与注册表的说明。292.5编译IDL并注册COM组件(续)3.注册MyCo29303 在VC和VB中使用COM组件内容3.1调用COM组件的过程3.2在VC中创建COM组件客户3.3在VB中使用COM组件

303 在VC和VB中使用COM组件内容30313.1 调用COM组件的过程

Windows系统下有大量的组件可供使用,前面我们所创建的MyCom组件也注册好了,因此也可以使用,使用COM组件过程是一个典型的客户/服务器(Client/Server)方式。COM组件含有被调用的接口,它是提供服务的,因此是服务方。

Windows系统下的组件如同一大堆积木,不同的人建房子所使用的积木也不一样,因此不同的人使用的COM组件也不一样,但它们有共同的使用过程:首先客户程序要获取包含组件的服务器(如MyCom.dll就是提供了字符串转化的服务器),然后让服务器创建组组件相关联的类工厂,再由类工厂实例化组件,最后通过接口来使用组件。313.1 调用COM组件的过程31323.2 在VC中创建COM组件客户1.打开上一节的MyCom工程后,选择File|New菜单,将弹出的New对话框切换到Projects选项卡后,选择MFCAppWizard(exe)项,在Projectname编辑框中输入ComClient工程名称,并选择AddToCurrentWorkspace单选择按钮。如图8所示。图8在MyCom工作区中添加MyComClient工程323.2 在VC中创建COM组件客户1.打开上一32333.2 在VC中创建COM组件客户(2)2.单击“OK”按钮进入向导下一步骤,选择单文档应用程序类型。完后按“Finish”按钮生成ComClient工程(这是在一个工作区中包含两个工程的情况)。

3.在对话框资源IDD_COMCLIENT_DIALOG中添加图9所示的控件,这些控件的属性如表2所示。图9对话框界面设计333.2 在VC中创建COM组件客户(2)2.单击“OK”33343.2在VC中创建COM组件客户(3)控件类型属性值对应成员变量静态文本控件IDIDC_STATIC

Caption源串

IDIDC_STATIC

Caption目标串

编辑框控件IDIDC_EDIT1m_strSource

IDIDC_EDIT2m_strDestion按钮控件IDIDOK

Caption退出

IDIDC_BUTTON1

Caption转换

表2控件的属性设置与对应的成员变量设置

return343.2在VC中创建COM组件客户(3)控件类型属性值对34353.2在VC中创建COM组件客户(4)

4.在工程中添加Istr类按CTR+W打开类向导对话框后,在当前的工程中加入COM中的一个类。方法为在类向导的MessageMap选项卡下,单击“AddClass”按钮,弹出选项“FromaTypeLibrary”如图10。单击“FromaTypeLibrary”选项,出现图11的对话框,把Mycom.tlb选上,又出现图12的对话框,把Istr类选上,按“OK”按钮,这样就把创建的MyCom.tlb中的类Istr加入到该工程中。

图10从类型库中增加类353.2在VC中创建COM组件客户(4)35363.2在VC中创建COM组件客户(5)

返回

图11选择Mycom.tlb图12选择类型库中的IStr类

363.2在VC中创建COM组件客户(5)返36373.2 在VC中创建COM组件客户(6)5.主要代码(1)在应用程序类的InitInstance()函数中增加初始化OLE的代码BOOLCComClientApp::InitInstance(){AfxEnableControlContainer();AfxOleInit();//初始化OLE……}(2)“转换”按钮的实现代码voidCComClientDlg::OnButton1(){IStrm_string;if(!m_string.CreateDispatch("MyCom.str.1"))//初始化COM库MessageBox("CreateUserInfoerror");UpdateData(true);//将前台数据传到后台BSTRbstrDestion=SysAllocString(L"");m_string.FirstToUpper(m_strSource,&bstrDestion);//调用COM组件中的方法m_strDestion=bstrDestion;UpdateData(false); //将后台数据传到前台}373.2 在VC中创建COM组件客户(6)5.主要代码37383.3 在VB中使用COM组件

前面用ATL创建了一个COM组件MyCom,该组件包含有一个类型库。因为类型库使得可以在

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论