Select to view content in your preferred language

How to add handler to mouse click on the map of ArcMap?

7556
13
Jump to solution
06-14-2012 02:07 PM
SuiHuang
Frequent Contributor
Hi Everybody:

    I am writing an ArcMap 10 extension using C#. I want to detect the user's mouse click on the map. However, I haven't successfully get it done.

    I notice that IMapControlEvent2 should give a delegate to handle the event, but I don't know how to get IMapControlEvent2 out of the current application. I did the following but it doesn't work:
***************************************************************
IActiveView view = (_mApplication.Document as IMxDocument).ActivatedView;
IMapControlDefault mapControlDefault = new MapControl();
mapControlDefault.Map = view.FocusMap;
IMapControlEvents2 mapControlEvents = mapControlDefault as IMapControlEvents2;
***************************************************************

    How shall I do it?
    Thank you!
0 Kudos
1 Solution

Accepted Solutions
SuiHuang
Frequent Contributor
Hi richwawr:

    Yes I am using Visual Studio, and I actually created the code with template and then modified it. I am using the COM approach because COM can still do more then Add-in, even though Add-in is easy to deploy.
    The reason I why I was not using the custom tool template at the beginning is that: I don't actually want to create a tool with a button on the ArcMap toolbar. Instead I want to make a button on a windows form to bring user into a state of picking features on the map, so I tried to handle the map events first. However, I still end up building a tool (but hide it from the toolbar) 🙂
    I just use the following derived BaseTool classes to allow the state of ArcMap tool rollback to original after user has interacted.
    Any better idea?
    Thank you!

    public abstract class RollbackableToolBase : BaseTool      {         protected IApplication m_Application = null;           public ICommandItem RollbackTool { get; set; }          public override sealed void OnCreate(object hook)         {             m_Application = hook as IApplication;         }     }      public class RollbackableTool1 : RollbackableToolBase      {         public RollbackableTool1 ()         {             Result = null;         }          // the shoot event         public event RanEventHandler Ran= null;          public object Result { get; private set; }          public override void OnMouseDown(int button, int shift, int x, int y)         {             // interact with the screen and get the result              // restore the current tool             m_Application.CurrentTool = this.RollbackTool;         }     }      public delegate void RanEventHandler(object sender, EventArgs e);


Are you using Visual Studio? There are templates in VS to create custom tools for ArcMap. You can create them as COM extensions (need an installer to deploy) or using the newer Add-in framework. I recommend the Add-in method because it makes deployment much easier. It looks like your code is attempting to use the COM method. There is a lot more to it than what you have and yes it has to be registered. Do you have the template?

View solution in original post

0 Kudos
13 Replies
SuiHuang
Frequent Contributor
Hi Everybody:

    Just an update that the event interface object is retrieved, but the application still does not respond. Here is my code:
*************************************************************************
IMapControlDefault mapControlDefault = new MapControl();
mapControlDefault.Map = view.FocusMap;
mapControlDefault.FlashShape(_CurrentFeatureBo.ShapeCopy);
IMapControlEvents2_Event mapControlEvents = mapControlDefault as IMapControlEvents2_Event;
mapControlEvents.OnMouseDown += new IMapControlEvents2_OnMouseDownEventHandler(mapControlEvents_OnMouseDown);
mapControlEvents.OnViewRefreshed += new IMapControlEvents2_OnViewRefreshedEventHandler(mapControlEvents_OnViewRefreshed);
      
void mapControlEvents_OnViewRefreshed(object ActiveView, int viewDrawPhase, object layerOrElement, object envelope)
{
     MessageBox.Show("refreshed");
}

void mapControlEvents_OnMouseDown(int button, int shift, int X, int Y, double mapX, double mapY)
{
     MessageBox.Show("clicked");
}
*************************************************************************

When I click on the map or refresh the map in ArcMap. The message boxes in event handlers do not show up.
How shall I change it?

Thank you!

Hi Everybody:

    I am writing an ArcMap 10 extension using C#. I want to detect the user's mouse click on the map. However, I haven't successfully get it done.

    I notice that IMapControlEvent2 should give a delegate to handle the event, but I don't know how to get IMapControlEvent2 out of the current application. I did the following but it doesn't work:
***************************************************************
IActiveView view = (_mApplication.Document as IMxDocument).ActivatedView;
IMapControlDefault mapControlDefault = new MapControl();
mapControlDefault.Map = view.FocusMap;
IMapControlEvents2 mapControlEvents = mapControlDefault as IMapControlEvents2;
***************************************************************

    How shall I do it?
    Thank you!
0 Kudos
SuiHuang
Frequent Contributor
Hi Everybody:

    More update...
    I tried the following code.

// variable declarations in class level
private IMapControlEvents2_Event mapControlEvents = null;
private IMapControlDefault mapControlDefault = null;

// wiring up the events in one of the called member function, each event handler use MessageBox.Show to display a message
mapControlDefault = new MapControl();
mapControlDefault.Map = view.FocusMap;
mapControlEvents = mapControlDefault as IMapControlEvents2_Event;
mapControlEvents.OnMouseDown += new IMapControlEvents2_OnMouseDownEventHandler(mapControlEvents_OnMouseDown);
mapControlEvents.OnSelectionChanged += new IMapControlEvents2_OnSelectionChangedEventHandler(mapControlEvents_OnSelectionChanged);
mapControlEvents.OnMouseUp += new IMapControlEvents2_OnMouseUpEventHandler(mapControlEvents_OnMouseUp);
mapControlEvents.OnMouseMove += new IMapControlEvents2_OnMouseMoveEventHandler(mapControlEvents_OnMouseMove);
mapControlEvents.OnDoubleClick += new IMapControlEvents2_OnDoubleClickEventHandler(mapControlEvents_OnDoubleClick);
mapControlEvents.OnExtentUpdated += new IMapControlEvents2_OnExtentUpdatedEventHandler(mapControlEvents_OnExtentUpdated);
mapControlEvents.OnKeyDown += new IMapControlEvents2_OnKeyDownEventHandler(mapControlEvents_OnKeyDown);


By experiment I found that in these events only OnExtentUpdated and OnSelectionChanged response. All the events related to mouse and key press are not responding. Anybody know why?

Thank you!
0 Kudos
RichWawrzonek
Frequent Contributor
Sui-
I don't think you want to get a reference to your IMapControl2 object using the new keyword. I think you need to query interface from an existing object.

Something like this:
IMapControl4 mapControl = axMapControl1.Object as IMapControl4;


Do you have an axMapControl1 object somewhere?
0 Kudos
SuiHuang
Frequent Contributor
Hi richwawr:

    Do you mean I need to have an ESRI.ArcGIS.Controls.AxMapControl object? I found this class by Visual Studio intellisense, but I was not able to find how to get this object, neither find the help document of this class.
    Further hinds?
    Thank you.

Sui

Sui-
I don't think you want to get a reference to your IMapControl2 object using the new keyword. I think you need to query interface from an existing object.

Something like this:
IMapControl4 mapControl = axMapControl1.Object as IMapControl4;


Do you have an axMapControl1 object somewhere?
0 Kudos
RichWawrzonek
Frequent Contributor
Are you using ArcEngine?  I assumed you were since you were trying to use the IMapControl. That interface is for accessing the map of an ArcEngine control.
0 Kudos
SuiHuang
Frequent Contributor
Hi richwawr:

    I don't think I am using ArcEngine, and I am not suppose to, because I am just developing an ArcMap extension, not a stand alone application.
    Should I use IMapControl only if I have ArcEngine license? Then how shall I capture the mouse-click event on ArcMap?
    Thank you!

Are you using ArcEngine?  I assumed you were since you were trying to use the IMapControl. That interface is for accessing the map of an ArcEngine control.
0 Kudos
RichWawrzonek
Frequent Contributor
That really depends on what you are trying to do. Are you trying to return information from a feature clicked in the map? Trying to pop up a context menu when user right-clicks? It's all different. Please define what you are trying to acheive.

A typical scenario is the need to capture the location when a user left-click the map. To accomplish this I create a ITool that the user activates prior to clicking. The ITool provides event handlers such as OnMouseUp that you can add code to.
0 Kudos
SuiHuang
Frequent Contributor
Thank you richwawr! I am trying the ITool approach.

That really depends on what you are trying to do. Are you trying to return information from a feature clicked in the map? Trying to pop up a context menu when user right-clicks? It's all different. Please define what you are trying to acheive.

A typical scenario is the need to capture the location when a user left-click the map. To accomplish this I create a ITool that the user activates prior to clicking. The ITool provides event handlers such as OnMouseUp that you can add code to.
0 Kudos
SuiHuang
Frequent Contributor
Hi! richwawr:

    Instead of directly using ITool, I directly inherit BaseTool and register it to ArcMap (following the style of making a custom tool). Because the tool's activation needs to deactivate the other tools in ArcMap, I think registering it to ArcMap is necessary. Am I right? Or there is simpler way to detect the mouse click?
    Following is my code for now. Thank you!
// set the tool with hardcoded UID to current
ICommandBars documentBars = _mApplication.Document.CommandBars;
UID cmdID = new UIDClass();
cmdID.Value = "{0dxxc599-c213-4xxb-8978-1227bac1bx8d}";
ICommandItem cmdItem = documentBars.Find(cmdID, false, false);
(cmdItem.Command as TestTool).rollbackTool = _mApplication.CurrentTool;
_mApplication.CurrentTool = cmdItem;


[Guid("0dxxc599-c213-4xxb-8978-1227bac1bx8d")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CustTool.TestTool")]
public class TestTool : BaseTool
{
    // registration methods
    // ...
    // OnCreate method
    // ..

    public ICommandItem rollbackTool = null;
    private IApplication mApplication = null;
    public override void OnMouseDown(int button, int shift, int x, int y)
    {
        // do the work
        mApplication.CurrentTool = this.rollbackTool;
     }
}


That really depends on what you are trying to do. Are you trying to return information from a feature clicked in the map? Trying to pop up a context menu when user right-clicks? It's all different. Please define what you are trying to acheive.

A typical scenario is the need to capture the location when a user left-click the map. To accomplish this I create a ITool that the user activates prior to clicking. The ITool provides event handlers such as OnMouseUp that you can add code to.
0 Kudos