I just want to draw a pline on the screen and get the pline objectid and continue the next step code, but it seems the sending command 'pline' always starts in the end of all the code. could you help me to solve this problem?
the following code was copy from kean's blog, I try to add one line of code after the 'PLINE' command, but alert dialog shows before let user select pline point.
using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; namespace revMarkCreate { public class MyPlineCmds1 : IExtensionApplication { // Flag used to check whether it's our command // that launched PLINE private static bool myCommandStarted = false; public void Initialize() { Document doc = Application.DocumentManager.MdiActiveDocument; doc.CommandEnded += new CommandEventHandler(plineCommandEnded); } public void Terminate() { Document doc = Application.DocumentManager.MdiActiveDocument; doc.CommandEnded -= new CommandEventHandler(plineCommandEnded); } [CommandMethod("MYPOLY1")] public void MyPoly() { // Set the flag and launch PLINE myCommandStarted = true; Document doc = Application.DocumentManager.MdiActiveDocument; doc.SendStringToExecute("_PLINE ", false, false, false); //I want to let the 'PLINE' command run before the alertdialog shows Application.ShowAlertDialog("test"); } private void plineCommandEnded(object sender, CommandEventArgs e) { if (myCommandStarted && e.GlobalCommandName.ToUpper() == "PLINE") { // We're just performing a simple check, so OK.. // We could launch a follow-on command, if needed Document doc = Application.DocumentManager.MdiActiveDocument; PromptSelectionResult lastRes = doc.Editor.SelectLast(); if (lastRes.Value != null && lastRes.Value.Count == 1) { doc.Editor.WriteMessage("\nThe entity is: " + lastRes.Value[0].ObjectId); } myCommandStarted = false; } } } }
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
This is a well known issue:
- SendStringToExecute does not run synchronously.
- SendCommand (the COM method) may not be completely synchronous.
To synchronously run a command, you have to P/Invoke acedCmd or acedCommand, or better, use Tony Tanzillo's wrapper for the undocumented runCommand() method.
You'd rather use the runCommand wrapper shown in the link I provided.
Anyway, if you indeed want to p/invoke acedCmd:
For A2013 and later
[System.Security.SuppressUnmanagedCodeSecurity] [DllImport("accore.dll", EntryPoint = "acedCmd", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] extern static private int acedCmd(IntPtr resbuf); public static void Command(ResultBuffer args) { acedCmd(args.UnmanagedObject); }
For prior versions, replace accore.dll with acad.exe.
In the meantime, invest the time in adding drawing entities directly (as opposed to sending commands). Its well worth the effort.