50楼#
发布于:2003-10-26 14:23
经典
问个问题 能不能建立独立的Application 管理mxdocument 谢谢 |
|
|
51楼#
发布于:2003-10-26 11:45
终于开始COM了,一个很沉重也很值得玩味的东西,我想许多AO的开发者对此都会有不同的感受。COM是Microsoft的Component Object Model缩写,它不仅定义了组件程序之间进行交互的标准,而且也提供了组件程序运行所需要的环境(COM本身要实现一个称为COM库(COM library)的API,它提供诸如客户对组件的查询,以及组件的注册/反注册等一系列服务,一般来说,COM库由操作系统加以实现,我们不必关心其实现的细节,象大家经常看到的ActiveX,DirectX,OLEDB都是基于COM技术的),主要应用于Microsoft Windows操作系统平台上。COM通常的发布形式是:以win32动态链接库(DLL)或可执行文件(EXE)的形式发布。
2.3 COM的目标和特性 Ÿ 建立在二进制代码级上的可重用性(通过包容和聚合); Ÿ 语言无关性,只要其能生成符合COM规范即可; Ÿ 对使用COM对象的客户程序而言的进程透明性; 2.3 对象、类和接口 对象是COM的基本要素之一,和C++中的对象不同的是其封装特性是真正意义上的封装,对于对象使用者(通常称为客户)而言是不可见的,此外,COM对象的可重用性表现在COM对象的包容和聚合,一个对象可以完全使用另一个对象的所有功能,而C++对象的可重用性表现在c++类的继承性。 接口是指组件对象的接口,它是包含了一组函数的数据结构,通过这组数据结构,客户代码可以调用组件对象的功能,组件对象间的访问都是通过接口来进行的。接口设计必须满足: 1. 必须直接或间接地从IUNKNOWN接口继承(该接口在AO中是省缺的); 2. 接口必须有唯一的标识符号;接口不变性,一旦分配和公布了IID,接口定义的任何因素都不能改变。 用COM开发意味着使用接口,也可以称为基于接口的设计模型。对象间的所有通信都是通过它们的接口来进行的,COM接口是抽象的,意味着相关的接口没有实现,和接口相关的代码来自于一个类实现。如何实现接口对于不同对象是不同的,因此对象只是继承接口的类型,而不是它的实现,这称为类型继承。功能用接口被抽象地构造,并且用类去真正实现。在COM中类和接口通常被当作‘做什么’和‘怎么做’,接口定义一个对象能做什么,类定义它怎么去做。 COM类提供了一个或多个接口相关的代码,因此功能实体封装在类中。几个类可以有同样的接口,但是它们的实现可能是极不相同的。通过实现这些接口,COM实现了面向对象的多态性,COM不支持多重继承概念,然而,这不是一个缺点因为一个类可以实现多个接口。 2.4 COM的其它组成 COM对象的接口可以是双接口,双接口不同于普通接口(Custom Interface)之处在于双接口是从Automation基本接口Idispatch继承的,而普通接口是从Iunknown接口直接继承来的,缺省的接口模型是双接口模型是双接口。 2. 入接口和出接口(Inbound interface,Outbound interface) COM调用既可以是单向的(即客户程序创建组件对象,然后客户程序调用对象所提供的功能,在适当时候再把对象释放掉),通常称为入接口。如果一个COM对象支持一个或多个主动与客户程序进行通信的接口,则这种接口称为出接口,是因为这些接口并不由对象实现,而是由客户程序实现。类型库(Type Library) 一个类型库被作为一个接口定义语言(IDL)文件的二进制版本,是一系列COM对象和接口的集合,并被编译进一个形如OLB、DLL或OCX这样的二进制文件中。为了支持一个不依赖于开发语言工具的组件集,关于ArcObjects库所有相关的数据都被打包进esricore.olb的类型库,它就包括了一个所有coclasses的二进制描述,接口,方法和服务器类型。 Microsoft提供了多个COM接口用于类型库,这两个接口是ITypeInfo 和ItypeLib。利用标准的COM接口,不同的开发工具和编译器能够获得由一个特定库支持的coclasses和接口有关信息。 4. 双向COM支持 是指有可能既在一种语言中使用COM对象,又可使用这种语言编写COM对象; 5. 进程内COM、本地COM和远程COM COM是一个客户/服务器体系,服务器(或对象)提供功能,并且客户程序使用这些功能。如果COM程序和客户程序在同一进程地址空间内,则称之为进程内COM,这通常是以DLL形式实现,而本地COM是指同一计算机上不同进程中的EXE,远程COM则是指不同计算机中的DLL或EXE。有不耐烦或现在回过头看这章而且存有疑问的人吗?讲了那么多COM AND COM,那么我在DEPHI或VB下用AO写一个DLL,这个DLL到底算什么呢?好,就让我来用C/S的概念来做一个解释。如果你是自己写的应用程序框架,那么你的应用程序就是客户端,而调用的DLL其实就是服务器了;如果你在ArcMap中,那么ArcMap应用程序其实就充当了客户端的角色发出请求,这个请求通过COM机制传递给COM服务器—那个你写的DLL来完成相应的功能,而这个服务器外部和内部就是由ESRI AO的接口及类来完成的。 第三章 AO对象的使用 在第二章中我们谈到了许多关于COM的概念,象类,对象,接口,方法等,那么一个实际的AO开发中是如何体现这些COM概念的呢---既然AO是基于COM的。在本节中,我将使用VB代码来说明如何使用AO的对象,并对如何阅读OMD(Object Model Diagram)进行介绍。 3.1 AO对象的使用 让我们直接用AO相关的代码来开始这段旅程吧,如果你觉得的是的话。:) Dim pMap as IMap Set pMap = New Map PMap.name =”地图名称为-Tour” ……………………. ……………………. Pmap.ClearLayers Pmap.Clear //ERROR 如何运行这段代码是下一章的内容,先看看为什么代码会这么写吧,里面奥妙不少。 Dim pMap as Imap 我们知道在COM中对对象的访问是通过接口来完成,因此不能象许多可视化控件那样,可以直接通过其名称来调用属性或执行其方法。那么这句其实就是定义了一个接口变量(题外注释:其实准确地讲应该是一个指向接口的指针变量才对,好在VB把这一切都给演示了)。有了这个接口变量还不行,因为接口是定义在对象上的,那么下来的步骤应该是产生一个对象,而对象又是从那里来的呢---类。 于是就有了这样的代码Set pMap = New Map。 在这句中不单纯只是实例化出一个Map对象,并且将上句的pMap接口变量做为了该对象的缺省接口。OK,现在我们就可以通过这个接口来对地图名进行修改,或者调用ClearLayer方法来删除掉该地图中的所有图层了。再看看增加最后一句的执行情况—会出错,至于为什么,原因很简单,不同的接口中的方法或属性只能通过其接口来访问,而Clear方法属于Map类的另外一个接口IactiveView所有。可以通过查询接口(Query Interface)来’切换‘到IactiveView上。代码如下 Dim mView as IactiveView set mview=pmap mview.clear 3.2 OMD的作用 OMD(对象模型图)是基于OMT(Object Modeling Technique)的表示方法,先来看看OMD能帮我们做些什么? 1. 该类支持哪些接口; 2. 完成任务需要哪些对象; 3. 如何使用该类的对象; 4. 是否可以直接实例化类; 5. 接口有哪些方法和属性; 6. 是否有其它类也支持该接口; 7. 对象间的关系 3.3 OMD符号解释 在OMD中有三类class,分别是抽象类(AbstractClass)、组件类(CoClass)和普通类(Class)。抽象类的主要目的是为它的子类定义公共接口,一个抽象类将把它的部分或全部实现延迟到子类中,因此,一个抽象类不能被实例化。一个组件类对象可以被直接创建,普通类对象虽然不能直接创建,但它可以可以作为其它类的一个属性或者从其它类的实例化来创建。AO中的Dataset或Geometry classes是抽象类的示例,一个Geometry类型对象不能被创建,但是一个Polyline可以被创建。这个Polyline对象实际上在类的基础上实现了Geometry中定义的接口,因此在基类对象中被定义的接口可以从coclass来访问。 在OMD中的关系类型主要有类型继承(Type inheritance)、创建(Instantiation)、组成(Composition)以及关联(Associations)等。类型继承我们在COM一章过提到过,实际上就是继承完全继承了超类的接口,这点可以利用AO对象浏览器工具清楚的看到,而组成关系指的是对象间的主次关系,也就是说主体的生命存在与否决定着次体的存在与否。 3.4 AO的组织划分 整个AO的OMD看起来密密麻麻,让人有些头晕眼花的感觉。还好,ESRI对整个AO进行了结构的组织分割,按照不同的应用领域可以找到相应的PDF格式的OMD。从AO开发帮助中我们可以发现划分为以下的几个子系统: 1. 3D Analyst Extension ---用于3D可视化和表面建模的组件对象; 2. Application Framework ---让开发者在ArcMap和ArcCatalong中通过程序来定制用户界面; 3. ArcCatalog --- 能够让开发者扩展数据对象模型并集成定制对象和视图到ArcCatalog应用框架中;. 4. ArcMap --- 提供了ArcMap应用程序的核心功能,用于操作和显示地图文档; 5. ArcMap Editor--- 包括了对象编辑器扩展组件对象,要做编辑开发来这吧; 6. Display --- GIS的一个重要应用就是数据表现,对国内的许多最终用户更是热衷于此,利用这里包含的对象可以完成诸如地图符号显示、图形编辑反馈轨迹、坐标转换和屏幕控制等功能; 7. Geocoding --- 主要用于创建和管理地理编码服务等; 8. Geodatabase--- AO开发中一个不可或缺,毕竟GIS的应用都是围绕数据展开的,所以有关的GIS数据创建、加载、管理和存储等都是通过这里的对象进行的; 9. Geometry--- 不管是要素还是图形,涉及到空间信息的获取和应用来这儿找吧; 10. IMS ---提供了连接到ArcIMS服务器并访问ArcIMS图象和要素服务的功能; 11. NetWork--- 提供了网络创建、管理和完成分析操作等功能,打算定制和开发特定网络应用可以利用NetWork对象; 12. OutPut ---有入就有出,如果想把制作好的地图输出怎么办,通过这里提供的对象来完成吧; 13. Raster --- 用于访问和管理栅格数据的的AO对象; 14. Spatial Reference--- 用于完成空间参考的设置; 15.StreetMap USA Extension---这个和国内的用户关系不大。 诚然,在AO的开发中对象的层次和相互关系是极其重要的,稍有撼缺的是OMD中的对象层次组织看起来有些纷乱,个人觉得《Exploring ArcObjects》里的对象模型图更适合入门使用-----它将一些常用和重要的对象抽取出来并以上下层次结构来表示。 絮语闲聊,权当消遣- 最近抽时间整理一些以前写的程序,也开始了解MO(ESRI MapObject)的应用,有些感受一起吐出。在GIS应用中最大的工作就是数据的采集整理了,虽然你可以采用MO、MAPX等一些地图控件(我曾经还看到过一个南非人用DEPHI写的地图控件,也是很有些特点的),如果你够超人,甚至可以自己去做一个地图控件,来完成一个实用性也很个性化的系统出来。可是它终究只是一个应用系统而已。 ???你应该知道我要讲什么的了吧。所有的应用都是基于一定的数据结构,你可以在自己的应用开发中定义数据模型,但是数据的来源呢。不是CAD,就是COVERAGE,SHAPE,(标准嘛)你可以针对一两种数据格式进行转换,只是现实中的数据类型是多样的,总不能都去写吧,况且你的数据格式能否得到认可呢。再想想看你要做多少工作---那是一个GIS平台才能完成的事情。这就是许多情形下我们为什么没法完全用底层或地图控件去写一个完整GIS系统主要的原因吧。 扯远了。。。在本章中,我会实现一个特定功能的DLL,用来说明AO开发开发的几种模式,AO工具包的使用,如何应用写好的组件。在ArcObjects Developer Help中有许多完整和详尽的示例代码,这儿主要想就方法做一个简要的说明。 4.1 选择一个开发模式 AO可选的的开发方式可以分为两种,一种是在ArcMap应用框架基础上进行定制开发,另一种是脱离ArcMap应用框架去开发独立的应用程序。通常情况下,我们都是在ArcMap框架下进行定制开发。开发环境可以选择ArcMap本身自带的VBA,也可以选择VB、VC、DEPHI(AO 8.2以上的版本开始支持C#)。 4.2 选择一个开发工具 作为首选的是VB语言,这样不管是在VBA,还是编写COM组件,你都有最充足的资源可以使用(AO开发文档中最多的SAMPLE就是VB代码了)。第二种是VC(我更愿意将VC做为一个强有力的后备工具),第三种在我看来应该是一种无奈之举了,即用DEPHI(有一堆人该贬我了:)一直对DEPHI是仰慕有加心仪已久的,只是在AO中有关DEPHI的例子太少了,这对快速应用开发来说是致命的)。 4.3 最简单的”Hello,world”程序 讨论开发工具多少有点离题,现在让我们来转回到一个出名的小应用程序—“Hello,world”,许多语言都是以此做为第一个应用的,我也就不例外了。 打开ArcMap应用程序,选择TOOLS菜单下的MACROS子菜单,打开其中的VBA环境。选择Project工程下的ArcMap Object ,双击打开其中的ThisDocument对象,在右边的编辑环境中选择对象列表中的MxDocument对象,在任务列表中选择OpenDocumen,然后键入以下的代码: //Private Function MxDocument_OpenDocument() As Boolean Dim pmap As IMap Set pmap = New Map pmap.Name = "Hello,world" MsgBox pmap.Name //End Function 然后按CTRL+S保存后退出ArcMap。当你再次打开你所保存的工程文档时看到了什么?呵呵呵,不知道ESRI的设计人员看到这样的一个SAMPLE会不会晕掉。 有人说了,你这一堆VB代码对我来说我搞不懂啊,我熟悉的是VC,总不能让我先去学VB再来做AO开发吧。OK,没关系,下面我就以这个“Hello,world”来写一个组件并在ArcMap中来使用。 1. 启动VC,使用ATL COM AppWizard创建一个DLL工程; 2. 在INSERT菜单下选择NEW ATL OBJECT来增加一个ATL COM对象, 3. 给这个COM对象就起个“world”的名字吧,选择Custom接口类型(至于为什么不选择DUAL,你可以琢磨下) 4. 在工作空间上选择Cworld类,并右键选择Implement Interface,在类型库中引入ESRI OBJECT Library,选择你要实现的接口(这儿我们选择Icommand) 5. 增加一个全局变量(IApplicationPtr m_ipApp;)来引用到一个应用程序。注意到没有,这儿的接口变量定义和VB的有什么不同,除了本身的语法。就是接口多了‘Ptr’。因此,在VC中如何使用AO的对象你现在应该猜到一些了吧。 6. 下面的工作就是实现接口了。看看Iworld接口中都有哪些东西,哦,这个OnClick()应该是我们想要做些事情的地方了。 // STDMETHODIMP CZoomIn::OnClick(){ IDocumentPtr ipDoc; m_ipApp->get_Document(&ipDoc); IMxDocumentPtr ipMxDoc(ipDoc); IMapPtr ipmap; ipMxDoc->get_FocusMap(&ipmap) ipmap->put_Name(_bstr_t("Hello,world"); ………… ::MessageBox(NULL,_T("Hello World!",_T("Wellcom AO", MB_OK); return S_OK; //} 7.编译连接工程; 8.在 ArcMap中注册后就可以将该按钮直接拖放到ArcMap中来使用了。(当你点击时,会弹出当前地图被修改后的名称----“Hello,world”。 4.5 AO程序实现的一般过程 不管是用VB还是VC或是其它,要做的第一步就是在集成环境因入AO对象库(Esricore.olb),剩下的工作在接口中实现你要做的事情。关于如何进入VB和VC开发的完整代码及说明,请参阅ArcObject Developer Help。 可能是有感于独立AO应用程序开发群的迅速扩大,ESRI在其最新的ArcGIS8.2版本中不但继续提供对MapControl控件的开发支持,而且新增了一个PageLayoutControl控件,这对于有制图应用的开发者来说无疑带来了福音。许多时候可能会对组件和控件有些糊涂,其实Active X并不能代表整个COM,它只是COM对象的封装技术,由于COM对象使用的复杂性,因此才会创建框架(如Active X控件)来简化它。所以这两个控件也可称为AO高级通用组件,它由AO基础组件构造而成,面向通用功能,简化了用户开发过程,组件之间的协同控制消息都被封装起来。这级组件经过封装后,使二次开发更为简单。如一个简单的AO应用系统,若用基础AO组件对象开发,需要编写不少的代码,而利用高级通用组件,只需几句代码就够了。 5.1 MapControl控件 MapControl控件提供了类似ArcMap中的数据视图(Data View)的窗口,通过它你可完成以下甚至更多功能: Ÿ 显示图层地图。 Ÿ 放大,缩小,漫游。 Ÿ 生成图形元素,如点,线,圆,多边形。 Ÿ 说明注记 Ÿ 识别地图上被选中的元素,进行空间或属性查询。 Ÿ 标注地图元素。 总之在ArcMap中能能够完成的大部分任务,通过MapControl控件也可以完成。通过设置MapControl General, Layers, Map 属性,你甚至不需要写一行代码可以获得一些GIS功能。关于MapControl控件有许多完整的应用示例,存放在\\ArcObjects Developer Kit\Samples\Controls目录下。 5.2 PageLayout控件 PageLayout控件提供了类似ArcMap中的版面视图的窗口,它有以下的属性、方法和事件: • 管理控件的外观设置 • 管理控件的显示属性 • 管理页面属性 • 在控件中增加和查找元素 • 加载地图文档到控件 • 可以直接从资源管理器和ArcCatalog中拖放数据到控件中 • 打印页面设计. 至于它的功能嘛,ArcMap的Layout 视图能完成的工作,使用PageLayoutControl同样可以完成,象增加和设置图例、打印输出等许多功能。关于PageLayout控件有许多完整的应用示例,也存放在\\ArcObjects Developer Kit\Samples\Controls目录下。 5.3 MapControl和MapObject的关系 确切地讲,MapControl和MapObject控件没有直接的联系。首先,MapControl控件是AO的一部分,至少到目前为止它还不是一个独立的产品,而MapObject是ESRI的一个独立的低端应用产品。第二,MapControl比MapObject功能要强大许多和完善许多,MapObject产品的定位就是提供一些基本的地图功能,高级的功能这得完全靠开发者自己去实现,而依托强大的AO组件库MapControl可以实现许多高级的GIS分析及应用。 |
|
|
上一页
下一页