阅读:1283回复:0
用C++实现混合使用MAPGIS的多种二次开发方式
<P>一、MAPGIS及其二次开发</P>
<P>1、MAPGIS简介 MAPGIS微机地理信息系统是武汉中地信息工程有限公司开发的GIS基础平台软件系统。集地图输入编辑、数据库管理及空间分析为一体GIS基础平台。可应用于建立基础地理信息系统,能应用于需要地理信息的相关行业和应用系统。作为一个GIS基础平台软件,提供了多种二次开发方式,用户可以在MAPGIS上进行二次开发,开发出适合自己需要的应用系统。</P> <P>2、MAPGIS二次开发方式 MAPGIS的二次开发方式主要有API函数、MFC类库、ActiveX控件三种方式,MAPGIS二次开发库封装在若干动态链接库(DLL文件)中。MAPGIS提供的二次开发方式采用的开发接口独立于开发工具(MFC类库开发方式除外),用户无需学习新的开发工具就可以进行MAPGIS二次开发,无需像某些有自己二次开发语言(工具)的GIS系统,要学习其开发语言(工具)。下面介绍一下MAPGIS的三种二次开发方式: API函数:MAPGIS的API函数开发方式与Windows的API开发方式一样。 MFC类库:MAPGIS类库是基于MFC库的开发方式。用面向对象的思想把一些API功能进行封装,形成多个派生于MFC中CView类的可重用基类,用户利用基于MFC的MAPGIS类库,可构建符合面向对象软件工程的MAPGIS应用系统。 ActiveX控件:它是基于COM(组件对象模型)标准的一种程序组件,能够嵌入程序中运行完成一定功能,在软件开发中实现了功能重用。开发中只需简单调用功能接口就行了,开发更为简单、可靠、便利。</P> <P>3、C++开发工具 C++语言是最符合面向对象软件工程思想的开发工具,C++支持结构化软件工程、面向对象工程、组件软件工程开发模式。事实上C++也是应用最广泛的开发语言,在当今最先进的组件软件开发模式中,C++是支持得最好的,尽管组件的使用不依赖特定的语言,但开发符合COM规范的软件组件的最佳开发语言还是C++。Visual C++ 是微软公司推出的C++开发工具,它与Windows系统有很好的兼容性,自Visual C++5.0推出以来,它已成为开发Windows应用程序的最流行的C++开发工具。我们就以Visual C++ 为例介绍怎样用C++实现混合使用MAPGIS的多种二次开发方式。</P> <P>二、用C++实现混合使用MAPGIS的多种二次开发方式 使用C++进行API、MAPGIS类库方式开发MAPGIS应用程序,大家都很熟悉。这里主要是讲怎样用C++实现混合使用MAPGIS的三种二次开发方式。对于C++使用MAPGIS控件开发MAPGIS应用程序,可能有些用户还不太熟悉。所以先讲怎样用ActiveX控件开发MAPGIS应用程序,再讲怎样用C++实现混合使用MAPGIS的三种二次开发方式。</P> <P>1、Visual C++中使用ActiveX控件开发方式 MAPGIS推出的ActiveX控件二次开发方式,主要是对于那些使用基于对象语言开发工具的用户,如Visual Basic,Delphi等,用这些开发工具的用户就可以使用MAPGIS控件对象来快速构建MAPGIS应用程序。事实上这种基于COM(组件对象模型)标准的MAPGIS控件是用C++开发出来的,但是这种用C++做出来的好东东,被他人所用,总感觉不爽。其实C++可以使用ActiveX控件开发,经常往对话框中放的一些编辑框之类的东西就是一些ActiveX控件,但是MAPGIS是要在视图中显示大量的图形的,并要进行操作,怎么办呢?你不要担心,对话框、视窗都是派生于CWnd类的,它们都能支持嵌入ActiveX控件。下面分别介绍</P> <P> 一、 在对话框程序中使用MAPGIS控件 在对话框应用程序中使用MAPGIS的ActiveX控件,比较简单。我们可以这样做。 首先将MAPGIS的ActiveX控件在Windows系统中注册,以GisEdit控件为例,运行regsvr32.exe 注册。见图1。</P> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD align=middle height=169><IMG src="http://www.mapgis.com.cn/club/image/image002.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图1</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD align=left height=32>注册成功后,出现图2所示对话框:</TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image004.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 2</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>如果没成功的话,看看是否和MAPGIS的DLL文件放在同一目录下,因为它还要依赖MAPGIS的DLL库。 然后用VC中的MFC AppWizard生成一个对话框架的应用程序。打开所生成的对话框资源,在对话框资源上右击,并选择Insert ActiveX Control…菜单。如图3所示。 </TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image006.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 3</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=13>然后选择GisEdit Contrl控件并插入,如图4、图5所示。</TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image008.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 4</TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image010.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 5</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>调整对话框大小及GisEdit控件大小,添加几个功能按钮,如图6所示。 白色部分为GisEdit控件。</TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image012.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 6</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>为了操作GisEdit控件,在ClassWizard中,将GisEdit控件添加为成员变量。变量名为m_MapGIS。如图7所示 </TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image014.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 7</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>为几个功能按钮添加消息映射,并编写对应的函数。代码如下: void CDdDlg::OnL() //装入MAPGIS线文件 { m_MapGIS.LoadLine(); } void CDdDlg::OnP() //装入MAPGIS点文件 { m_MapGIS.LoadPoint(); } void CDdDlg::OnPr() //装入MAPGIS工程文件 { m_MapGIS.LoadProject(); } void CDdDlg::OnR() //装入MAPGIS区文件 { m_MapGIS.LoadRegion(); } <P> 编译运行后就可以了。运行结果见图8</P> <p> <p></TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image016.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 8</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>以上只是一个很简单的例子。对话框和控件都是由CWnd类的派生的,利用MFC类的相关函数,可以完成更高级的功能,如对话框大小由程序调整,GisEdit控件的位置和大小也可由程序动态调节,加入菜单、工具条、状态条等,你要知道VB是在FROM上用GisEdit控件开发,这和VC中对话框上用GisEdit控件开发,在原理上是一样,只不过VB有一个比较易用的控件属性对话框,但VC可直接支持更多的功能,你完全可以用MAPGIS控件在VC上开发出MAPGIS应用程序。 <P> 二、 文档/视窗应用程序中使用MAPGIS控件 在对文档/视窗应用程序程序中使用MAPGIS的ActiveX控件,并不复杂。我们可以这样做。通过MFC AppWizard生成一个单文档/视窗框架的应用程序。</P> <P> 建好工程后,选择“Project->Add project->Components and Controls…”后,选择“Registered ActiveX Controls”进入后,选择插入GisEdit Control控件。如图9所示。 </P></TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image018.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 9</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>插入控件后,你会发现ClassView中多了一个CGisEdit类,这表明已经把控件加入到工程中来了,下面就可以进行操作了。我们还需要对CgisEdit类进行一下改进,因为我们要通过视窗大小的变化来改变CgisEdit控件的大小,查一下CgisEdi的基类就可发现它是CWnd类的派生类,在CWnd类中有个MoveWindow(CRect rect)函数来改变窗体位置和大小,不幸的是CgisEdit也有一个同样的函数,但功能不一样。所以我们自己增加一个改变控件位置和大小的函数MoveWindows(int x,int y)。具体代码如下: <P>void CGisEdit::MoveWindows(int x, int y)</P> <P>{ CWnd::MoveWindow(0,0,x,y);</P> <P>}</P> <P> 在视窗类中,加入变量m_MapGIS,类型为CGisEdit;如图10所示:</P> <p></TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image020.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 10</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD align=left height=32>定义了变量m_MapGIS后,要做的事是让视窗建立时,同时运行m_MapGIS控件。要为视窗类添加WM_CREATE消息映射,并加入如下代码: <P>int CMapView::OnCreate(LPCREATESTRUCT lpCreateStruct) </P> <P>{</P> <P>if (CView::OnCreate(lpCreateStruct) == -1)</P> <P>return -1; </P> <P>// TOD Add your specialized creation code here</P> <P>m_MapGIS.Create(NULL, WS_VISIBLE,CRect(50,50,100,100), this, 0); </P> <P>return 0;</P> <P>}</P> <P>为了在视窗改变大小时,m_MapGIS控件也改变大小,为视类添加一个WM_SIZE消息,在其生成的OnSize函数中添加如下代码。 void CMapView::OnSize(UINT nType, int cx, int cy) </P> <P>{</P> <P>CView::OnSize(nType, cx, cy); </P> <P>// TOD Add your message handler code here</P> <P>m_MapGIS.MoveWindows(cx,cy);// GisEdit控件中新增的改变窗口大小函数</P> <P>} </P> <P>在菜单资源中,修改“打开文件”项,改成“打开工程文件”;并将其(资源ID号:ID_FILE_OPEN) 在视窗类中(本例为CMapView)建立消息映射。在映射函数中加入如下代码:</P> <P>void CMapView::OnFileOpen() </P> <P>{</P> <P>// TOD Add your command handler code here</P> <P>m_MapGIS.LoadProject();</P> <P>}</P> <P>编译整个工程并运行,打开一个MAPGIS工程文件,运行结果如图11,所示</P> <p></TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image022.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 11</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>运行结果与通过MAPGIS类库开发的应用程序一样!但是你会发现,它与通过类库开发的MAPGIS应用程序相比,不需要放在MAPGIS的系统目录中运行。因为基于COM标准的MAPGIS控件是操作系统直接支持的,通过MAPGIS控件开发的MAPGIS应用程序通过操作系统直接调用MAPGIS控件,无需与MAPGIS系统目录下的开发库直接打交道。这样你的MAPGIS应用程序就可在装有MAPGIS 系统的机器上运行,不必考虑存放在什么位置了。是不是要方便一点。 <P>3、用C++实现混合使用MAPGIS的多种二次开发方式</P> <P>通过上面的文档/视窗应用程序示例程序。我们可以看出用控件开发实际上是:C++利用COM标准根据控件接口功能抽象成调用控件接口的一个类,像用类库开发一样调用控件的功能。刚才我们就用这个方法扩充了控件的功能。实际上我们就混合了类库和控件的开发方式。有时候类库和控件开发方式的功能不能满足开发需要,我们可以同时使用API开发方式完成一些高级功能。下面举例子说明。 比如我们要在上面的文档/视窗应用程序中实现读取加密狗(卡)号的功能。类库和控件中都没有这功能。我们可以使用API方式来完成。</P> <P>为了使应用开发能使用API方式,在stdafx.h文件中包含mapgis.h,具体操作可参考《MapGIS地理信息系统开发手册》。 首先在上面的文档/视窗应用程序中,在菜单资源中增加一个test字菜单,并增加card菜单项,在视类(CMapView)中增加处理card菜单项的消息映射和函数。函数代码如下:</P> <P>void CMapView::OnMenuCard() </P> <P>{</P> <P>// TOD Add your command handler code here</P> <P>long id;</P> <P>CString fxj;</P> <P>fxj.Format("加密狗(卡)号:%d",id);</P> <P>id=_GetCardNo();</P> <P>MessageBox(fxj); </P> <P>}</P> <P>编译运行结果,如图12所示:</P> <p></TD></TR> <TR> <TD vAlign=center align=middle height=25><IMG src="http://www.mapgis.com.cn/club/image/image024.jpg"></TD></TR> <TR> <TD vAlign=center align=middle height=25>图 12</TD></TR></TABLE> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TR> <TD class=hanggao2 align=left height=32>不要忘了,由于是采用了API开发方式,要把编译好的执行文件放在MAPGIS系统目录下运行,或者将MAPGIS系统目录的东东单独拷出来放在同一目录下运行。 <P>以上只是一个小小的例子,起抛砖引玉的作用。希望与大家探讨MAPGIS二次开发。</P></TD></TR></TABLE> |
|
|