2

I am trying to create and show a context menu for arcmap desktop 10.2. I have followed the steps in the link provided by esri, which explains that I must override OnContextMenu. I am not sure if I am doing it right and need your help.

What I did was, I got the same code that is provided on the webpage and pasted it in my project, but nothing happens when I right click on the map. I am sure I am missing something.. do I have to register the context menu somewhere ?

I am a nooby it is obvious from my other questions, I do a lot of reading, but it gets very confusing, so I need someone to simplify things a bit.

Here is my understanding of what I should do, and correct me where I am wrong. According to the link provided below, there are two ways to get a context menu to show. either by implementing the ITool.OnContextMenu in case I want the menu to show for a specific tool, or by implementing the IDocumentEvents.OnContextMenu, which for both cases the event OnContextMenu will automatically fire when the user right-clicks on the active view.

The implementation for the event is also provided in the link, which I copied and pasted into VStudio.. now comes the part where I am confused about. how do I get the event to fire ?. When running the project arcmap starts, I right click on the active view, but no menu pops up. do I have to create the menu myself using windows forms?

http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//0001000004p9000000

Update, here is a chunk of the code, I want to start listening to those events OnMouseDown and OnContextMenu in this part

    public class PTCExternalComponent : BaseTool, ISchematicXmlGenerate, ISchematicXmlUpdate{
    private Application _application;

    public void GenerateXmlData(string diagramName, string diagramClassName, ref   object xmlSource, ref bool cancel) {
               cancel = false;
        try {
            var app = NEAutomation2.Application.Instance().IApplication;
            var nameofActivetool = app.CurrentTool.Command.Name;
            var activeTool = (ITool)app.CurrentTool;
            var toolIndex = app.CurrentTool.Index;
            //((IToolbarControlEvents).OnItemClick(ss);
        //    activeTool.OnMouseDown(0, 0, 0, 0);

            var diagramGenerator = DiagramGenerationFactory.GetDiagramGenerator(
                diagramName, diagramClassName);
            if (diagramGenerator == null) {
                Logger.ShowMessageDialog("Unable to find a Diagram Generator for    diagram type [" + diagramClassName + "]", true);
            } else {
                bool canceled;
                var diagram = diagramGenerator.GenerateDiagram(out canceled);
                var sxg = new SchematicXmlGenerator(diagram, false); // for debugging
                if (diagram != null)
                    xmlSource = sxg.GenerateDiagramXml();
            }
        } catch (Exception e) {
            Logger.ShowMessageDialog(
                "An exception occurred while trying to generate diagram of type " +
                diagramClassName + "; Exception " + e.Message, true);
            ProgressTrackingUtility.HideProgressBar();
        }
    }

    public override void OnMouseDown(int button, int shift, int i, int i1) {
              // do stuff here
    }

    public override bool OnContextMenu(int x, int y) {
      //do stuff here
        throw new NotImplementedException();
    }

    object ISchematicXmlGenerate.ApplicationHook {
        get { return _application as AppRef; }
        set { _application = value as Application; }
    }
Rest of Code .....
  • You have to create the context menu, either dynamically or have it prebuilt. Have a look at this page – Hornbydd Mar 22 '15 at 11:10
  • ok I'll complete the steps and see what happens. Thanks a ton. – ZZZ Mar 22 '15 at 13:35
  • The question is where do you want to create the context menu? The events are different for right click on the map, right click on the table of contents, right click on an existing tool... You need to wire the event and also you need the code wiring the event to be run. Is your code a button? Toolbar? AddIn? How will it be started? Are you trying to put your own option in an existing box or do you want to completely replace the event? – Michael Stimson Mar 22 '15 at 21:51
  • @MichaelMiles-Stimson I want to create a context menu that will be displayed for the user upon right-clicking while the schematic selection tool is active. OnMouseDown sounds like the right event to be using, once the event fires I check which button was clicked, which tool is active and do action "show context menu", but I cant get it to work.. – ZZZ Mar 23 '15 at 8:01
  • Yes, the OnMouseDown will give you the right click event but you must also OnContextMenu(){ return true }; to tell Esri that you're all done or it will display its context menu as well. Are any of your events working? Can you show some code? Is this an addin? If so, can you show what's in your Config.esriaddinx? Has the tool been added to ArcMap? what happens when you click on it? – Michael Stimson Mar 23 '15 at 21:17
1

Implementing BaseTool is the old way, there are quite a few things you will need to do to get ArcMap to 'see' the tool. I would strongly recommend creating a new project starting as an ArcGis addin, which is an available option if you have the ArcObjects SDK installed... this does the hard part for you. If you choose to do it that way it would be much easier as everything comes pre-wired and you would need to implement ISchematicXmlGenerate, ISchematicXmlUpdate on top of ESRI.ArcGIS.Desktop.AddIns.Tool.

If you want to persist with what you've got I can give you an example of functions from one of my old tools called Eddie_Lives in the namespace HandiToolBar:

[Guid("e272d412-85b4-4c5c-bfcf-33dee1dd3003")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("HandiToolBar.Eddie_Lives")]
public sealed class Eddie_Lives : BaseTool
{
    #region COM Registration Function(s)
    [ComRegisterFunction()]
    [ComVisible(false)]
    static void RegisterFunction(Type registerType)
    {
        // Required for ArcGIS Component Category Registrar support
        ArcGISCategoryRegistration(registerType);
    }

    [ComUnregisterFunction()]
    [ComVisible(false)]
    static void UnregisterFunction(Type registerType)
    {
        // Required for ArcGIS Component Category Registrar support
        ArcGISCategoryUnregistration(registerType);
    }

    #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);
        MxCommands.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);
        MxCommands.Unregister(regKey);

    }

    #endregion
    #endregion

Obviously you will need to generate your own GUID because this one is already taken.

Then in the class initializer:

public Eddie_Lives()
{
    base.m_category = "my Tools"; //localizable text 
    base.m_caption = "Eddie, the editor.";  //localizable text 
    base.m_message = "Opens the eddie editor interface.";  //localizable text
    base.m_toolTip = "Opens the eddie editor interface.";  //localizable text
    base.m_name = "Eddie Lives!";   //unique id, non-localizable (e.g. "MyCategory_ArcMapTool")

    try
    {
      //
      // TODO: change resource name if necessary
      //
      //string bitmapResourceName = GetType().Name + ".bmp";
        base.m_bitmap = Properties.Resources.Eddie.ToBitmap();
      //base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
    }
    catch (Exception ex)
    {
      System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
    }
}

base is a property of the BaseTool which you're implementing.

Then in the overriden class OnCreate:

public override void OnCreate(object hook)
{
    m_application = hook as IApplication;

    //Disable if it is not ArcMap
    if (hook is IMxApplication)
    { 
        base.m_enabled = true; // enable the tool

After you've jumped through all those hoops you can add the compiled dll (after it is registered using C:\Program Files (x86)\Common Files\ArcGIS\bin\ESRIRegAsm.exe) to ArcMap and the tool will be available in the customize dialog, place it on a tool bar and your events should fire. Com types are being replaced by addins which means this code will definitely have a limited lifespan before you need to create an addin just to get it to work.

  • Thanks for the information, but I have used this method before to create a toolbar which contains 7 tools. I feel like I am not sure if this is what I am looking for, the truth is I might be confusing you with the question because of my lack of knowledge. But ALL I am trying to do is this "show a menu for the user when they right click on the map while schematic edit tool is active", that is all I am trying to do. if this requires an add in then what type of add in would it be ? – ZZZ Mar 25 '15 at 8:57
  • Does the schematic edit tool become active? Is it on a toolbar in ArcMap? Your code sample lacks the methods in the answer, these properties are important to ArcMap to add/run the tool correctly, if they're not there then ArcMap will ignore your code and the events will not be wired. – Michael Stimson Mar 25 '15 at 21:25
  • Yes my code runs as soon you click on the Generate Diagrame from the schematic editor toolbar which is built in Arcmap..I know I have not pasted much but this project contains over 20 classes, and is very complex so I just pasted where the code starts up top. I have decided to create an extension that will be running in the background as soon as arcmap starts, I'll wire the map events there and do action based on the active tool. I will post my final results as soon as it is complete. – ZZZ Mar 26 '15 at 7:24
  • so OnClick is working, and you say OnMouseDown isn't responding... interesting. Your OnMouseDown doesn't do anything perhaps put a messagebox in there and set a breakpoint to see if that code block is being hit. For some reason in my code the context is being handled by OnMouseDown with if (arg.Button == MouseButtons.Right) and OnContextMenu simply returns true to tell ArcMap that the context has been done and ArcMap shouldn't try to display the default context menu. – Michael Stimson Mar 26 '15 at 21:14
  • I managed to get it done, I was implementing BaseTool, when in fact I didnt need an add-in or the onMouseDown event, all I needed was to make an extension that will listen to my map events, and handle m_docEvents_OnContextMenu event which fires when the user right clicks on the map. now I need to create a context menu. is there an built-in Arcmap context menu that I can display to the user ? if so, how do I show it to the user ? I tried extending Arcmap by building a class that extends BaseMenu. and in the constructor I am adding item, but when invoked it doesnt show. – ZZZ Mar 30 '15 at 6:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.