Cancelling an active command in AutoCAD
Thanks to Alexander Rivilis for this topic (he submitted a comment to my previous post that got me thinking about this addendum).
When you're asking AutoCAD to execute commands by submitting them to its command-line, it helps to make sure no command is currently active. The accepted approach is to send two escape characters to the command-line... this is adopted by our menu & toolbar macros that consistently start with ^C^C in MNU and now CUI files.
Why two? The first is to cancel the "most active" command, and the second is to drop out of either the dimension mode or the outermost command, if the innermost was actually being executed transparently. Strictly speaking there are probably a few cases where you might actually need three escape characters. Type "DIM VERT 'ZOOM" into the command-line, and you'll need three escapes to get back to the "Command:" prompt, but that's fairly obscure - two is generally considered enough for most realistic situations.
So... what constitutes an escape character? Well, luckily we no longer need to thumb back to the ASCII table in the back of our AutoCAD R12 Programming manuals to find this out. It's ASCII code 27, which is represented as 1B in hexadecimal notation.
A common way to send the character from C++ is to send the string "\x1B" for each escape character to AutoCAD. From VB you would tend to use Chr$(27) for the same purpose.
In terms of your choice for sending the character(s) across to AutoCAD... you can generally use one of the functions suggested previously, sendStringToExecute(), SendMessage() or SendCommand(). It won't work from ads_queueexpr(), but then given its typical usage context you shouldn't need to use it for this. Also, as Alexander very rightly pointed out in his comment, you might use PostMessage() or acedPostCommand() (more on this second one later).
SendMessage() and PostMessage() are very similar - you can check this article for the differences. I tend to prefer SendMessage() for synchronous use, as it waits to have an effect before returning, but PostMessage() is still good to have around in the toolbox (it's good for firing off keystrokes into a window's message loop).
acedPostCommand() is another undocumented function, which needs declaring in your code before use:
extern Adesk::Boolean acedPostCommand(const ACHAR* );
What's particularly interesting about this function is its use of the special keyword, which should get you back to the "Command:" prompt irrespective of command nesting:
Then, of course, you can continue to use it as shown in my previous post:
acedPostCommand(_T("_POINT 6,6,0 "));
One quick note about cancelling commands from acedCommand(). If you pass RTNONE as the only argument to acedCommand(), this will be interpreted as an escape by AutoCAD.