The right way to show modal and modeless dialogs in AutoCAD using .NET
My manager is currently sailing back from Honolulu to San Francisco, after his boat came 2nd in its division in the 2008 Pacific Cup (congratulations, Jim! :-), so I'm spending more time on management-related activities than I would normally. Which means I'm getting less time to spend on the fun stuff, such as researching blog posts: I'm plundering what I can from my email archives, but my output may feel a little thin over the next week or two.
Here's some information from an internal discussion that I thought might be of general interest.
The question:
Why is it important to use Application.ShowModalDialog() or Application.ShowModelessDialog()? The documentation for both these commands says "You must use this method instead of Form.Show[Dialog], which may lead to unexpected behavior." Any pointers as to what the "unexpected behavior" might be?
Here's the answer, provided by a member of the AutoCAD Engineering team:
There are a number of reasons to use Application.Show[Modal/Modeless]Dialog() rather than Form.Show[Dialog]:
- Dialogs will automatically pick up the icon of the host product
- Dialog size and position will be persisted automatically
- Other floating AutoCAD windows (e.g. the Properties palette) will be disabled, as needed
- The DIASTAT system variable will be set properly with the exit status of the dialog

Subscribe via RSS
I am a little confused. If I build a form with the Visual Studio UI designer, it will extend Form. Do you mean, I cannot then do myForm.ShowDialog()? How am I supposed to use the Editor?
Posted by: namin | August 07, 2008 at 09:46 PM
Oh, OK. I think I got it. I am using ObjectARX 2007, in which it's not Editor but Application. So I am supposed to use Application.Show... Thanks, I didn't know that.
Posted by: namin | August 07, 2008 at 09:48 PM
Namin -
My mistake. My edits were incorrect: I should have put Application instead of Editor. I'm fixing the post.
My apologies,
Kean
Posted by: Kean | August 07, 2008 at 10:09 PM
My experience with the Application.ShowDialog or Application.Show ist that it works fine with a parent or main form. However, if I have child forms that spawn after a button click, then the Application.ShowDialog functions are not reliable. Unfortunately, I don't have a specific example to submit to you or DevHelp to show you what I mean. But the long and short of it is that I use the Application.Show functions for generating the parent form, and then I use the forms built-in / inherited method of .Show for the child dialogs.
Posted by: Jon Szewczak | August 08, 2008 at 01:40 PM
Thanks for the input, Jon. I'm sure people will find it useful.
If you do come across a reproducible case, please do submit it via DevHelp.
Regards,
Kean
Posted by: Kean | August 08, 2008 at 01:42 PM
"2. Dialog size and position will be persisted automatically"
This probably not .NET API issue, but the automatic persisting could be a problem, when you sometimes have to connect your computer to different number of monitor. Say, if you use your laptop in office with 2 screens, you place one of your .NET API dialog box (modal!) on second screen and close it there. Then you carry your laptop to a presentation with a projector (only one screen), start AutoCAD, run your commend to show the dialog box. Now your AutoCAD would appear frozen without reason. You can only kill the Acad process from task manager. That is because the dialog box is shown somewhere outside the screen (the persisted position on second screen). I was embarrassed when running into this in the exactly situation, and I could not show anything in that presentation until I came back to my desk, connected back to my second screen, dragged the dialog box back to primary screen and close it from the primary screen.
So, if I want to show a dialog box, and the first 3 reasons you listed are not important to me (1. I'd like my own icon; 2. I do not want Acad remember dialog box location, it should always on primary screen, and 3. Since it is dialog box, one cannot access other Acad window anyway), what other unexpected behaviors would be if I simply use System.Windows.Forms.Form.ShowDialog()?
Of course, if Acad is clever enough to detect if the persisted location is valid in available screen(s), if not, show dialog box in primary screen, then the reason 2 would be a benefit as you say.
Posted by: Norman Yuan | August 16, 2008 at 12:37 AM
I haven't checked, so you might want to see if the runtime automatically hides and unhides forms that are not shown via the Application methods, before/after the form code calls a GetXxxxx() method of the Editor.
Posted by: Tony Tanzillo | August 16, 2008 at 07:28 AM
Yes - Tony's point is likely to be a concern for modeless dialogs not displayed using ShowModelessDialog().
Around the dialog display issue: one option, in lieu of AutoCAD checking the bounds of a dialog before display, would be for you to manipulate (or simply remove) the location information stored for the dialog:
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R17.2\ACAD-7001:409\Profiles\AutoCAD\Dialogs\MyApplication.MyForm
Regards,
Kean
Posted by: Kean | August 16, 2008 at 02:34 PM
Hi,
Posted by: Vignesh. S | March 04, 2009 at 05:36 AM
Hi,
Sorry for the previous mail. Wrongly activated the post button.
I have a doubt regarding modal dialogs. Is there any possibility to detect whether any modal dialog is opened on current autocad application. If so, is there any possibility to close those modal dialogs programmatically?
Thanks and Regards,
Vignesh. S
Posted by: Vignesh. S | March 04, 2009 at 05:39 AM
AutoCAD is not fundamentally single-threaded in nature (although it does use multi-threaded runtime DLLs), so when a model dialog is open, it has the execution thread.
Are you trying to check this from an external COM application? If so, you're probably going to get some kind of COM server time-out that you might be able to trap programmatically and then use SendKeys to fire off some escape characters to the application, hoping to cancel the open dialog(s).
This is really a topic for the discussion groups (or the ADN team), so please direct your follow-up questions there.
Kean
Posted by: Kean Walmsley | March 04, 2009 at 09:59 AM
Hi Kean,
I have a similar exception to that Posted by: Jon Szewczak | August 08, 2008 at 01:40 PM, above.
He did not specify, but my issue is with a Modeless dialog that I display as a child to several different Modal Parent forms. All of my other forms work fine with Application.ShowModal/ShowModelessDialog, but this particular form comes up correctly the first time it is shown, then the second time it is shown, all of the controls on the form are visible, but disabled. Then from that point on, every time you show the form all of the controls are invisible. I switched just that one call to the normal form.show and it works again. This is a repeatable problem, but it is a fairly large project for submitting to someone (I have also not yet convinced my company to spring for ADN). I could probably strip a bunch of unrelated stuff out, and attempt to simplify the project while maintaining the unusual behavior, if you want.
Posted by: David Osborne | April 09, 2009 at 12:31 AM
Hi David,
Modeless dialogs are intended for top-level modeless input (e.g. Property Palettes, Tool Palettes, etc.). I haven't heard of them being launched and used within a particular modal context (i.e. with a number of other modal dialogs being displayed).
I'm actually surprised this has ever worked, to be quite honest.
Regards,
Kean
Posted by: Kean Walmsley | April 09, 2009 at 09:20 AM
Based on part of your comment, I was unclear in that there is only one modal parent form each time this modeless dialog might be displayed, but there are multiple modal forms that are potential parents for this form.
The idea is that this form contains options which apply to several different types of objects (physical objects, not programming) and each of those different types of objects has its own placement form.
Rather than recreate the same set of controls on several forms(or make a user control to replicate), I decided to make a seperate form, and I chose to make it modeless so that if the user hits the 'more >>' button, it shows the additional options form, but the user can still pick controls on both the parent form and the child. Essentially these choices were made to try and accommodate a request from my user group.
Posted by: David Osborne | April 13, 2009 at 07:54 PM
That particular API asks AutoCAD to host the modeless form (and my understanding was this would be hosted as a top-level modeless form, not beneath one or more modal forms).
You should be able to do what you want by calling Form.Show(), although this means you won't get the 4 advantages listed in the article.
Kean
Posted by: Kean Walmsley | April 14, 2009 at 08:39 AM