May 04, 2007

Adding a context menu to AutoCAD objects using .NET

It's been quite a week - between interviews for a DevTech position we're working to fill in Beijing and AU proposals (my team managed to pull together and submit nearly 60 API class proposals at the beginning of the week) life has been extremely hectic.

Thankfully we're now in the middle of the "May Day Golden Week" here in China. The Chinese government schedules three Golden Weeks every year - one for Spring Festival, one for Labour Day (also known as May Day) and one for the National Day. They're basically week-long holidays formed by a few standard holidays and mandating that people work through an adjacent weekend, grouping together the holidays with the days that are freed up into a contiguous week-long break. These weeks are designed to promote domestic tourism, by allowing people to plan vacations well in advance, and they seem to be working, apparently 25% of domestic tourism in China is due to these three Golden Weeks.

Anyway - I've been working, on and off, as my team isn't all based in China, but I did get to spend some quality time with my family. All this to say it's been a week since my last post, so I'm up late on Friday night to assuage my guilt. :-)

I threw some simple code together to show how to add your own custom context menu to a particular type of AutoCAD object using .NET. The below code adds a new context menu at the "Entity" level, which means that as long as only entities are selected in the editor, the context menu will appear. As objects have to be of type Entity to be selectable, I think it's safe to say the context menu will always be accessible. :-)

You could very easily modify the code to only show the menu for a concrete class of object (Lines, Circles, etc.), of course.

So what does this new context menu do? In this case it simply fires off a command, which then selects our entities by accessing the pickfirst selection set, and does something with the selected entities. The actual command I implemented was very simple, indeed: it simply counts the entities selected and writes a message to the command-line.

Here's the C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Windows;

using System;

namespace ContextMenuApplication

{

publicclassCommands : IExtensionApplication

{

publicvoid Initialize()

{

CountMenu.Attach();

}

publicvoid Terminate()

{

CountMenu.Detach();

}

[CommandMethod("COUNT", CommandFlags.UsePickSet)]

staticpublicvoid CountSelection()

{

Editor ed =

Application.DocumentManager.MdiActiveDocument.Editor;

PromptSelectionResult psr = ed.GetSelection();

if (psr.Status == PromptStatus.OK)

{

ed.WriteMessage(

"\nSelected {0} entities.",

psr.Value.Count

);

}

}

}

publicclassCountMenu

{

privatestaticContextMenuExtension cme;

publicstaticvoid Attach()

{

cme = newContextMenuExtension();

MenuItem mi = newMenuItem("Count");

mi.Click += newEventHandler(OnCount);

cme.MenuItems.Add(mi);

RXClass rxc = Entity.GetClass(typeof(Entity));

Application.AddObjectContextMenuExtension(rxc, cme);

}

publicstaticvoid Detach()

{

RXClass rxc = Entity.GetClass(typeof(Entity));

Application.RemoveObjectContextMenuExtension(rxc, cme);

}

privatestaticvoid OnCount(Object o, EventArgs e)

{

Document doc =

Application.DocumentManager.MdiActiveDocument;

doc.SendStringToExecute("_.COUNT ", true, false, false);

}

}

}

And here's what we see when we have our application loaded, right-clicking after selecting some AutoCAD objects:

Followed by the somewhat mundane result:

Selected 10 entities.

Update:

As an alternative, it's worth looking at theseposts which show how to add context menus for AutoCAD objects using CUI.