手动添加MapControl中的消息响应函数

    在利用ArcGIS二次开发实现“鹰眼”功能时发现在MapControl控件不能自动添加控件事件(OnMapReplacedOnExtentUpdated等)。咨询ESRI支持中心后给出的回答是:

“在ArcGIS 10.0之后对于MFC框架的支持出现了一些障碍,导致ArcGISEngine中的ActiveX控件无法注册。”

    既然这样那么我们就动手自己添加我们所需的响应函数。

    我的开发平台是:VS2010MFC+ArcGIS10.1

第一步:我们要得到事件响应函数的函数名、参数列表、以及控件给这个函数分配的ID

方法使使用VS带的开发工具OLE View,打开esriControls.olb,定位到IMapControlEvents2,我们就可以看到MapControl所有的事件响应函数:


 

下面我们要在*.h文件中加入事件响应函数的声明:

DECLARE_EVENTSINK_MAP()

void OnMouseDown( long button, long shift,  long X, long Y,double mapX, double mapY);

 

*.cpp文件中加入事件响应函数的定义:

void CMyGIS02View::OnMouseDown( long button, longshift,  long X, long Y,double mapX,double mapY)

{

//事件响应代码

}

重要的,我们要在*.cpp文件中添加事件接收响应

BEGIN_EVENTSINK_MAP(CMyGIS02View, CFormView)

ON_EVENT(CMyGIS02View, IDC_MAPCONTROL1,1,CMyGIS02View::OnMouseDown,VTS_I4 VTS_I4 VTS_I4 VTS_I4 VTS_R8 VTS_R8)

END_EVENTSINK_MAP()

注意BEGIN_EVENTSINK_MAPBEGIN_MESSAGE_MAP的区别,前者应用于COM组件的事件链接点的,后者应用于窗口的消息循环。

ON_EVENT( theClass,id, dispid, pfnHandler, vtsParams)

解释一下ON_EVENT中的第3个参数与第5个参数,

dispid

Thedispatch ID of the event fired by the control.

OLE VIEW中函数位于第一个位置,那么这里dispid=1

vtsParams

Asequence of VTS_ constants that specifiesthe types of the parameters for the event. These are the same constants thatare used in dispatch map entries such asDISP_FUNCTION.

一系列用来指定事件参数类型的VTS_常量。在MSDN中搜索EVENT_CUSTOM会得到VTS_常量与参数类型的对照表。其中:

VTS_I4

long

VTS_R8

double

 

这样我们就成功的添加了OnMouseDown()这个函数。

但是在添加OnMapReplaced()事件时却出现了问题,程序进入不到事件响应函数亦或进入事件响应函数后系统崩溃(内存读取错误,向空指针写入数据)

OLE VIEW中事件响应函数声明:

void OnMapReplaced(VARIANT newMap);

进过反复试验,错误原因在于类型为VARIANT的参数。在VTS_常量与参数类型的对照表中没有和VARIANT对应的常量(见下表),因此我们只能进行适当的变通。

VTS_VARIANT

const VARIANT*

VTS_PVARIANT

VARIANT*

具体做法如下:

BEGIN_EVENTSINK_MAP(CMyGIS02View, CFormView)

ON_EVENT(CMyGIS02View, IDC_MAPCONTROL1,15,CMyGIS02View::OnMapReplaced,VTS_VARIANT)

END_EVENTSINK_MAP()

 

void CMyGIS02View::OnMapReplaced(VARIANT*newMap)

{

//向鹰眼MapControl控件加载地图 [2/26/2014 pan]

m_MapControl2->LoadMxFile(CComBSTR("G:\\gis_ex09\\ex01\\ex01.mxd"));

}

要注意我们在事件接收响应中使用的是VTS_VARIANT常量,使用VTS_PVARIANT无法进入事件响应函数

OnMapReplaced的声明和定义中要把形参VARIANT newMap改为VARIANT*newMap,否则程序执行完事件响应后程序会崩溃

实际上无论事件响应函数中的参数列表怎么写,只要ON_EVENT中正确书写事件响应,那么程序都能顺利进入事件响应函数中,但是在执行完事件响应函数后会出现指针错误。

 

附半成品图:




在C#添加TabControl控件需要以下步骤: 1. 在窗体设计器,找到工具箱(Toolbox)窗口。 2. 在工具箱找到TabControl控件,可以通过拖拽方式将其放置在窗体上。 3. 在TabControl控件上右键单击,并选择“属性”(Properties)以打开属性窗口。 4. 在属性窗口,可以设置TabControl的各种属性,如名称(Name)、大小(Size)、位置(Location)等。 5. 可以在TabControl添加选项卡(TabPage)来展示不同的内容。在TabControl上右键单击,并选择“添加选项卡”(Add Tab)。 6. 为选项卡设置标题和内容。选项卡可以在窗体设计器进行编辑。 以下是一个简单示例,演示了如何在C#添加TabControl控件: ```csharp using System; using System.Windows.Forms; namespace TabControlExample { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void MainForm_Load(object sender, EventArgs e) { // 添加选项卡 TabPage tabPage1 = new TabPage("选项卡1"); TabPage tabPage2 = new TabPage("选项卡2"); TabPage tabPage3 = new TabPage("选项卡3"); // 设置选项卡的内容 tabPage1.Controls.Add(new Label() { Text = "这是选项卡1的内容" }); tabPage2.Controls.Add(new Label() { Text = "这是选项卡2的内容" }); tabPage3.Controls.Add(new Label() { Text = "这是选项卡3的内容" }); // 将选项卡添加到TabControl tabControl1.TabPages.Add(tabPage1); tabControl1.TabPages.Add(tabPage2); tabControl1.TabPages.Add(tabPage3); } } } ``` 在这个示例,我们在窗体加载事件动态创建了三个选项卡,并为每个选项卡添加了一个Label控件作为内容。然后将这些选项卡添加到TabControl控件。你可以根据自己的需求来设置选项卡的标题和内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值