本打算这次写缩小的,发现还得实现Itool和Icommend接口,真是麻烦啊!想到后面还有那么多的工具要写,每个都要实现这两个接口,要ctrl+c 和ctrl+V 多次,对于像我这样的懒人,一次也不想干。重新设计一下,增加个基类,在基类里实现这两个接口,所有的工具都继承这个基类,就OK了!
tool和command 的工作方式不同,tool是与地图有交互,command是没有,因此最好设计两个基类ToolBase和CommandBase,将二者分开。ToolBase的代码如下
1: ///2: /// CommBase 的摘要说明。3: ///4: public class ToolBase:BaseTool,IDisposable5: {
6: protected IHookHelper m_pHookHelper;7:
8: protected object m_pControl;9: protected IActiveView m_pActiveView;10: protected IMap m_pMap;11: ///12: /// 标示右键功能是否起作用13: ///14: protected bool m_showContextMenu = false;15: protected ContextMenu m_contextMenu;16:
17:
18: ///19: ///20: ///21: /// 工具名称22: public ToolBase(string str):base()23: {
24: m_pHookHelper=new HookHelperClass();25: InitialToolRes(str);
26: initContextMenu();
27: }
28:
29: ///30: ///31: ///32: /// 工具关联的地图控件33: ///34: public ToolBase(AxMapControl mapContrl, string str)35: :this(str)36: {
37: OnCreate(mapContrl.Object);
38: }
39:
40: ///41: ///42: ///43: /// 工具关联的地图控件44: ///45: public ToolBase(AxPageLayoutControl playoutCtl, string str)46: : this(str)47: {
48: OnCreate(playoutCtl.Object);
49: }
50:
51: public override void OnCreate(object hook)52: {
53: m_pHookHelper.Hook=hook;
54:
55: if (hook is Control)56: {
57: m_pControl = hook;
58: if (hook is AxMapControl)59: {
60: AxMapControl mapcontrl = hook as AxMapControl;61: m_pHookHelper.Hook = mapcontrl.Object;
62: }
63: else if (hook is AxPageLayoutControl)64: {
65: AxPageLayoutControl pagepcontrl = hook as AxPageLayoutControl;66: m_pHookHelper.Hook = pagepcontrl.Object;
67: }
68: }
69: else70: {
71: if (hook is IMapControlDefault)72: {
73: IMapControlDefault pMapDefault = hook as IMapControlDefault;74: m_pControl = Control.FromChildHandle(new IntPtr(pMapDefault.hWnd));75: m_pHookHelper.Hook = pMapDefault;
76: }
77: else if (hook is IPageLayoutControlDefault)78: {
79: IPageLayoutControlDefault pPageDefault = hook as IPageLayoutControlDefault;80: m_pControl = Control.FromChildHandle(new IntPtr(pPageDefault.hWnd));81: m_pHookHelper.Hook = pPageDefault;
82: }
83: }
84:
85: m_pActiveView = m_pHookHelper.ActiveView;
86: m_pMap = m_pHookHelper.FocusMap;
87: }
88:
89:
90: ///91: /// 只读 当前的地图对象92: ///93: protected IMap Map94: {
95: get
96: {
97: if (null != m_pMap) return m_pMap;98: else99: {
100: if (m_pControl is AxMapControl)101: {
102: m_pMap = (m_pControl as AxMapControl).Map;103: }
104: else if (m_pControl is AxPageLayoutControl)105: {
106: AxPageLayoutControl axPageLayoutControl = m_pControl as AxPageLayoutControl;107: IGraphicsContainer pGraphicsCont = axPageLayoutControl.GraphicsContainer;
108: pGraphicsCont.Reset();
109: IElement pElement = pGraphicsCont.Next();
110: IMapFrame pMapFrame = null;111:
112: while (pElement != null)113: {
114: if (pElement is IMapFrame)115: {
116: pMapFrame = pElement as IMapFrame;117: m_pMap = pMapFrame.Map;
118: break;119: }
120: }
121: }
122: return m_pMap;123: }
124: }
125: }
126:
127: //初始化该功能的GUI资源128: private void InitialToolRes(string str)129: {
130: try131: {
132: ResourceManager pResourceManager = Resources.ResourceManager;
133: pResourceManager.IgnoreCase=true;134:
135: base.m_cursor=CommFun.GetCur(pResourceManager.GetObject("cur"+str));136:
137: base.m_bitmap = (Bitmap)pResourceManager.GetObject("bmp" + str);138: base.m_name = (string)pResourceManager.GetObject("na" + str);139: base.m_caption = (string)pResourceManager.GetObject("cpt" + str);140: if (m_caption == string.Empty) m_caption = m_name;141:
142: base.m_category = (string)pResourceManager.GetObject("ctg" + str);143:
144: base.m_message = (string)pResourceManager.GetObject("msg" + str);145: if (m_message == string.Empty) m_message = m_name;146:
147: base.m_toolTip = (string)pResourceManager.GetObject("tlt" + str);148: if (m_toolTip == string.Empty) m_toolTip = m_name;149:
150: pResourceManager.ReleaseAllResources();
151: }
152: catch153: {
154: return;155: }
156: }
157:
158: ///159: /// 初始化右键快捷菜单160: ///161: protected virtual void initContextMenu()162: {
163: }
164:
165: ///166: /// 显示右键快捷菜单167: ///168: ///169: ///170: protected virtual void ShowContextMenu(int X, int Y)171: {
172: if (!m_showContextMenu) return;173: if (null == m_contextMenu) return;174: if (X < 0 || Y < 0) return;175: System.Drawing.Point pt = new System.Drawing.Point(X, Y);176:
177: if (m_pControl is AxMapControl)178: {
179:
180: AxMapControl axMapControl = (AxMapControl)m_pControl;
181: pt.Offset(axMapControl.Left, axMapControl.Top);
182: m_contextMenu.Show(axMapControl.Parent, pt);
183: }
184: else if (m_pControl is AxPageLayoutControl)185: {
186: AxPageLayoutControl axPageLayoutControl = (AxPageLayoutControl)m_pControl;
187: pt.Offset(axPageLayoutControl.Left, axPageLayoutControl.Top);
188: m_contextMenu.Show(axPageLayoutControl.Parent, pt);
189: }
190: }
191:
192: ///193: /// 获取当前的鼠标性形状194: ///195: ///196: ///197: protected Cursor getCursor(esriSystemMouseCursor esriSystemMouseCursorType)198: {
199: ISystemMouseCursor systemMouseCursor = new SystemMouseCursorClass();200: systemMouseCursor.Load(esriSystemMouseCursorType);
201:
202: Cursor cr = new Cursor((IntPtr)systemMouseCursor.Cursor);203: return cr;204: }
205:
206: #region IDisposable 成员207:
208: public void Dispose()209: {
210: m_pHookHelper = null;211: m_bitmap = null;212: m_cursor = null;213: }
214:
215: #endregion216: }
BaseTool 基类是ESRI.ArcGIS.ADF.BaseClasses命名空间下的基类,该基类实现了IToo和Icommand接口,具体如下
自定义的ToolBase基类,增加了一个Map属性,可以动态获得IMap接口,极大地方便了地图操作。
工具的名称、提示、显示、图标、鼠标形状,都存储在资源文件里,方便维护,为以后的改变主题留有扩展。
增加了右键菜单的设置,默认情况下不显示右键菜单,右键菜单的菜单项,在子类里配置,一些方法的使用,见代码的说明。
实现ZoomIn
继承ToolBase基类,代码实现如下
1: ///
2: /// 地图放大工具
3: ///
4: public class ZoomIn : Base.ToolBase
5: {
6: private INewEnvelopeFeedback m_feedBack;
7: private IPoint m_point;
8: private Boolean m_isMouseDown;
9:
10: #region 实例化
11: public ZoomIn()
12: :base("ZoomIn")
13: {
14: if (m_cursor == null) m_cursor = getCursor(esriSystemMouseCursor.esriSystemMouseCursorZoomIn);
15: }
16:
17: public ZoomIn(AxMapControl mapCtl)
18: : base(mapCtl, "ZoomIn")
19: {
20: if (m_cursor == null) m_cursor = getCursor(esriSystemMouseCursor.esriSystemMouseCursorZoomIn);
21: }
22:
23: public ZoomIn(AxPageLayoutControl plCtl)
24: : base(plCtl, "ZoomIn")
25: {
26: if (m_cursor == null) m_cursor = getCursor(esriSystemMouseCursor.esriSystemMouseCursorZoomIn);
27: }
28: #endregion
29:
30: public override void OnMouseDown(int Button, int Shift, int X, int Y)
31: {
32: if (m_pHookHelper.ActiveView == null) return;
33: m_point = m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
34: m_isMouseDown = true;
35: }
36:
37: public override void OnMouseUp(int Button, int Shift, int X, int Y)
38: {
39: if (!m_isMouseDown) return;
40:
41: //If an envelope has not been tracked
42: IEnvelope pEnvelope;
43:
44: if (m_feedBack == null)
45: {
46: //Zoom in from mouse click
47: pEnvelope =this.m_pActiveView.Extent;
48: pEnvelope.Expand(0.5, 0.5, true);
49: pEnvelope.CenterAt(m_point);
50: }
51: else
52: {
53: //Stop the envelope feedback
54: pEnvelope = m_feedBack.Stop();
55:
56: //Exit if the envelope height or width is 0
57: if (pEnvelope.Width == 0 || pEnvelope.Height == 0)
58: {
59: m_feedBack = null;
60: m_isMouseDown = false;
61: }
62: }
63: //Set the new extent
64: m_pActiveView.Extent = pEnvelope;
65: //Refresh the active view
66: m_pActiveView.Refresh();
67: m_feedBack = null;
68: m_isMouseDown = false;
69: }
70:
71: public override void OnMouseMove(int Button, int Shift, int X, int Y)
72: {
73: if (!m_isMouseDown) return;
74: //Start an envelope feedback
75: if (m_feedBack == null)
76: {
77: m_feedBack = new NewEnvelopeFeedbackClass();
78: m_feedBack.Display = m_pActiveView.ScreenDisplay;
79: m_feedBack.Start(m_point);
80: }
81: //Move the envelope feedback
82: m_feedBack.MoveTo(m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y));
83:
84: }
85: }
相对于 实现Itool和Icommand两个接口的实现,代码量少多了。