VC下MapX开发环境建立

  有很多的朋友在VC下使用MapX的时候,总是感觉不是很顺手,其中一个很明显的问题就是老是出现COleVariant或Variant 类型的数据,对于习惯了使用VC下形如CString等类型变量的朋友来说COleVariant或Variant类型给VC下使用MapX造成了很多不 便;也造成了开发和调试效率很低,在数据类型上打转转。

    我这篇文章不是要告诉大家如果进行数据类型的转换,也不是来讲VC下如何使用MapX的各个功能来编写程序,而是要解决一个环境问题——帮助习惯了使用VC一般数据类型的朋友建立一个平易近人的MapX开发环境。

声明:我这篇文章只针对VC++6.0下使用MapX,以后不再加以说明。

一、”普适标准工程”

    只要安装了MapX控件,无论使用什么样的.H或.CPP文件,MapX在你的机器上就可以用来做开发使用了。

    一个使用MapX控件的”普适标准工程”就是将MapX安装目录下”\MapInfo\MapX 5.0\Samples50\C++\Cpp”文件夹下的MAPX.H和MAPX.CPP文件考到你的工程目录下,通过” Project->Add To Project->Files…”添加到工程中去就完成了。

    上面这个”普适标准工程”,会有几个比较棘手的问题出现:

    1. 基于Dialog的工程中,以前可以直接从控件栏上拖下来一个MapX控件放在窗体上,还可以调整大小,设定一些初始值,”普适标准工程”无法做到了?

    2. 基于Doc/View的工程下建立了一个”普适标准工程”后,如何添加一个MapX控件,并让它显示出来?如何给它添加事件响应?

    3. 如何将我现有的工程转换成”普适标准工程”?

二、Dialog标准工程

    执行“Project->Add To Project->Components and Controls…”,在Components and Controls Gallary对话框中选择Mapinfo MapX 5.0控件,点击Insert并确认添加后会出现Comfirm Classes对话框:

    在Comfirm Classes对话框中显示出了添加MapX控件将会在我们的工程里面自动生成的所有类(包括.H和.CPP文件)。一般情况下,大家都是直接点击了确认,于是就会出现下图这样的情形:

    要建立Dialog的标准工程,这里不提倡上面的做法。而是采用下面的方法:除了必须添加的CCMapX类以外其他的类均不添加,具体的做法就是在点击OK前将其他类前复选框的对勾去掉,如下图:

    这样点击确认后就会出现下图的情形:

    添加完成后控件栏上就会多出一个MapX控件:

    接下来要做的就是从文件视图中,选中cmapx.h和cmapx.cpp两个文件,按下Delete键,将这两个文件从工程中删除;同时从工程目录下将 cmapx.h和cmapx.cpp两个文件删除。删除的这两个文件其实就是支持COleVariant或Variant类型的文件,接下来要做的就是添 加MAPX.H和MAPX.CPP两个文件。

    从MapX控件安装目录MapInfo\MapX 5.0\Samples50\C++\Cpp下找到MAPX.H和MAPX.CPP两个文件拷贝到Dialog工程目录下;通过 “Project->Add To Project->Files…”添加到Dialog工程当中。此时的工程应该有如下形式:

    到此为止,一个Dialog标准工程就建立好了。你仍然可以从控件栏中拖下MapX控件,调整位置和大小,也可以通过属性页设置它的初始状态,还可以使用 ClassWizard来给控件添加变量以及事件响应等等。但是,这个标准工程下,一般不会再出现COleVariant或Variant类型的数据了, 很多地方都可以直接使用如CString这样的变量了。

三、Doc/View下如果使用MapX控件

    其实这里我说多了好多人都会笑话我的,但是基于从初学着的角度来讲还是说一点。

    MAPX是一个窗口控件,也就是它本身就是一个窗口,它跟CEdit、CComboBox这些控件是样的。要想在Doc/View中使用就必须动态创建, 而MAPX控件创建的过程跟CEdit或CComboBox是没有什么区别的,只要你会在Doc/View中动态创建CEdit或CComboBox就应 该会创建MAPX控件。一般都遵从这样的步骤:

    1.添加资源ID。

    这个需要在工程的资源视图下的String Table下增加一个ID,形如: 

   

    2.添加MAPX控件头文件的引用

    我一般直接把MAPX头文件的引用添加到工程的StdAfx.h文件中,这样就不必在其他的很多文件中添加这个引用了。#include MAPX.H

    3.声明CMapX类型变量

    在视图类中声明: CMapX m_ctrlMapX;

    4.使用MAPX的Creat方法,在工程中视图类创建(也可以是其他地方,但是要在视图类本身创建完成后)的时候创建MAPX控件。

    例如:

 1    int C**View::OnCreate(LPCREATESTRUCT lpCreateStruct) // (C**View类的WM_CREATE消息响应函数)
 2          {
 3                   if (CView::OnCreate(lpCreateStruct) == -1)        return -1;
 4                   RECT windRect;
 5                   GetClientRect(&windRect);       //取得视图区域
 6                   if (!m_ctrlMapX.Create(NULL, WS_VISIBLE, windRect, this,IDS_MAPX1))         return -1;
 7                   //这里创建的MAPX控件窗口覆盖整个视图区域
 8                   //这句代码用语言描述的话可以这样说:
 9                   //以当前视图窗口为父窗口,以IDS_MAPX1为标识,创建一个可见的、无窗口名称的、
10                   //覆盖整个视图区域的MAPX控件窗口。
11                   return 0;
12          }

    5.设定控件的初始状态

    如果简单的创建了MAPX控件在显示的时候会显示美国的地图,这样就需要在视图出现前改变MAPX的基本设置,改变默认地图。当然进行一些其他的设置也是可以的,例如,改变地图中心、缩放率、是否可编辑、是否可选择以及添加一些新图层等等操作。

    我一般将这些初始化放在view类的OnInitialUpdate()函数中来做。例如:

 1    void C**View::OnInitialUpdate()
 2     {
 3                   CView::OnInitialUpdate();
 4 
 5                   //----------------加载中国地图---------------------------
 6                   m_ctrlMapX .SetGeoSet("CHINA.GST");
 7                   //-------------------------------------------------------------
 8 
 9                   CMapXLayers allLr= m_ctrlMapX .GetLayers();
10 
11                   //----------------- 添加现有数据图层 -----------------
12                   allLr.Add("CHINAHWY.TAB");
13                   allLr.Add("CHCTY_5K.TAB");
14                   //--------------------------------------------------------------
15 
16                   //------------------添加用户绘制图层--------------------
17                   CMapXLayer cusLr=allLr.AddUserDrawLayer(“userLr”,1);
18                   allLr.SetAnimationLayer(cusLr.DetachDispatch());
19                   //--------------------------------------------------------------
20 
21                   //-------------------添加一个”固定”图层-----------------        
22                   CMapXLayer staLr;
23                   staLr =allLr.CreateLayer(“stLrNa”,NULL, 2, 32);
24                   //---------------------------------------------------------------
25 
26     }

    6.添加MAPX控件的事件响应

    很显然在Doc/View下要想像Dialog中那样通过ClassWizard来给MAPX控件添加事件响应已经不可能了。这个时候需要我们自己手动添加了。

    这里简单的扯两句,其实ClassWizard添加事件响应与我们手动添加有什么本质上的不同么?答案是没有,一模一样的。

    要正确的认识ClassWizard。ClassWizard其实就是一个助手,它只是让我们在代码生成上更加的直观,更加有效率,同时规避了一些内部必然的联系还需要我们手动来做的麻烦而已。如果我们不嫌麻烦,那么完全可以不用ClassWizard。

    下面是一个标准的菜单消息响应过程,这个过程主要包括四个部分:函数定义、宏声明、消息映射、函数实现.

 1   afx_msg void OnFileOpen();                                //H文件中函数定义
 2     DECLARE_MESSAGE_MAP()                            //H文件中宏声明
 3     BEGIN_MESSAGE_MAP(C**View, CView)     //CPP文件中消息映射
 4     //{{AFX_MSG_MAP(C**View)
 5     ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
 6     //}}AFX_MSG_MAP
 7     END_MESSAGE_MAP()
 8     void C**View::OnFileOpen()                                //CPP文件中函数实现
 9     {
10     }

    给动态生成的MAPX控件添加事件也需要这样一个过程,所不同的是,我们需要一个不同的宏来处理消息映射。这个不同的宏就是DECLARE_EVENTSINK_MAP()——槽事件处理宏声明。(这里不多讨论)

    我们只管照猫画虎,也弄出一个MAPX的消息响应过程来(以DrawUserLayer事件为例),如下:

 1   afx_msg void OnDrawUserLayerMap1 (LPDISPATCH Layer, long hOutputDC, long hAttributeDC, LPDISPATCH RectFull, LPDISPATCH RectInvalid);  
 2     //H文件中函数定义
 3     DECLARE_EVENTSINK_MAP()   //H文件中宏声明
 4     BEGIN_EVENTSINK_MAP (C**View, CView)
 5     //{{AFX_EVENTSINK_MAP(CMeteoCenView)
 6     ON_EVENT (C**View, IDS_MAP1, 10 /* DrawUserLayer */, OnDrawUserLayerMap1, VTS_DISPATCH VTS_I4 VTS_I4 VTS_DISPATCH VTS_DISPATCH)    
 7     //CPP文件中消息映射
 8     //}}AFX_EVENTSINK_MAP
 9     END_EVENTSINK_MAP ()
10     void C**View::OnDrawUserLayerMap1 (LPDISPATCH Layer, long hOutputDC, long hAttributeDC, LPDISPATCH RectFull, LPDISPATCH RectInvalid)
11     //CPP文件中函数实现
12     {
13     }

    上面的老虎(MAPX控件)画好了,只要按照猫(菜单)的样子把各个代码分别分配到相应的位置就可以完成MAPX控件的事件响应了。

    主要解释一下下面这段代码的含义:

1 ON_EVENT (C**View, IDS_MAP1, 10 /* DrawUserLayer */, OnDrawUserLayerMap1, VTS_DISPATCH VTS_I4 VTS_I4 VTS_DISPATCH VTS_DISPATCH)

    C**View:是MapX所在的View类。

    IDS_MAP1:是为MapX添加的窗体ID

    10 /* DrawUserLayer */:是MapX的事件代码,10表示的是DrawUserLayer事件。

    OnDrawUserLayerMap1:是DrawUserLayer事件的处理函数

    VTS_DISPATCH VTS_I4 VTS_I4 VTS_DISPATCH VTS_DISPATCH:这些是DrawUserLayer所携带的参数类型说明。

    整个这段代码的意思可以这样表述:

    当C**View接收到以IDS_MAP1标示的MapX窗体的DrawUserLayer(代码为10)事件时将通过OnDrawUserLayerMap1来处理这个事件。

    在Doc/View类型工程下使用MapX时我一般的做法是:建立一个Dialog的MAPX标准工程,使用ClassWizard给MAPX添加上所有 的事件响应。然后,当我在Doc/View类型工程下需要的时候,我就去Dialog工程中所需要的事件响应过程考过去,改改ID和类名什么的就可以用 了。

四、现有工程如果转到标准工程

    1.直接在文件视图中删除所有添加的以“C”打头的MAPX的.h和.cpp文件。

    2.删除工程目录下的所有自动生成的以“C”打头的MAPX的.h和.cpp文件。

    3.在整个工程中搜索”#include”,只要是还有上面这些文件的引用全部删除。

    4. 从MapX控件安装目录MapInfo\MapX 5.0\Samples50\C++\Cpp下找到MAPX.H和MAPX.CPP两个文件拷贝到工程目录下,并添加到工程当中去。

    5.在StdAfx.h文件中添加#include MAPX.H

    6.编译工程(肯定还有很多错误,一个一个往下找),将以前使用COleVariant或Variant类型以及其他不相符数据类型的地方改正过来,以前使用两个"C"打头的类换成一个"C"打头的类。(要细心,磨刀不费砍柴工!)

五、其他VC环境

    VC.net(VS2003/VS2005/VS2008)环境下MAPX的环境建立与本文所提到的方法与步骤基本相同,可以很顺利的移植过去。

六、简单对比(MapXLayer::SearchAtPoint函数)

    使用控件自动生成的文件时:SearchAtPoint第二个参数是一个VARIANT类型

1    CCMapXFeatures CCMapXLayer::SearchAtPoint(LPDISPATCH Point, const VARIANT& SearchResultFlags)        
2         LPDISPATCH pDispatch;
3         static BYTE parms[] =
4         VTS_DISPATCH VTS_VARIANT;
5         InvokeHelper(0x1d, DISPATCH_METHOD, VT_DISPATCH, (void*)&pDispatch, parms,
6         Point, &SearchResultFlags);
7         return CCMapXFeatures(pDispatch);
8         }     

    使用MAPX安装目录下Demo中提供的MAPX.H和MAPX.CPP时:SearchAtPoint第二个参数是一个short类型

1    CMapXFeatures CMapXLayer::SearchAtPoint(LPDISPATCH Point, short SearchResultFlags)        
2        LPDISPATCH result;
3         static BYTE parms[] =
4         VTS_DISPATCH VTS_I2;
5         InvokeHelper(0x1d, DISPATCH_METHOD, VT_DISPATCH, (void*)&result, parms,
6         Point, SearchResultFlags);
7         return CMapXFeatures(result);
8         } 

 原文地址:http://blog.csdn.net/Tinary3v0/article/details/3321610

 

 

转载于:https://www.cnblogs.com/junlei/p/3635756.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值