用VC++对MapX进行二次开发总结(二)(
3.MapX在VC++ 环境下GIS基本功能的实现
在进行MapX 开发之前,确保已经在计算机中正确的安装了MapX 控件。下面就用一个具体的实例,介绍在VC+ +中集成MapX 的方法。
3.1 将MapX支持类库加入工程
在您的项目中包括MapX.cpp和.h文件。这两个文件包含用于对MapX控件进行访问的类定义和方法实现。MapX.h 和 MapX.cpp 文件可能位于安装有 MapX 的 Samples50CPP 子目录中(如果您安装的事MapX 4.0,则路径为 … Samples40C++Cpp)。
利用VC++ 环境下的应用程序生成向导创建一单文档应用程序MapSample。将MapX.h和MapX.cpp文件拷贝到当前工程路径下,然后从Project菜单中选择Add to Project >Files命令,此时打开Insert Files into Project对话框,选择MapSample文件夹下的MapX.h和MapX〉cpp文件加入到工程中。
警告:不要选择Project菜单中的Add to Project > Components And Controls命令。这样做将会创建一个.cpp文件,但该文件将是不完整的。我一开始就是这么做的,结果很多常用函数都没有,郁闷了我很长时间。希望大家一起要切记这一点。
3.2 使用VC++创建MapX控件
在将包含该控件得视图中包括它:
#include “MapX.h”
:
:
:
Class CMapXSampleView : public CView
{
:
:
:
Protected:
CMapX m_ctrlMapX;
:
:
}
要声明表示用于MapX的控件ID的常数:
(1)选择“View”>”Resource Symble”。
(2)单击“New”。
(3)键入“IDC_MAP”来作为名称。
要在类向导中为WM_SIZE和WM_CREATE消息创建处理程序:
(1)转入”View”>”ClassWizard”;
(2)从“Class Name”组合框中选择您的视图类。
(3)在“Messages”列表框中,单击“WM_CREATE”,然后单击“Add Function”。
(4)接着还在该消息框中选择” WM_SIZE”并单击“Add Function”。
(5)然后,单击“Edit Code”
在创建视图时创建该控件。在CMapXSampleView::OnCreate中:
//create map with default size
//resize message will cause it to be size to the client area of the view
If(!m_ctrlMapX.Create(NULL,WS_VISIBLE, CRect(0,0,100,100),this,IDC_MAP))
Returen -1;
Keep the control’s size in sync with the containing window;
//resize the map to be the same size as our client area
Void CMapXSampleView:: OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if(cx!=0 && cy!=0)
m_ctrlMapX.MoveWindow(0,0,cx,cy);
}
像您为WM_CREATE消息所作的一样为WM_SETFOCUS消息创建新消息标头。
在我们的示例中,我们想要确保只要窗口被激活MapX就获得焦点:
void CMapXSampleView::OnSetFocus(CWnd* pOldWnd)
{
CView::OnSetFocus(pOldWnd);
m_ctrlMapX.SetFocus();
}
3.3 使用地图标准工具
在地图显示出来后,用户通常要以各种比例查看地图的全局、局部或细部,必须提供诸如放大、缩小和漫游等功能。采用MapX通用工具,可以非常方便地实现上述功能。设定MapX使用标准工具的方法很简单,只需设定地图对象的CurrentTool属性。下面的例子是用标准放大工具实现放大功能。
添加新菜单项资源,输入标题“工具”,在“工具”下添加子菜单,输入标题“放大”及ID 为ID_ZOOM_ IN。打开类向导,选择视图类CMapXSampleView,为菜单项ID_ZOOM_IN 添加COMMAND 消息映射函数OnZoomIn ( ),并编辑码如下。
void CMapXSampleView::OnZoomIn()
{
m_ctrlMapX.SetCurrentTool(miZoomInTool);// miZoomInTool为放大工具常量
}
编译运行程序,选择“工具|放大”,就会看到此时光标变为放大镜,单击鼠标就会实现放大功能。可用相同方法实现其他标准工具的功能。MapX提供的可用标准工具如下表。
工具 |
常数 |
说明 |
添加线条 |
miAddLineTool |
将线条图元添加到插入图层中。 |
添加点 |
miAddPointTool |
单击该工具可将点图元添加到插入图层中。 |
添加折线 |
miAddPolyLineTool |
将折线图元添加到插入图层中。 |
添加区域 |
miAddRegionTool |
将区域图元添加到插入图层中。 |
箭头 |
miArrowTool |
单击标题或注释此外,在可编辑图层中移动选定图元或调整选定图元的大小。 |
居中 |
miCenterTool |
单击该工具可以重新将地图居中。 |
加标签 |
miLabelTool |
在一个图元上单击可以给该图元加标签。 |
平移 |
miPanTool |
拖动该工具可以重新将地图居中。 |
多边形选择 |
miPolygonSelectTool |
单击该工具可以绘制一个多边形;该多边形内的对象将被选定。 |
半径选择 |
miRadiusSelectTool |
拖动该工具可以选择半径内的图元。 |
矩形选择 |
miRectSelectTool |
拖动该工具可以选择矩形内的图元。 |
选择工具 |
miSelectTool |
单击该工具可以选择图元。 |
符号 |
miSymbolTool |
放置符号注释。 |
文本 |
miTextTool |
放置文本注释。 |
放大 |
miZoomInTool |
放大。 |
缩小 |
miZoomOutTool |
缩小。 |
3.4 使用自定义工具
MapX提供的地图标准工具能满足一般需要,但在一些特殊地方,用户可能需要某种特殊工具来完成某些特定的地图操作功能。因此,MapX提供了用户自定义工具的方法,这样可以大大扩展MapX的应用范围。开发者可使用地图对象的CreateCustomTool 方法创建自定义工具。一旦您已使用CreateCustomTool方法创建了定制工具后,就可以在用户使用定制工具时使用ToolUsed事件执行操作。
此示例进行测试以了解正使用哪一工具。然后,根据正在使用的工具,该示例或者:
• 更改光标下的地图图元的样式,或者
• 在用户单击处放置新符号。
void CMapXSampleView::OnToolUsed(short ToolNum, double X1, double Y1, double X2, double Y2, double Distance,BOOL Shift, BOOL Ctrl, BOOL* EnableDefault)
{
CString str;
CMapXPoint pnt;
str.Format("Tool=%d, [%f,%f] [%f, %f], dist=%f, %s %sn",
ToolNum, X1,Y1,X2,Y2,Distance,
(Shift)?"Shift":"",(Ctrl)?"Ctrl":"");
TRACE(str);
// change the style of the feature under the cursor
if (ToolNum == MAP_TOOL_CHANGESTYLE) {
try {
// Need the dispatch to use the point
if (pnt.CreateDispatch(pnt.GetClsid())) {
pnt.Set(X1, Y1);
}
else {
// something went wrong, can't use the point...
AfxThrowOleException(CO_E_CLASS_CREATE_FAILED);
}
CMapXLayers layers = m_ctrlMapX.GetLayers();
// Get the USA feature under the cursor
CMapXFeatures ftrs =
layers.Item("USA").SearchAtPoint(LPDISPATCH(pnt));
// work on only the first feature
CMapXFeatureftr = ftrs.Item(1);
// get the style object from the feature
CMapXStylestyle = ftr.GetStyle();
style.SetRegionBackColor(255);
// update the feature in the layer
ftr.Update();
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
// place a new symbol at the point clicked on
else if (ToolNum == MAP_TOOL_NEWPOINT) {
try {
CMapXLayers layers = m_ctrlMapX.GetLayers();
CMapXFeatureftr;
// Need the dispatch id to use the feature
if (ftr.CreateDispatch(ftr.GetClsid())) {
// Symbol feature
ftr.SetType(miFeatureTypeSymbol);
// Get the point object from the feature
// and call the Set method
ftr.GetPoint().Set(X1, Y1);
// Add it to the layer
layers.Item("USA").AddFeature(ftr);
}
else {
AfxThrowOleException(CO_E_CLASS_CREATE_FAILED);
}
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
}
3.5 处理MapX事件
若要处理MapX事件,您首先需要为感兴趣的事件建立eventsink地图。用于事件DISPATCH id 的常数是在MapX.h中为MapX定制事件定义的,并且是在中为 OLE 普通事件定义的。
// From MapX.h
#define MAPX_DISPID_SELECTION_CHANGED 0x1
#define MAPX_DISPID_RESOLVEDATABIND 0x2
#define MAPX_DISPID_TOOLUSED 0x3
#define MAPX_DISPID_REQUESTDATA 0x4
#define MAPX_DISPID_DATAMISMATCH 0x5
#define MAPX_DISPID_MAPVIEWCHANGED 0x6
#define MAPX_DISPID_ANNOTATIONADDED 0x7
#define MAPX_DISPID_ANNOTATIONCHANGED 0x8
#define MAPX_DISPID_THEMEMODIFYREQUESTED 0x9
#define MAPX_DISPID_DRAWUSERLAYER 0x0a
#define MAPX_DISPID_POLYTOOLUSED 0x0b
// From
#define DISPID_CLICK (-600)
#define DISPID_DBLCLICK (-601)
#define DISPID_KEYDOWN (-602)
#define DISPID_KEYPRESS (-603)
#define DISPID_KEYUP (-604)
#define DISPID_MOUSEDOWN (-605)
#define DISPID_MOUSEMOVE (-606)
#define DISPID_MOUSEUP (-607)
#define DISPID_ERROREVENT (-608)
EVENT_SINK中的ON_EVENT 宏也为MapX控件指定一个ID (在该示例中为 IDC_MAP),指定该事件的参数,并且指定事件处理程序方法的名称。
在视图标头文件MapXSampView.h中,将“DECLARE_EVENTSINK_MAP ()”一行放置于“DECLARE_MESSAGE_MAP”行之下。
从CMapXSampleView.cpp:
BEGIN_EVENTSINK_MAP(CMapXSampleView, CView)
ON_EVENT(CMapXSampleView, IDC_MAP, DISPID_MOUSEMOVE,
OnMouseMoveInMap,VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS)
ON_EVENT(CMapXSampleView, IDC_MAP, MAPX_DISPID_MAPVIEWCHANGED,
OnMapViewChanged, VTS_NONE)
ON_EVENT(CMapXSampleView, IDC_MAP, DISPID_MOUSEUP,
OnMouseUpInMap, VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS)
ON_EVENT(CMapXSampleView, IDC_MAP, MAPX_DISPID_TOOLUSED,
OnToolUsed, VTS_I2 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_BOOL
VTS_BOOL VTS_PBOOL)
ON_EVENT(CMapXSampleView, IDC_MAP,
MAPX_DISPID_THEMEMODIFYREQUESTED, OnThemeModifyRequested,
VTS_DISPATCH)
END_EVENTSINK_MAP()
随后是用于OnToolUsed 事件的事件处理程序代码。来自CMapXSampleView.h 的声明:
void OnToolUsed(short ToolNum, double X1, double Y1, double X2,double Y2, double
Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault);
…以及来自CMapXSampleView.cpp 的实现方式(我们只使用 TRACE 宏将参数输出到调试窗口):
void CMapxSampleView::OnToolUsed(short ToolNum, double X1, double Y1,
double X2, double Y2, double Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault)
{
CString str;
str.Format("Tool=%d, [%f,%f] [%f, %f], dist=%f, %s %sn",ToolNum, X1,Y1,X2,Y2,Distance,
(Shift)?"Shift":"",(Ctrl)?"Ctrl":"");
TRACE(str);
}
3.6 添加快捷菜单
DISPID_MOUSEUP事件可用于添加快捷(鼠标右键按钮)菜单。为您的快捷菜单创建菜单资源(如果菜单资源的ID为IDR_CONTEXTMENU)。OnMouseUpInMap 处理程序类似于以下代码:
// if right mouse button, display the context menu
BOOL CMapxSampleView::OnMouseUpInMap(short Button, short Shift,
OLE_XPOS_PIXELS x,OLE_YPOS_PIXELS y)
{
if (Button == 2) { // right button
CMenu menu; // top-level menu
CMenu *pMenu=NULL; // pop-up menu
// Load the menu resource.
menu.LoadMenu(IDR_CONTEXTMENU);
// TrackPopupMenu cannot display the top-level menu, so get
// the handle of the first pop-up menu.
pMenu = menu.GetSubMenu(0);
if (!pMenu) {
return TRUE;
}
SetMenuDefaultItem(pMenu->m_hMenu, ID_VIEW_PROPERTIES,
FALSE);
// Display the floating pop-up menu. Track the right mouse
// button on the assumption that this function is called
// during WM_CONTEXTMENU processing.
POINT pt;
GetCursorPos(&pt);
pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
pt.x, pt.y, this, NULL);
// Destroy the menu.
menu.DestroyMenu();
}
return TRUE;
}
3.7 MapX异常错误处理
MapX通过报告(引发)COleDispatchException 来报告大多数错误。在调用 MapX 时捕获异常错误是十分重要的,因为MFC的默认异常错误处理程序不捕获它们并且您的应用程序将退出。在消息框中显示对错误的说明也是非常有用的。错误消息的文本将帮助您确定是否正确使用了 MapX 图元,或者是否已发生某一其它问题。
COleDispatchException类还在公共成员m_wCode中包括错误代码,以便您的程序可以标识和处理不同类型的错误。对于错误代码及其说明的列表,请参见联机帮助中的 MapX 错误代码。
如果在尝试调用MapX时具有一般的OLE错误(在您使用过时的MapX.h 或 MapX.cpp 版本时可能发生),则 MFC 将引发 COleException。建议你在调用 MapX 时捕获全部两个异常错误类型。
MapX 也可能在 Error 事件中传递错误(尽管非常少见)。只有在不从MapX属性或方法直接调用的异步处理(像redraw)期间出现某种类型的错误时,才可能发生上述情况。
在此示例的 ThemeModifyRequested 事件的事件处理程序中,我们显示普通的“主题”属性对话框以让用户更改主题颜色等。请注意异常错误处理的方式。
// Note: in objects passed to events, the event handler
// does not change the reference count
// ie: do not call release on the object
void CMapxSampleView::OnThemeModifyRequested(LPDISPATCH Theme)
{
try {
CMapXTheme theme;
COptionalVariant vHelpFile, vHelpID;
// mark as optional since we don't have a helpfile
theme.AttachDispatch(Theme, FALSE); // don't auto release
theme.ThemeDlg(vHelpFile, vHelpID);
// could decide to bring up legend dlg here instead
//CMapXLegend leg(theme.GetLegend());
//leg.LegendDlg(vHelpFile, vHelpID);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
用VC++对MapX进行二次开发总结(二)(相关推荐
- 微信商城开源版二次开发(二)
微信商城开源版二次开发(二) 最近想了解如何Java对接微信平台,快速搭建完整项目开发,发现网上有很对开源的这类二开源码.https://gitee.com/luozijing123/JooLun-w ...
- Firefox ios 火狐浏览器iOS版本二次开发(二)
Firefox ios 火狐浏览器iOS版本二次开发(二) 编译 Firefox ios源代码下载地址: Firefox CSDN下载地址 Firefox ios版本采用的是swift语言来进行开发的 ...
- pythoncad二次开发视频_revit二次开发|bim软件二次开发|revit二次开发教程|Revit二次开发技术文档...
二次开发 revit二次开发|bim软件二次开发|revit二次开发教程|Revit二次开发技术文档2019-07-08赞( 0 ) 记录一下CAD二次开发的一些简单实例. 1.helloworld ...
- ug二次开发python_NXOpen二次开发.pdf
NXOpen二次开发 NXOpen 二次开发 二○一三年十二月 目 录 第一章 NXOpen 简介1 1.1 NX API 简介1 1.1.1 NX API 架构与统一对象模型1 1.1.2 现有 N ...
- ProE二次开发 Creo二次开发 MCADEx Tools 免费工具QQ群 156242985
ProE二次开发 Creo二次开发 MCADEx Tools 免费工具QQ群 156242985 转载于:https://www.cnblogs.com/esdtech/p/4199884.html
- arcgis二次开发python-ArcGIS 二次开发专题 序
依据ArcGIS 组件式开发及应用的目录结构,将系统性的学习ArcGIS 二次开发的道路分为三个部分.这个系列包含以下三个部分: Part1 基础 1. 前言 1.1 组件式GIS 1.2 ArcOb ...
- 织梦二次开发写php,PHP教程—DedeCMS二次开发(二)
织梦内容管理系统(DedeCMS),是一个集内容发布.编辑.管理检索等于一体的网站管理系统(Web CMS),他拥有国外CMS众多特点之外,还结合中国用户的需要,对内容管理系统概念进行明确分析和定位. ...
- arcgis python实例_arcgis二次开发_arcgis二次开发python_arcgis二次开发实例
[1.rar] - QQ连连看的源码.单消秒杀挂机等功能喜欢的朋友请拿去研究 [qqCHAR.rar] - qq 验证码识别程序 可以叫准确的识别出qq登陆前的验证码 [1.rar] - 本书以Vis ...
- python二次开发odoo_odoo二次开发 - 战鹏的Blog - OSCHINA - 中文开源技术交流社区
#odoo Odoo 的前身是 OpenERP,是一个开源的企业 ERP 系统.odoo官网 通过官网可以看到odoo可以干很多事情,例如销售.CRM等等. #odoo文档 我们可以在odoo文档看到 ...
最新文章
- CVPR 2020论文开源项目一页看尽,附代码论文
- 解析PHP实现多进程并行执行脚本
- Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感 是印度上古时期一些文献的总称...
- leetcode 643. 子数组最大平均数 I(滑动窗口)
- php查询数据方法,php查询数据库的方法
- 网站服务器在境外境内怎么维护,涉黄网站服务器移至境外 境内维护人员将受制裁...
- 【渝粤教育】国家开放大学2019年春季 2610药剂学 参考试题
- 洛谷 P2383 狗哥玩木棒
- 使用easyos递归删除城通网盘的日志
- 计算机文档分段,Word文档如何快速分段
- wps怎么把当前页面设置为横向_wps单页面方向设置为横向的方法
- iOS依赖注入框架系列(一):介绍Typhoon
- Linux下Makefile的automake生成全攻略(转)
- 广州大学数据库实验三——数据库系统设计综合实验
- Kali Linux入门教程(非常详细)从零基础入门到精通,看完这一篇就够了。
- 【转】Unity3.5是一次较大的更新.它包含的新功能和改进会让你爱不释手.
- 高新技术企业的优惠政策有哪些
- 服务器虚拟化fc配置,设置虚拟化主机-连接-FC存储
- 数据插补—拉格朗日插值法
- openlayer3 系列 4 - 加载天地图
热门文章
- 谁在抢占「低代码」高地?
- 安卓10自带录屏_手机自带的录屏功能真是太强大了,完全秒杀第三方工具
- 计算机英语system,电脑英语Computer System 计算机系统
- 2048核心算法,数字移动合并检测
- java emr_java – EMR – 在Hadoop(和YARN)中使用自定义日志记录appender
- Linux入门(2)——Linux下的文件管理
- Vue2.5+Vue-cli3.0+Vue-router仿制京东金融前端页面
- u9过期老玉米挖掘软件V2版-过期域名采集软件-网址采集软件-域名采集软件-未注册域名检测软件-老域名采集工具
- springboot 大文件分片上传、断点续传和秒传
- 光模块的中心波长和传输距离