阅读:1385回复:2
应用Visual Basic的事件机制设计可复用的大粒度GIS组件
<H2><a href="http://www.cnblogs.com/maweifeng/archive/2004/12/21/79977.html" target="_blank" >应用Visual Basic的事件机制设计可复用的大粒度GIS组件</A> </H2>
<DIV> </DIV> <H1>1. 引言</H1> <DIV>当前地理信息系统的应用需要GIS与与MIS、OA等其它系统的有机集成,因此,大多数的GIS系统开发都选择以组件式GIS为核心进行二次开发。因此,随着计算机和地理信息技术的飞速发展,以及GIS理论与应用的逐渐成熟,组件式技术已逐渐成为GIS 软件的主流,改变了传统集成式GIS 平台的工作模式。代表性的组件式GIS有ERSI的ArcGIS和北京超图的SuperMap Object。</DIV> <DIV>在组件式GIS的开发中,由于GIS功能和用户界面要求按照需求进行定制,而GIS的大多数功能的调用都需要调用底层的GIS组件进行实现,因此,每次的开发都需要对一些重复的GIS基本功能或核心功能进行编码和实现,工作异常的繁琐且易出错。例如,地图的浏览功能(包括大小缩放、漫游、显示控制等)在几乎所有的GIS系统中都要求实现,而其核心实现又都是基于GIS组件的,因此,在开发过程中,开发人员常常需要一遍遍的实现类似功能。</DIV> <DIV>本文将介绍基于VB的事件机制和对象委托方式将类似功能封装成一个COM组件的思路和方法。</DIV> <DIV> </DIV> <DIV>全文及免费代码:<a href="http://www.cnblogs.com/maweifeng/archive/2004/12/21/79977.html" target="_blank" >http://www.cnblogs.com/maweifeng/archive/2004/12/21/79977.html</A></DIV> |
|
1楼#
发布于:2004-12-21 13:55
<P><img src="images/post/smile/dvbbs/em01.gif" /></P><P>转过来了</P><H1>1. 引言</H1><DIV>当前地理信息系统的应用需要GIS与与MIS、OA等其它系统的有机集成,因此,大多数的GIS系统开发都选择以组件式GIS为核心进行二次开发。因此,随着计算机和地理信息技术的飞速发展,以及GIS理论与应用的逐渐成熟,组件式技术已逐渐成为GIS 软件的主流,改变了传统集成式GIS 平台的工作模式。代表性的组件式GIS有ERSI的ArcGIS和北京超图的SuperMap Object。</DIV><DIV>在组件式GIS的开发中,由于GIS功能和用户界面要求按照需求进行定制,而GIS的大多数功能的调用都需要调用底层的GIS组件进行实现,因此,每次的开发都需要对一些重复的GIS基本功能或核心功能进行编码和实现,工作异常的繁琐且易出错。例如,地图的浏览功能(包括大小缩放、漫游、显示控制等)在几乎所有的GIS系统中都要求实现,而其核心实现又都是基于GIS组件的,因此,在开发过程中,开发人员常常需要一遍遍的实现类似功能。</DIV><DIV>本文将介绍基于VB的事件机制和对象委托方式将类似功能封装成一个COM组件的思路和方法。</DIV><H1>2. Visual Basic的事件机制</H1><DIV>Visual Basic是并不是一个优秀的面向对象语言,但在Visual Basic中也可以完全开发具有属性、方法、事件(P-M-E)COM组件。下面将详细介绍VB6的事件处理过程。</DIV><DIV>在VB中,事件的定义和触发的语法如下:</DIV><DIV>在Class(类)中定义:</DIV><DIV> ○ 事件定义:Event …</DIV><DIV> ○ 事件触发:RaiseEvent …</DIV><DIV>而客户代码事件处理使用如下语法:</DIV><DIV> ○ 第一,定义事件处理对象:Dim WithEvents ObjectXX As Class</DIV><DIV> ○ 第二,处理事件:</DIV><DIV> </DIV><DIV> Private Sub ObjectXX_EventName</DIV><DIV> …</DIV><DIV> End Sub</DIV><DIV> </DIV><DIV>对于一般情况下,窗体、控件的使用,其实并不需要这么使用,因为有缺省的事件处理过程,例如Form_Load事件,Command1_Click事件等等,我们只需要相应其事件就可以了。但是,如果在一个Form内有一个Command1的按钮控件,那么,我们可以定义以下的事件处理程序:</DIV><DIV> </DIV><DIV>Private Sub Command1_Click()</DIV><DIV> MsgBox "Old Test"</DIV><DIV>End Sub</DIV><DIV> </DIV><DIV>另外,我们还可以定义另外一个处理过程:</DIV><DIV> </DIV><DIV>Dim WithEvents SS As CommandButton</DIV><DIV> </DIV><DIV>Private Sub SS_Click()</DIV><DIV> MsgBox "New Test"</DIV><DIV>End Sub</DIV><DIV> </DIV><DIV>执行则可以看到,两个过程都可以响应执行。因此,通过WithEvents定义的事件处理过程可以在单独的模块或类里,这样就可以隔离程序的界面和具体逻辑,这也就是本文需要应用的技术。</DIV><DIV>其实对于VB.net或者C#,事件处理的方法和VB6在形式上并没有很大的差别,差别只是VB6中有缺省的事件处理过程;如同VB6有缺省的窗体一样,你可以这样使用:Form1.show,而在VB.net中必须先创建一个form,然后才可以调用。</DIV><H1>3. 应用实例</H1><DIV>应用以上方法和技术,我们将基于北京超图公司的SuperMap Object组件式GIS先创建一个可以重复使用的地图浏览的控件,并且通过一个简单的项目来测试其正确性。</DIV><H2>3.1. 可重复使用的地图浏览控件MapView</H2><DIV>首先,启动VB6,创建一个ActiveX 控件项目,给该项目添加一个工具条控件,添加必要的按钮。</DIV><DIV>其次,我们需要添加对SuperMap Object组件的引用,在该组件的代码中添加如下声明:</DIV><DIV> </DIV><DIV>Dim SW As SuperWorkspace</DIV><DIV>Dim SM As SuperMap</DIV><DIV> </DIV><DIV>Private WithEvents EventSM As SuperMap</DIV><DIV> </DIV><DIV>第一、二句声明了工作空间和地图对象,第三句声明了地图对象事件的处理对象。给该控件添加一个连接方法,使声明的工作空间和地图空间指向项目中的实际控件:</DIV><DIV> </DIV><DIV>Public Function Connect(objSW As Object, objSM As Object) As Boolean</DIV><DIV> If objSW Is Nothing Or objSM Is Nothing Then</DIV><DIV> Connect = False</DIV><DIV> Else</DIV><DIV> Set SW = objSW</DIV><DIV> Set SM = objSM</DIV><DIV> Set EventSM = SM</DIV><DIV> Connect = True</DIV><DIV> End If</DIV><DIV>End Function</DIV><DIV> </DIV><DIV>其中,传入的参数将工作空间和地图声明为Object类型是因为这两个控件都是不可创建的,因此不能在参数中声明。其他代码很简单,只是将传入的控件实例赋给控件中的工作空间和地图对象。其中Set EventSM = SM初始化EventSM对象,使EventSM对象可以处理地图对象的事件。然后,对于地图操作,我们就可以使用这两个对象(SW和SM)来进行了。例如地图缩放:</DIV><DIV> </DIV><DIV>……</DIV><DIV>Case "ZoomIn"</DIV><DIV> SM.Action = scaZoomIn</DIV><DIV>Case "ZoomOut"</DIV><DIV> SM.Action = scaZoomOut</DIV><DIV>……</DIV><DIV> </DIV><DIV>对于工作空间和地图对象的事件处理,因为在控件开始声明了具体的事件处理对象“EventSM”,利用此对象,即可对相应的事件进行处理。以下两个过程,第一个当地图重画后更新地图比例尺的显示,第二个在选中地图对象后,调用一个过程显示相应对象的属性。</DIV><DIV> </DIV><DIV>Private Sub EventSM_AfterMapDraw(ByVal hdc As stdole.OLE_HANDLE)</DIV><DIV> '地图比例尺</DIV><DIV> If SM.ViewScale <> 0 Then</DIV><DIV> Combo1.Text = "1:" ; Format(1 / SM.ViewScale, "#")</DIV><DIV> End If</DIV><DIV>End Sub</DIV><DIV> </DIV><DIV>Private Sub EventSM_GeometrySelected(ByVal nSelectedGeometryCount As Long)</DIV><DIV> '调用属性显示过程显示选中对象属性</DIV><DIV> ShowObjectInfo SM</DIV><DIV>End Sub</DIV><DIV> </DIV><DIV>这样,我们就可以把地图浏览显示的一些代码封装在一个控件内,而无需关心其实现,只要在代码中将其和实际的地图和工作空间对象连接即可使用。</DIV><H2>3.2. MapView地图浏览控件的使用</H2><DIV>新建一个VB6工程,添加相应的SuperMap Object控件和MapView控件,调整其到合适的位置,在FormLoad事件里添加如下代码:</DIV><DIV> </DIV><DIV>If Me.SuperWorkspace1.Open("…") Then</DIV><DIV>Me.SuperMap1.Connect Me.SuperWorkspace1.Handle</DIV><DIV>Me.SuperMap1.OpenMap "World"</DIV><DIV>If Not Me.MapView1.Connect(Me.SuperWorkspace1, Me.SuperMap1) Then</DIV><DIV> Unload Me</DIV><DIV> End If</DIV><DIV>End If</DIV><DIV> </DIV><DIV>程序与控件的连接语句只需“MapView1.Connect”,运行程序,可以看到地图浏览控件实现的地图浏览已正确的运行,见下图:
</DIV><DIV align=center> <img src="http://www.cnblogs.com/images/cnblogs_com/maweifeng/MapView001.jpg"> </DIV><H1>4. 结论</H1><DIV>基于以上方法,笔者应用VB6实现了基于SuperMap Object的地图浏览控件,该控件只需要在初始化时调用Connect语句,与SuperMap Object的工作空间控件和地图控件连接,即可实现地图的缩放、平移、图层控制、属性的SQL查询、将当前地图输出为图片和打印当前地图等功能。该控件及其示例代码可在笔者的Blog下载。</DIV><DIV>应用Visual Basic的事件处理机制,以及合适的面向对象的设计,一方面,我们可以将在项目开发中经常需要使用的组件GIS的功能封装成独立的组件,可以大大的加快开发速度,避免不必要的错误,减少应用逻辑、程序界面、GIS实现之间的耦合,提高开发质量;另一方面,通过此类方法,可以在实际开发中进行合理的分工合作,提高工作效率。</DIV><DIV> </DIV><DIV>本文代码开发和测试环境:</DIV><UL><LI>Windows XP Sp1 <LI>Visual Basic 6 (Sp6) <LI>SuperMap Object 3 </LI></UL><P><a href="http://www.cnblogs.com/Files/maweifeng/MapView.rar" target="_blank" >http://www.cnblogs.com/Files/maweifeng/MapView.rar</A> </P> |
|
|
2楼#
发布于:2004-12-22 10:57
<P>在vc里头实现就复杂鸟,还要定义一个嵌套类来实现那个连接</P>
|
|