AutoCAD Map 3D Developer
Welcome to Autodesk’s AutoCAD Map 3D Developer Forums. Share your knowledge, ask questions, and explore popular AutoCAD Map 3D Developer topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Cancelling a pending command line before calling Editor.GetPoint

2 REPLIES 2
Reply
Message 1 of 3
Anonymous
969 Views, 2 Replies

Cancelling a pending command line before calling Editor.GetPoint

Hello people,

 

I'm working on an application that run as an AutoCAD palette. Among various things, my palette has some buttons working as shortcut for some command line like "PAN" ou "ZOOM W", some other making more complex things, including waiting for the user to select a point with Editor.GetPoint(), and a Cancel button.

 

Each of my control button begin with a cancellation command to be sure we clear any running command before going for the next.

Before AutoCAD 2015, my cancellation sub was a call to acedPostCommand("CANCELCMD") and everything was fine. It's not supported anymore and I have some trouble to replace it with something working every time.

 

For now, my solution is to send some escape character with Document.SendStringToExecute. The last case that doesn't work is when there is a pending command line and I try to cancel it before making an Editor.GetPoint in the same call. The cancellation fails and the GetPoint immediately returns a PromptStatus.Cancel. If I make a cancellation alone (with my cancel button), it works.

 

What do I miss ?

 

Here's a code example for clarity :

 

public partial class PaletteTest : UserControl
    {
        public PaletteTest()
        {
            InitializeComponent();
        }
        
        private void buttonPANcmd_Click(object sender, EventArgs e)
        {
            CancelRunningCommand();
            ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute("_.PAN ", true, false, true);
        }

        private void buttonZoomWcmd_Click(object sender, EventArgs e)
        {
            CancelRunningCommand();
            ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute("_.ZOOM _.W ", true, false, true);
        }

        private void buttonGetPoint_Click(object sender, EventArgs e)
        {
            Document doc = ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            
            ApplicationServices.Application.DocumentManager.MdiActiveDocument.Window.Focus();

            Debug.WriteLine("quiescent 1 : {0}", doc.Editor.IsQuiescent);
            CancelRunningCommand();                 // Fail to cancel any pending command line
            Debug.WriteLine("quiescent 2 : {0}", doc.Editor.IsQuiescent);

            PromptPointResult ppr = ed.GetPoint("click somewhere"); // immediately return PromptStatus.Cancel if there is a pending command line
            if (ppr.Status != PromptStatus.OK)
                return;
            
            MessageBox.Show(string.Format("clicked on {0:N4}, {1:N4}", ppr.Value.X, ppr.Value.Y));
        } 

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            CancelRunningCommand();
        }

        private void CancelRunningCommand()
        {
            Document doc = ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            string cmds = (string)ApplicationServices.Application.GetSystemVariable("CMDNAMES");
            string esc = string.Empty;

            if (cmds.Length > 0)
            {
                // case of a command line command to be cancelled
                int cmdNum = cmds.Split('\\').Length;
                for (int i = 0; i < cmdNum ; i++)
                {
                    esc += "\x03";
                }
                doc.SendStringToExecute(esc, true, false, true);
            }
            else if (! doc.Editor.IsQuiescent)
            {
                // case of a prompt to be cancelled
                esc = "\x03";
                doc.SendStringToExecute(esc, true, false, true);
            }
            else
            {
                // nothing to cancel                
            }
        }
    }
2 REPLIES 2
Message 2 of 3
norman.yuan
in reply to: Anonymous

Firstly, since this is really a generic AutoCAD .NET API programming topic, you may want to post to .NET forum to reach more interested readers.

 

I think the issues is due to the Editor.GetXxxx() being called after SendStringToExecute() (inside the CancalRunningCommand() method). In this case, the code in the buttonGetPoint_Click() keeps going without waiting for the SendStringToExecute() being completed (that is, the SendStringToExecute() only get run when the code is waiting for user to pick point.

 

SendStringToExecute() should be only used as the last line of code being executed between an full cycle of user interaction with AutoCAD.

 

Because PaletteSet is a floating UI that should be running in application context and interact with active document out of multiple documents, this poses a challenge for us programmers to code it correctly in some cases, such as what you are intended to do: if AutoCAD is in the middle of command, what user action on PaletteSet can do to the active command.

 

While there is possibility to do this or that, I'd first follow known AutoCAD behaviour, Take AutoCAD's property paletteset window as example. It has "Select Object" and "Quick Select" button, so that user can click them and select in Editor. However, if there is a command active, such as waiting user to enter keyword or to pick point, clicking these 2 buttons does nothing (or prompt for invalid input), the active command still waiting to be continued/cancelled by user. If we think about it, it is only logically make sense: a command against the current drawing is waiting to be completed, and should not be unconditionally cancelled by outside app easily.

 

Another example: opening Design Center. We all know we can insert block from design center by dragging a block/layer/text style... from design center into current drawing, right? Well, if there is command active in AutoCAD, one cannot drag anything into current drawing.

 

So, I think, instead of trying to cancel whatever active command in custom paletteset's action, the paletteset action should first check if there is active command running (and waiting for user input). If yes, the paletteset action should be aborted with or without prompting user. That is, our custom paletteset should behave the same way as AutoCAD built-in PaletteSet, so that user is not surprised by our custom app.

 

That my thought after trying different code based on yours.

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 3
Anonymous
in reply to: norman.yuan

I'm a bit late for that, but thanks for that answer.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost