Author Topic: Command not working in CommandEnded Event  (Read 2940 times)

0 Members and 1 Guest are viewing this topic.

flyte

  • Newt
  • Posts: 26
Command not working in CommandEnded Event
« on: September 20, 2017, 12:06:32 AM »
I have a command that calls upon some editor commands to eventually perform an export (to dwf):

Code: [Select]
[CommandMethod("X3")]
        public static void X3()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            var currentFilename = doc.Name;
            var currentPath = Path.GetDirectoryName(currentFilename);
            var drawing = Path.GetFileNameWithoutExtension(currentFilename);
            var fileWithDwfExt = Path.ChangeExtension(drawing, ".dwf");

            var destFile = Path.Combine(currentPath, fileWithDwfExt);

            XrefUtils.DetachAllXrefsCommand();
            LayerUtils.Layerson();
            LayerUtils.ThawAll();
            ed.Command("-xref", "d", "*");
            ed.Command("export", destFile, "a", "y");
        }

This works just fine when executed via the AutoCAD commandline, however when the same routine is called in response to the Command* events:

Code: [Select]
public void Initialize()
        {
            Application.DocumentManager.DocumentCreated += DocumentManager_DocumentCreated;
            foreach (Document doc in Application.DocumentManager)
            {
                doc.CommandEnded += OnCommandEnding;
            }

        }

Code: [Select]
public static void OnCommandEnding(object sender, CommandEventArgs e)
        {
             X3();
        }


it fails with the following exception:
Code: [Select]
System.Exception {Autodesk.AutoCAD.Runtime.Exception}

with
Quote
"eInvalidInput"
as a message.

Anyone know what I'm doing wrong?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Command not working in CommandEnded Event
« Reply #1 on: September 20, 2017, 03:54:10 AM »
Hi,

As far as I know, you cannot call a command from an event handler (either using SendStringToExecute, SendCommand or Command).
Speaking English as a French Frog

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: Command not working in CommandEnded Event
« Reply #2 on: September 27, 2017, 01:23:53 AM »
In this sort of situation the Application.Idle event can be your friend to insuring that your code is running from the proper state, just add your callback function to the list then remove it once it's been called.

Code - C#: [Select]
  1.            
  2.         {
  3.              //code not running in application context
  4.              Autodesk.AutoCAD.ApplicationServices.Application.Idle += Application_Idle;
  5.         }
  6.  
  7.         static void Application_Idle(object sender, EventArgs e)
  8.         {
  9.             Autodesk.AutoCAD.ApplicationServices.Application.Idle -= Application_Idle;
  10.             //do stuff from application context
  11.         }

flyte

  • Newt
  • Posts: 26
Re: Command not working in CommandEnded Event
« Reply #3 on: November 01, 2017, 05:15:12 PM »
Hi,

As far as I know, you cannot call a command from an event handler (either using SendStringToExecute, SendCommand or Command).

So my command is successfully executing when one does a qsave or clicks the save toolbar button (seems to also issue a qsave command). But how do I react when the user does it through the dialog when it prompts you if you want to save upon exit? This doesnt' seem to trigger the CommandEnded event.. how would I solve this?

flyte

  • Newt
  • Posts: 26
Re: Command not working in CommandEnded Event
« Reply #4 on: November 01, 2017, 06:23:03 PM »
..actually I think I solved this by hooking into the e.Document.Database.SaveComplete command instead.. so now any save method will trigger my export, (I exclude autosave tho)

flyte

  • Newt
  • Posts: 26
Re: Command not working in CommandEnded Event
« Reply #5 on: January 16, 2018, 11:51:24 PM »
I do trigger my export during the SaveComplete event:
Code: [Select]
public void Initialize()
{
Application.DocumentManager.DocumentCreated += DocumentManager_DocumentCreated;
foreach (Document doc in Application.DocumentManager)
{
doc.Database.SaveComplete += OnDatabaseSaveComplete;
}
}
       

and my event handler:

Code: [Select]
private void OnDatabaseSaveComplete(object sender, DatabaseIOEventArgs e)
{
// ignore when the document is being auto saved
if (e.FileName.Contains(".sv$"))
return;

Document doc = Application.DocumentManager.MdiActiveDocument;
var currentFilename = doc.Name;
if ((currentFilename.Contains("-CSA-")) ||
(currentFilename.Contains("-S-")) ||
(currentFilename.Contains("-B-")) ||
(currentFilename.Contains("-F-")))
{
ExportTo3dDwf();
}
}

and ExportTo3dDwf detaches all xrefs and thaws all layers... but my intention is to not modify the database.. I want to leave the DWG as is before I detach xrefs and thaw layers in preparation to export to dwf.

So I am using some of the nifty routines found here.. this is the how I am Thawing all layers:

Code: [Select]
[CommandMethod("Thawall")]
public static void ThawAll()
{
Database db = HostApplicationServices.WorkingDatabase;
LayerTableRecord layer;

string curLayer = (string)Application.GetSystemVariable("CLayer");
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
foreach (ObjectId layerId in lt)
{
layer = tr.GetObject
(layerId, OpenMode.ForWrite) as LayerTableRecord;
if (layer.Name != curLayer)
layer.IsFrozen = false;
}
tr.Commit();
Application.DocumentManager.MdiActiveDocument.Editor.Regen();
}
}

So how can I do this, and NOT save / modify the DWG? I have tried removing the commit, but it still modifies the DWG.

In some old LISPs, I see
Code: [Select]
(acad-push-dbmod) to prevent saving the changes to the drawing. How do I do that in C#?

n.yuan

  • Bull Frog
  • Posts: 348
Re: Command not working in CommandEnded Event
« Reply #6 on: January 17, 2018, 09:37:30 AM »
Look into this:

Autodesk.AutoCAD.ApplicationServices.Document.PopDbMod()/PushDbMod().

Here is the quote from ObjectARX Reference Guide:

<QUOTE>

This method copies the current value of the DBMOD system variable onto a stack. This allows you to save the current value of the DBMOD read-only system variable for subsequent restoration through the popDbmod() method.

pushDbmod() and its counterpart popDbmod() allow your application to modify a database without having it marked as modified, as is commonly done by applications during edit session initialization. This includes modification of database header variables or adding to and modifying objects in the database being edited, which all cause flags in the document system variable DBMOD to be set. When DBMOD is non-zero, the 'Save your drawing?' prompt is posted when a user attempts to quit out of a drawing. To avoid this prompt in your application, stack the current DBMOD value with pushDbmod() before beginning to modify the database in a manner that should not cause this query, restore DBMOD with popDbmod() when such modifications are complete.

</QUOTE>