AE学习笔记之右键菜单的添加与实现
2016-10-11 14:46
645 查看
ArcGIS Engine 中自定义了一些添加命令、工具和菜单的基类,在需要写相应函数的时候可以直接很方便的添加。
我在前面的文章里面有一节讲述过如何添加控件命令:http://blog.csdn.net/my_lord_/article/details/52599153 。本节讲述一下右键菜单的实现,右键菜单也就是单击鼠标右键时弹出的一个菜单项。主体也就是新建一个IToolbarMenu m_MenuMap 接口,将自定义的命令添加进去,最后在鼠标右键的响应函数中弹出即可。具体流程与代码如下:
1、添加变量,在Form1的类中。
2、添加命令函数。
命令函数的具体添加过程就不再这里复述了,不太清楚地可以翻一下我前面的文章。这里贴上一些代码:
ZoomToLayer 命令:
RemoveLayer 命令:
LayerVisibility 命令:
这个里面做了几个处理,在这里描述一下:首先,这个命令的作用就是如果SubType为1时,设置Caption为Turn All Layer On ,2的话就是Turn All Layer Off就是打开图层和关闭图层。
其中,caption名字的变化是定义了一个Caption属性来修改。SubType值是通过在m_MenuMap.AddItem时根据第二个参数来定义。具体的细节我也不太懂,以后弄明白了再补充。
在这里在讲述一下IHOOKHelper接口:
IHookHelper 主要在用在自定义类型于AE带的的ICommand或ITool等,
1.实例化IHookHelper 对象:
IHookHelper m_hookHelper = new HookHelperClass();
m_hookHelper.Hook = this.axMapControl1.Object ;这样就可以把AxMapControl传递给其它要用到的地方。
2.通过IHookHelper,获取地图控件和主窗体:
IntPtr pHandle = new IntPtr (m_hookHelper.ActiveView.ScreenDisplay.hWnd);
axMapControl1 = System.Windows.Forms.Form.FromHandle(pHandle) as AxMapControl;//对这个地图控件对象操作,会直接反应到主窗体的地图控件上
Form. MainForm. = Form.FromHandle(pHandle).FindForm();//这里的主窗体对象之后运行时能起作用,MainForm. 不能直接访问到主窗体里的变量。
3.通过IHookHelper,获取IActiveView和IMap对象
再通过IHookHelper.ActiveView和IHookHelper.FocusMap属性来获取IActiveView和IMap对象,通过这两个接口进行更一步的操作.
4.通过IHookHelper,操作地图
IHookActions hookActions= m_hookHelper as IHookHelper;
获取IHookActions,再通过IHookActions进行Flash,Pan,ZoomTo操作.
HOOK实际是一个对象传出的自身的引用或者叫指针或者叫句柄。
例如一个程序,加载一个dll内的对象时通过把Hook传递给要调用的对象,
这样dll内的对象就得到了应用程序传递给他的这个hook,
对象可以通过这个hook查看程序内部的结构。
实际实现时就是对象间传递指向自身的指针传递给另一个对象。
IHookHelper m_hookHelper=new HookHelperClass();
m_hookHelper.Hook=axMapControl1.Object;
//这样就获得了axMapControl1控件的一个引用
然后通过m_hookHelper.ActiveView可以获得原axMapControl1的ActiveView项,
用m_hookHelper.FocusMap可以获得IMap对象
三、在Form1的Lord响应函数中初始化图层菜单,这一步在鼠标右键的响应函数中做初始化也一样。先后问题而已。
在最后一步中设置菜单Hook的时候是对菜单中所有添加的项进行设置,当然也可以自己调用每个命令的Oncreat进行传递Hook。代码如下:
ICommand m_Command=new ControlsMapZoomInToolClass();//自带的一个放大功能的类
m_Command。OnCreate(m_mapControl.Object);
m_mapCiontrol.CurrentTool=(ITool)m_Command;//对于需要点击的命令响应OnClick()。
四、鼠标右键响应函数
这里有一个不太明白的地方:
//设置CustomProperty为layer (用于自定义的Layer命令)
m_mapControl.CustomProperty = layer;
这一句不太懂。
运行结果:
附录:axTOCControl.HitTest方法介绍
public void HitTest ( int X, int Y, ref esriTOCControlItem ItemType, ref IBasicMap BasicMap, ref ILayer Layer, ref object Unk, ref object Data );
各参数的含义如下:
X,Y :鼠标点击的坐标;
ITemType: esriTOCControlItem枚举常量
BasicMap:绑定MapControl的IBasicMap接口
Layer:被点击的图层
Unk:TOCControl的LegendGroup对象
Data:LegendClass在LegendGroup中的Index。
esriTOCControlItem枚举常量用于描述TocControl上的Item的类型,其定义如下:
esriTOCControlItemNone 0 没有对象
esriTOCControlItemMap 1 Map对象
esriTOCControlItemLayer 2 Layer对象
esriTOCControlItemHeading 3 对象的标题
esriTOCControlItemLegendClass 4 LegendClass对象
----------------------------------------------------------end---------------------------------------------------
我在前面的文章里面有一节讲述过如何添加控件命令:http://blog.csdn.net/my_lord_/article/details/52599153 。本节讲述一下右键菜单的实现,右键菜单也就是单击鼠标右键时弹出的一个菜单项。主体也就是新建一个IToolbarMenu m_MenuMap 接口,将自定义的命令添加进去,最后在鼠标右键的响应函数中弹出即可。具体流程与代码如下:
1、添加变量,在Form1的类中。
#region Right Button Menu Class Memble //TOCControl控件变量 private ITOCControl2 m_TocControl = null; //TOCControl中Map菜单 private IToolbarMenu m_MenuMap = null; //TOCControl中图层菜单 private IToolbarMenu m_MenuLayer = null; #endregion
2、添加命令函数。
命令函数的具体添加过程就不再这里复述了,不太清楚地可以翻一下我前面的文章。这里贴上一些代码:
ZoomToLayer 命令:
/// <summary> /// 放大至整个图层 /// </summary> public sealed class ZoomToLayer : BaseCommand { private IMapControl3 m_mapControl; public ZoomToLayer() { base.m_caption = "Zoom To Layer"; } public override void OnClick() { ILayer layer = (ILayer)m_mapControl.CustomProperty; m_mapControl.Extent = layer.AreaOfInterest; } public override void OnCreate(object hook) { m_mapControl = (IMapControl3)hook; } }
RemoveLayer 命令:
/// <summary> /// 删除图层 /// </summary> public sealed class RemoveLayer : BaseCommand { private IMapControl3 m_mapControl; public RemoveLayer() { base.m_caption = "Remove Layer"; } public override void OnClick() { ILayer layer = (ILayer)m_mapControl.CustomProperty; m_mapControl.Map.DeleteLayer(layer); } public override void OnCreate(object hook) { m_mapControl = (IMapControl3)hook; } }
LayerVisibility 命令:
/// <summary> /// 图层可视控制 /// </summary> public sealed class LayerVisibility : BaseCommand, ICommandSubType { private IHookHelper m_hookHelper = new HookHelperClass(); private long m_subType; public LayerVisibility() { } public override void OnClick() { for (int i = 0; i <= m_hookHelper.FocusMap.LayerCount - 1; i++) { if (m_subType == 1) m_hookHelper.FocusMap.get_Layer(i).Visible = true; if (m_subType == 2) m_hookHelper.FocusMap.get_Layer(i).Visible = false; } m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null); } public override void OnCreate(object hook) { m_hookHelper.Hook = hook; } public int GetCount() { return 2; } public void SetSubType(int SubType) { m_subType = SubType; } public override string Caption { get { if (m_subType == 1) return "Turn All Layers On"; else return "Turn All Layers Off"; } } public override bool Enabled { get { bool enabled = false; int i; if (m_subType == 1) { for (i = 0; i <= m_hookHelper.FocusMap.LayerCount - 1; i++) { if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == false) { enabled = true; break; } } } else { for (i = 0; i <= m_hookHelper.FocusMap.LayerCount - 1; i++) { if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == true) { enabled = true; break; } } } return enabled; } } }
这个里面做了几个处理,在这里描述一下:首先,这个命令的作用就是如果SubType为1时,设置Caption为Turn All Layer On ,2的话就是Turn All Layer Off就是打开图层和关闭图层。
其中,caption名字的变化是定义了一个Caption属性来修改。SubType值是通过在m_MenuMap.AddItem时根据第二个参数来定义。具体的细节我也不太懂,以后弄明白了再补充。
在这里在讲述一下IHOOKHelper接口:
IHookHelper 主要在用在自定义类型于AE带的的ICommand或ITool等,
1.实例化IHookHelper 对象:
IHookHelper m_hookHelper = new HookHelperClass();
m_hookHelper.Hook = this.axMapControl1.Object ;这样就可以把AxMapControl传递给其它要用到的地方。
2.通过IHookHelper,获取地图控件和主窗体:
IntPtr pHandle = new IntPtr (m_hookHelper.ActiveView.ScreenDisplay.hWnd);
axMapControl1 = System.Windows.Forms.Form.FromHandle(pHandle) as AxMapControl;//对这个地图控件对象操作,会直接反应到主窗体的地图控件上
Form. MainForm. = Form.FromHandle(pHandle).FindForm();//这里的主窗体对象之后运行时能起作用,MainForm. 不能直接访问到主窗体里的变量。
3.通过IHookHelper,获取IActiveView和IMap对象
再通过IHookHelper.ActiveView和IHookHelper.FocusMap属性来获取IActiveView和IMap对象,通过这两个接口进行更一步的操作.
4.通过IHookHelper,操作地图
IHookActions hookActions= m_hookHelper as IHookHelper;
获取IHookActions,再通过IHookActions进行Flash,Pan,ZoomTo操作.
HOOK实际是一个对象传出的自身的引用或者叫指针或者叫句柄。
例如一个程序,加载一个dll内的对象时通过把Hook传递给要调用的对象,
这样dll内的对象就得到了应用程序传递给他的这个hook,
对象可以通过这个hook查看程序内部的结构。
实际实现时就是对象间传递指向自身的指针传递给另一个对象。
IHookHelper m_hookHelper=new HookHelperClass();
m_hookHelper.Hook=axMapControl1.Object;
//这样就获得了axMapControl1控件的一个引用
然后通过m_hookHelper.ActiveView可以获得原axMapControl1的ActiveView项,
用m_hookHelper.FocusMap可以获得IMap对象
三、在Form1的Lord响应函数中初始化图层菜单,这一步在鼠标右键的响应函数中做初始化也一样。先后问题而已。
//右键菜单项的初始化 m_MenuMap = new ESRI.ArcGIS.Controls.ToolbarMenuClass(); m_MenuLayer = new ESRI.ArcGIS.Controls.ToolbarMenuClass(); m_TocControl = (ITOCControl2)this.axTOCControl1.Object; //添加自定义菜单项到TOCCOntrol的Map菜单中 //打开文档菜单 m_MenuMap.AddItem(new OpenNewMapDocument(m_controlsSynchronizer), -1, 0, false, esriCommandStyles.esriCommandStyleIconAndText); //添加数据菜单 m_MenuMap.AddItem(new ControlsAddDataCommandClass(), -1, 1, false, esriCommandStyles.esriCommandStyleIconAndText); //打开全部图层菜单 m_MenuMap.AddItem(new LayerVisibility(), 1, 2, false, esriCommandStyles.esriCommandStyleTextOnly); //关闭全部图层菜单 m_MenuMap.AddItem(new LayerVisibility(), 2, 3, false, esriCommandStyles.esriCommandStyleTextOnly); //以二级菜单的形式添加内置的“选择”菜单 m_MenuMap.AddSubMenu("esriControls.ControlsFeatureSelectionMenu", 4, true); //以二级菜单的形式添加内置的“地图浏览”菜单 m_MenuMap.AddSubMenu("esriControls.ControlsMapViewMenu", 5, true); //添加自定义菜单项到TOCCOntrol的图层菜单中 m_MenuLayer = new ToolbarMenuClass(); //添加“移除图层”菜单项 m_MenuLayer.AddItem(new RemoveLayer(), -1, 0, false, esriCommandStyles.esriCommandStyleTextOnly); //添加“放大到整个图层”菜单项 m_MenuLayer.AddItem(new ZoomToLayer(), -1, 1, true, esriCommandStyles.esriCommandStyleTextOnly); //设置菜单的Hook m_MenuLayer.SetHook(m_mapControl); m_MenuMap.SetHook(m_mapControl); //右键菜单项的初始化--end
在最后一步中设置菜单Hook的时候是对菜单中所有添加的项进行设置,当然也可以自己调用每个命令的Oncreat进行传递Hook。代码如下:
ICommand m_Command=new ControlsMapZoomInToolClass();//自带的一个放大功能的类
m_Command。OnCreate(m_mapControl.Object);
m_mapCiontrol.CurrentTool=(ITool)m_Command;//对于需要点击的命令响应OnClick()。
四、鼠标右键响应函数
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) { //如果不是右键按下直接返回 if (e.button != 2) return; esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone; IBasicMap map = null; ILayer layer = null; object other = null; object index = null; //判断所选菜单的类型 m_TocControl.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index); //确定选定的菜单类型,Map或是图层菜单 if (item == esriTOCControlItem.esriTOCControlItemMap) m_TocControl.SelectItem(map, null); else m_TocControl.SelectItem(layer, null); m_MenuLayer.SetHook(m_mapControl); m_MenuMap.SetHook(m_mapControl); //设置CustomProperty为layer (用于自定义的Layer命令) m_mapControl.CustomProperty = layer; //弹出右键菜单 if (item == esriTOCControlItem.esriTOCControlItemMap) m_MenuMap.PopupMenu(e.x, e.y, m_TocControl.hWnd); if (item == esriTOCControlItem.esriTOCControlItemLayer) m_MenuLayer.PopupMenu(e.x, e.y, m_TocControl.hWnd); } }
这里有一个不太明白的地方:
//设置CustomProperty为layer (用于自定义的Layer命令)
m_mapControl.CustomProperty = layer;
这一句不太懂。
运行结果:
附录:axTOCControl.HitTest方法介绍
public void HitTest ( int X, int Y, ref esriTOCControlItem ItemType, ref IBasicMap BasicMap, ref ILayer Layer, ref object Unk, ref object Data );
各参数的含义如下:
X,Y :鼠标点击的坐标;
ITemType: esriTOCControlItem枚举常量
BasicMap:绑定MapControl的IBasicMap接口
Layer:被点击的图层
Unk:TOCControl的LegendGroup对象
Data:LegendClass在LegendGroup中的Index。
esriTOCControlItem枚举常量用于描述TocControl上的Item的类型,其定义如下:
esriTOCControlItemNone 0 没有对象
esriTOCControlItemMap 1 Map对象
esriTOCControlItemLayer 2 Layer对象
esriTOCControlItemHeading 3 对象的标题
esriTOCControlItemLegendClass 4 LegendClass对象
----------------------------------------------------------end---------------------------------------------------
相关文章推荐
- Linux学习笔记-Ubuntu添加右键菜单打开终端
- MFC学习笔记.day03-菜单,图形标记菜单创建,菜单栏禁用,命令响应,右键弹出菜单,添加菜单
- 【ext js 学习笔记】GridPanel 右键显示菜单的制作
- 为jQuery.Treeview添加右键菜单的实现代码
- lua学习笔记 2 android调用Lua。Lua脚本中实现添加Button,并为Button增加Listener
- TWaver HTML5学习笔记 —— 可定制的右键菜单
- JQuery学习笔记之实现菜单的下拉
- 实现Windows下的右键菜单添加
- sql语句学习笔记(8)-添加约束,实现数据完整性
- javascript dom 学习笔记 第九章:实现给某个元素添加加新的class的值的函数!
- iOS学习笔记44——实现滑动菜单SlidingMenu
- 《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现
- Hadoop学习笔记(二)--添加data节点和实现远程挂载HDFS
- chrome扩展学习 右键菜单实现代码
- Qt 学习(6)在QT中添加右键菜单
- JTree右键菜单实现编辑、添加、删除节点
- 为jQuery.Treeview添加右键菜单的实现代码
- Ferris教程学习笔记:js示例5.7 自定义右键菜单,请在页面点击右键查看效果。
- chrome扩展学习 右键菜单实现代码
- 用VB脚本实现向右键菜单添加快捷方式