How to change the cursor of an  ITool

1891
11
01-18-2012 04:41 AM
SergioMunoz
New Contributor
Hello everyone,

I am making an application with ARCGIS, and some actions take a lot of time (for example, zooming with ControlsMapZoomInToolClass). I would like to change the cursor to another one that tells the user that the application is busy (something like a sandwatch, or whatever), but Cursor property seems to be read only.

Is there any way to change the Cursor when the action begins, and revert it when it ends?

Thank you very much in advance.
0 Kudos
11 Replies
KenBuja
MVP Esteemed Contributor
In some of the .Net applications I build, I use the line

System.Windows.Forms.Cursor.Current = Windows.Forms.Cursors.WaitCursor

at the beginning of a long operation and at the end of the operation, setting it to the default with the line

System.Windows.Forms.Cursor.Current = Windows.Forms.Cursors.Default
0 Kudos
SergioMunoz
New Contributor
In some of the .Net applications I build, I use the line

System.Windows.Forms.Cursor.Current = Windows.Forms.Cursors.WaitCursor

at the beginning of a long operation and at the end of the operation, setting it to the default with the line

System.Windows.Forms.Cursor.Current = Windows.Forms.Cursors.Default


I have done that too, but the problem is that the tool is inside a map, like this:

    ICommand pCommand = new ControlsMapZoomInToolClass();
    pCommand.OnCreate(map.Object);
    map.CurrentTool = pCommand as ITool;


where map is an AxMapControl, and when the user moves the cursor into the map, it automatically changes the WaitCursor for the ControlsMapZoomInToolClass'. So what I want to do is to change the ControlsMapZoomInToolClass' cursor
0 Kudos
sapnas
by
Occasional Contributor III
You can create custom zoomin tool that inherits from itool and customize the cursor. Replace ControlsMapZoomInToolClass with custom zoom in tool.

using System;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.ADF.CATIDs;
using System.Runtime.InteropServices;
namespace PanZoom
{
 [ClassInterface(ClassInterfaceType.None)]
 [Guid("2C214724-BFA2-4e8c-BC5D-775C67FA6F51")]
 public class ZoomIn : ICommand, ITool
 {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);
            //
            // TODO: Add any COM registration code here
            //
        }
        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);
            //
            // TODO: Add any COM unregistration code here
            //
        }
        #region ArcGIS Component Category Registrar generated code
        /// <summary>
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Register(regKey);
        }
        /// <summary>
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Unregister(regKey);
        }
        #endregion
        #endregion
  [DllImport("gdi32.dll")]
  static extern bool DeleteObject(IntPtr hObject);
  private System.Drawing.Bitmap m_bitmap;
  private IntPtr m_hBitmap;
  private IHookHelper m_pHookHelper;
  private INewEnvelopeFeedback m_feedBack;
  private IPoint m_point;
  private Boolean m_isMouseDown;
  private System.Windows.Forms.Cursor m_zoomInCur;
  private System.Windows.Forms.Cursor m_moveZoomInCur;
  public ZoomIn()
  {
   //Load resources
   string[] res = GetType().Assembly.GetManifestResourceNames();
   if(res.GetLength(0) > 0)
   {
    m_bitmap = new System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream(GetType(), "ZoomIn.bmp"));
    if(m_bitmap != null)
    {
     m_bitmap.MakeTransparent(m_bitmap.GetPixel(1,1));
     m_hBitmap = m_bitmap.GetHbitmap();
    }
   }
   m_pHookHelper = new HookHelperClass ();
  }
 
  ~ZoomIn()
  {
   if(m_hBitmap.ToInt32() != 0)
    DeleteObject(m_hBitmap);
  }
  #region ICommand Members
  public void OnClick()
  {
  }
  public string Message
  {
   get
   {
    return "zooms the Display In By Rectangle or Single Click";
   }
  }
  public int Bitmap
  {
   get
   {
    return m_hBitmap.ToInt32();
   }
  }
  public void OnCreate(object hook)
  {
   m_pHookHelper.Hook = hook;
   m_zoomInCur = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream(GetType(), "ZoomIn.cur"));
   m_moveZoomInCur = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream(GetType(), "MoveZoomIn.cur"));
  }
  public string Caption
  {
   get
   {
    return "Zoom In";
   }
  }
  public string Tooltip
  {
   get
   {
    return "Zoom In";
   }
  }
  public int HelpContextID
  {
   get
   {
    // TODO:  Add ZoomIn.HelpContextID getter implementation
    return 0;
   }
  }
  public string Name
  {
   get
   {
    return "Sample_Pan/Zoom_Zoom In";
   }
  }
  public bool Checked
  {
   get
   {
    return false;
   }
  }
  public bool Enabled
  {
   get
   {
    if(m_pHookHelper.FocusMap == null) return false;
    return true;
   }
  }
  public string HelpFile
  {
   get
   {
    // TODO:  Add ZoomIn.HelpFile getter implementation
    return null;
   }
  }
  public string Category
  {
   get
   {
    return "Sample_Pan/Zoom";
   }
  }
  #endregion
 
  #region ITool Members
  public void OnMouseDown(int button, int shift, int x, int y)
  {
   if(m_pHookHelper.ActiveView == null) return;
   //If the active view is a page layout
   if(m_pHookHelper.ActiveView is IPageLayout)
   {
    //Create a point in map coordinates
    IPoint pPoint = (IPoint) m_pHookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
    //Get the map if the point is within a data frame
    IMap pMap = m_pHookHelper.ActiveView.HitTestMap(pPoint);
    if(pMap == null) return;
    //Set the map to be the page layout's focus map
    if(pMap != m_pHookHelper.FocusMap)
    {
     m_pHookHelper.ActiveView.FocusMap = pMap;
     m_pHookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
    }
   }
   //Create a point in map coordinates
   IActiveView pActiveView = (IActiveView) m_pHookHelper.FocusMap;
   m_point = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
   m_isMouseDown = true;
  }
  public void OnMouseMove(int button, int shift, int x, int y)
  {
   if(!m_isMouseDown) return;
   //Get the focus map
   IActiveView pActiveView = (IActiveView) m_pHookHelper.FocusMap;
   //Start an envelope feedback
   if(m_feedBack == null)
   {
    m_feedBack = new NewEnvelopeFeedbackClass();
    m_feedBack.Display = pActiveView.ScreenDisplay;
    m_feedBack.Start(m_point);
   }
   //Move the envelope feedback
   m_feedBack.MoveTo(pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y));
  }
  public void OnMouseUp(int button, int shift, int x, int y)
  {
   if(!m_isMouseDown) return;
   //Get the focus map
   IActiveView pActiveView = (IActiveView) m_pHookHelper.FocusMap;
   //If an envelope has not been tracked
   IEnvelope pEnvelope;
   if(m_feedBack == null)
   {
    //Zoom in from mouse click
    pEnvelope = pActiveView.Extent;
    pEnvelope.Expand(0.5, 0.5, true);
    pEnvelope.CenterAt(m_point);
   }
   else
   {
    //Stop the envelope feedback
    pEnvelope = m_feedBack.Stop();
    //Exit if the envelope height or width is 0
    if(pEnvelope.Width ==0 || pEnvelope.Height == 0)
    {
     m_feedBack = null;
     m_isMouseDown = false;
    }
   }
   //Set the new extent
   pActiveView.Extent = pEnvelope;
   //Refresh the active view
   pActiveView.Refresh();
   m_feedBack = null;
   m_isMouseDown = false;
  }
  public void OnKeyDown(int keyCode, int shift)
  {
   if(m_isMouseDown)
   {
    if(keyCode == 27)
    {
     m_isMouseDown = false;
     m_feedBack = null;
     m_pHookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
    }
   }
  }
  public void OnKeyUp(int keyCode, int shift)
  {
   // TODO:  Add ZoomIn.OnKeyUp implementation
  }
  public int Cursor
  {
   get
   {
    if(m_isMouseDown)
     return m_moveZoomInCur.Handle.ToInt32();
    else
     return m_zoomInCur.Handle.ToInt32();
   }
  }
  
  public bool OnContextMenu(int x, int y)
  {
   // TODO:  Add ZoomIn.OnContextMenu implementation
   return false;
  }
  public bool Deactivate()
  {
   return true;
  }
  public void Refresh(int hdc)
  {
   // TODO:  Add ZoomIn.Refresh implementation
  }
  public void OnDblClick()
  {
   // TODO:  Add ZoomIn.OnDblClick implementation
  }
  #endregion
 }
}
0 Kudos
GeorgeFaraj
Occasional Contributor III
You can create custom zoomin tool that inherits from itool and customize the cursor. Replace ControlsMapZoomInToolClass with custom zoom in tool.


Isn't this just a re-write of that functionality? There's no way to change properties for the existing control?
0 Kudos
sapnas
by
Occasional Contributor III
not that I know of
0 Kudos
GeorgeFaraj
Occasional Contributor III
not that I know of


So it is really not "change the cursor of an ITool" but create a new tool with a cursor.  Does anyone know how you can actually do the first task? Is it even possible? How can you replace the bitmap used on the toolbar for an existing tool? (If you have to re-write the tool then that kind defeats the purpose of even having those tools available for use.)
0 Kudos
sapnas
by
Occasional Contributor III
So it is really not "change the cursor of an ITool" but create a new tool with a cursor.


Hence I used the term custom tool.
0 Kudos
sapnas
by
Occasional Contributor III
(If you have to re-write the tool then that kind defeats the purpose of even having those tools available for use.)

It�??s not like I�??m  imposing any one here to use the solution. If you don�??t like it don�??t implement it.
0 Kudos
GeorgeFaraj
Occasional Contributor III
It�??s not like I�??m  imposing any one here to use the solution. If you don�??t like it don�??t implement it.


My intent was NOT to insult you!  You shared valuable knowledge and for that I thank you. I just wish ESRI would address this problem.
0 Kudos