Implementing task dialogs inside AutoCAD using .NET - Part 1
This is a topic I've been meaning to get to for some time... as I finally had to research it for a side project I'm working on, I decided to go ahead and post my findings here.
AutoCAD 2009 makes heavy use of task dialogs, which are basically message-boxes on steroids. MSDN contains documentation on Microsoft's implementation of task dialogs, although our implementation is a little different.
Why bother with these new task dialogs? They provide a way of asking more user-friendly questions using actual actions as answers rather than yes/no/cancel etc. It's a bit like the way I now often seem to be asked questions such as "who packed this bag?" when flying, these days, rather than "did you pack this bag yourself?" - you have to think a little more, but that usually increases the chances of getting accurate information. Alright, perhaps the airline security analogy wasn't all that appropriate, after all, but hopefully you get the idea.
In this first part of the two-part series we're going to look at the basic steps to add task dialogs to our projects, showing a very basic example that gives an idea of their capabilities, and in the next part we'll see a much more concrete, real-world implementation example.
The first thing to do to make use of task dialogs in your application is to add a reference to the AdWindows.dll assembly. You should find it in AutoCAD 2009 (but not previous versions), in the root application folder. As usual when adding AutoCAD's managed assemblies to your project, remember to set the "Copy Local" flag to false, to avoid problems later. Once we've added this reference we're able to use the Autodesk.Windows namespace (not to be confused with Autodesk.AutoCAD.Windows, which is AutoCAD-specific).
Here's our initial C# code to show a very basic task dialog, without doing very much with the information provided:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Windows;
namespace TaskDialogs
{
public class Commands
{
[CommandMethod("Task1")]
public static void TestingTaskDialogOptions()
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
// Create the task dialog itself
TaskDialog td = new TaskDialog();
// Set the various textual settings
td.WindowTitle = "The title";
td.MainInstruction = "Something has happened.";
td.ContentText =
"Here's some text, with a " +
"<A HREF=\"http://adn.autodesk.com\">" +
"link to the ADN site</A>";
td.VerificationText = "Verification text";
td.FooterText =
"The footer with a "+
"<A HREF=\"http://blogs.autodesk.com/through" +
"-the-interface\">link to Kean's blog</A>";
td.EnableHyperlinks = true;
td.EnableVerificationHandler = true;
// And those for collapsed/expanded text
td.CollapsedControlText =
"This control text can be expanded.";
td.ExpandedControlText
= "This control text has been expanded..." +
"\nTo span multiple lines.";
td.ExpandedText = "This footer text has been expanded.";
td.ExpandFooterArea = true;
td.ExpandedByDefault = false;
// Set some standard icons and display of the progress bar
td.MainIcon = TaskDialogIcon.Shield;
td.FooterIcon = TaskDialogIcon.Information;
td.ShowProgressBar = true;
// A marquee progress bas just loops,
// it has no range fixed upfront
//td.ShowMarqueeProgressBar = true;
// Now we add out task action buttons
td.UseCommandLinks = true;
td.Buttons.Add(
new TaskDialogButton(
1,
"This is one course of action."
)
);
td.Buttons.Add(
new TaskDialogButton(
2,
"Here is another course of action."
)
);
td.Buttons.Add(
new TaskDialogButton(
3,
"And would you believe we have a third!"
)
);
// Set the default to be the third
td.DefaultButton = 3;
// And some radio buttons, too
td.RadioButtons.Add(new TaskDialogButton(4, "Yes"));
td.RadioButtons.Add(new TaskDialogButton(5, "No"));
td.RadioButtons.Add(new TaskDialogButton(6, "Maybe"));
// Set the default to be the second
td.DefaultRadioButton = 5;
// Allow the dialog to be cancelled
td.AllowDialogCancellation = false;
// Implement a callback for UI event notification
td.Callback =
delegate(
ActiveTaskDialog atd,
TaskDialogEventArgs e,
object sender
)
{
ed.WriteMessage(
"\nButton ID: {0}",
e.ButtonId
);
ed.WriteMessage(
"\nNotification: {0}",
e.Notification
);
if (e.Notification ==
TaskDialogNotification.VerificationClicked)
{
atd.SetProgressBarRange(0, 100);
atd.SetProgressBarPosition(80);
}
else if (e.Notification ==
TaskDialogNotification.HyperlinkClicked)
{
ed.WriteMessage(" " + e.Hyperlink);
}
ed.WriteMessage("\n");
// Returning true will prevent the dialog from
// being closed
return false;
};
td.Show(Application.MainWindow.Handle);
}
}
}
When we execute the TASK1 command, we can see this dialog gets displayed:
This dialog exercises most of the UI options available in the TaskDialog class. You'll see a progress bar (which gets modified via the ActiveTaskDialog passed into the notification callback - try checking the "Verification text" box to see that happen) as well as option buttons, action buttons and some expandable text.
Here's how the dialog looks with the text expanded and the verification checkbox ticked:
It's worth playing around with the code to see how the notification is provided to the application, and how the ActiveTaskDialog can be used from there to modify the state of the dialog. One thing you'll notice is that the hyperlinks don't automatically result in a browser being launched, which overall is a good thing, as the links can then be set up to result in other actions (the application has all the information it needs to know what was clicked in the notification callback - if it wants to launch a browser to the clicked URL, it is free to do so).
Now that we've explored the various options open to us, in the next post we'll look at a more real-world example of using a task dialog to help manage potentially time-consuming application behaviour.

Subscribe via RSS
Hi Kean,
Good topic.
I translated this into VB, and had a conundrum on this part:
td.Callback = delegate(
ActiveTaskDialog atd,
TaskDialogEventArgs e,
object sender
)....
so I pulled it out to it's own function and did this:
td.Callback = AddressOf tdCallBack
which does seem to be catching the callbacks, but it threw an error on "atd.SetProgressBarState(Autodesk.Windows.ProgressBarState.Normal)"
and ultimately crashed AutoCAD after a second error that occured after the callback. I commented out that line and it seems to work fine.
the error was System.NotSupportedException
Message="Specified method is not supported."
Source="AdWindows"
and came with a stack trace 52 calls long.
Posted by: David Osborne | November 11, 2008 at 10:21 PM
Hi David,
Strange - not sure why it would be different in your version... I don't remember especially why I put the SetProgressBarState() call in there, so it could possibly be redundant or even erroneous (although I didn't see a crash).
Kean
Posted by: Kean | November 12, 2008 at 07:56 AM
Kean,
I received the same error as David on the same line.
The crash manifests when you hit the checkbox at the bottom of the dialog.
AutoCAD 2009
Visual C# Express 2008
.NET 3.5
Posted by: Glenn R | November 12, 2008 at 06:55 PM
David, Glenn,
OK - you have me convinced. :-)
For some reason it works fine on my (Vista) machine, but I can see no reason for the call being there & removing it does nothing to the behaviour. I suspect it's just an artifact from me testing out the various properties/methods.
So I've removed it from the post. Thanks for the report & confirmation!
Kean
Posted by: Kean | November 12, 2008 at 07:06 PM
Glenn did not mention his OS but I am on ACAD2009, VB pro 2005, .NET 2, and XP pro. Just for giggles I looked at the link above to the Microsoft implementation, and it says the required version is Vista, so that's probably it.
Posted by: David Osborne | November 12, 2008 at 07:26 PM
Autodesk's implementation was independent - I'm assuming to support XP as well as Vista. So that's not going to be the problem.
The call doesn't need to be made there, so it's safe to ignore the problem (I expect calling it on TaskDialog rather than ActiveTaskDialog works just fine).
Kean
Posted by: Kean | November 12, 2008 at 10:02 PM
Hi Kean,
I'm currently working in a furniture firm on the enginering department. Last year I followed 1 year Visual.NET programming.
This morning I received the question wether I could develop a program in AutoCAD 2009 speed up the design of furniture. The thing is, I've never developped something in AutoCAD with VBA.
Can I try this best with VBA or start programming in VB.NET?
Do you know where I can find information/tutorials/help the help me develop this application?
Many thanks!!!
Kind regards
Posted by: Thomas Keymeulen | March 13, 2009 at 01:02 PM
Hi Thomas,
I would start directly with VB.NET: Microsoft is putting everything behind their .NET technology and VBA isn't really supported by them anymore (there's no native 64-bit version of VBA, for instance).
So go directly with VB.NET (or C#), using either standard Visual Studio or Visual Basic (C#) Express.
I would (of course :-) recommend using this blog as a resource, and you can post your questions to the AutoCAD .NET Discussion Group. If your company is serious about helping your customization work, they might also invest in an ADN membership.
Regards,
Kean
Posted by: Kean Walmsley | March 13, 2009 at 01:48 PM