一起学习ArcEngine(2)-重构

  本打算这次写缩小的,发现还得实现Itool和Icommend接口,真是麻烦啊!想到后面还有那么多的工具要写,每个都要实现这两个接口,要ctrl+c 和ctrl+V 多次,对于像我这样的懒人,一次也不想干。重新设计一下,增加个基类,在基类里实现这两个接口,所有的工具都继承这个基类,就OK了!

      tool和command 的工作方式不同,tool是与地图有交互,command是没有,因此最好设计两个基类ToolBase和CommandBase,将二者分开。ToolBase的代码如下


   1:      /// <summary>
   2:      /// CommBase 的摘要说明。
   3:      /// </summary>
   4:      public class ToolBase:BaseTool,IDisposable
   5:      {
   6:          protected  IHookHelper    m_pHookHelper;
   7:   
   8:          protected object m_pControl;
   9:          protected IActiveView m_pActiveView;
  10:          protected IMap m_pMap;
  11:          /// <summary>
  12:          /// 标示右键功能是否起作用
  13:          /// </summary>
  14:          protected bool m_showContextMenu = false;
  15:          protected ContextMenu m_contextMenu;
  16:   
  17:   
  18:          /// <summary>
  19:          /// 
  20:          /// </summary>
  21:          /// <param name="str">工具名称</param>
  22:          public ToolBase(string str):base()
  23:          {
  24:              m_pHookHelper=new HookHelperClass();
  25:              InitialToolRes(str);
  26:              initContextMenu();
  27:          }
  28:   
  29:          /// <summary>
  30:          /// 
  31:          /// </summary>
  32:          /// <param name="mapContrl">工具关联的地图控件</param>
  33:          /// <param name="str"></param>
  34:          public ToolBase(AxMapControl mapContrl, string str)
  35:              :this(str)
  36:          {
  37:              OnCreate(mapContrl.Object);
  38:          }
  39:   
  40:          /// <summary>
  41:          /// 
  42:          /// </summary>
  43:          /// <param name="playoutCtl">工具关联的地图控件</param>
  44:          /// <param name="str"></param>
  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:              else
  70:              {
  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:          /// <summary>
  91:          /// 只读 当前的地图对象 
  92:          /// </summary>
  93:          protected IMap Map
  94:          {
  95:              get
  96:              {
  97:                  if (null != m_pMap) return m_pMap;
  98:                  else
  99:                  {
 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:              try
 131:              {
 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:              catch
 153:              {
 154:                  return;
 155:              }
 156:          }
 157:   
 158:          /// <summary>
 159:          /// 初始化右键快捷菜单
 160:          /// </summary>
 161:          protected virtual void initContextMenu()
 162:          {
 163:          }
 164:         
 165:          /// <summary>
 166:          /// 显示右键快捷菜单
 167:          /// </summary>
 168:          /// <param name="X"></param>
 169:          /// <param name="Y"></param>
 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:          /// <summary>
 193:          ///  获取当前的鼠标性形状
 194:          /// </summary>
 195:          /// <param name="esriSystemMouseCursorType"></param>
 196:          /// <returns></returns>
 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:          #endregion
 216:      }

BaseTool 基类是ESRI.ArcGIS.ADF.BaseClasses命名空间下的基类,该基类实现了IToo和Icommand接口,具体如下

image  自定义的ToolBase基类,增加了一个Map属性,可以动态获得IMap接口,极大地方便了地图操作。

工具的名称、提示、显示、图标、鼠标形状,都存储在资源文件里,方便维护,为以后的改变主题留有扩展。

增加了右键菜单的设置,默认情况下不显示右键菜单,右键菜单的菜单项,在子类里配置,一些方法的使用,见代码的说明。

 

实现ZoomIn

继承ToolBase基类,代码实现如下

   1:      /// <summary>
   2:      ///  地图放大工具
   3:      /// </summary>
   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两个接口的实现,代码量少多了。
posted @ 2009-09-06 15:43  liuyh208  阅读(1342)  评论(7编辑  收藏  举报