How to wait for AutoCAD document to finish loading before proceeding in code

Hi,
We have a Matlab application creating and working with AutoCAD drawings through COM interface. This is buggy, sometimes it works and mostly not. I have tracked down the issue to the following:
When creating the drawing, I have tried to add pause at different ranges before proceeding in the code, but this does not seem to be sufficient. The issue we are facing is that the COM object (AutoCAD drawing document) does not load correctly or fully. I have verfied this by converting it to a structure and using fieldnames() to get the different fields. A fully loaded object returns a large number of fields, but most times only a fraction is returned.
We need to find a way to loop or wait until the document is loaded and ready before we can proceed with manipulating it. This far, I have not been able to find a suitable solution and any help is wanted.
Br
Fredrik Walka

7 commentaires

Mario Malic
Mario Malic le 8 Fév 2023
Modifié(e) : Mario Malic le 8 Fév 2023
Hey,
I don't use the AutoCAD, but quick search led me to this AcApDocManagerReactor: https://help.autodesk.com/view/OARX/2023/ENU/?guid=OARX-RefGuide-__MEMBERTYPE_Methods_AcApDocManagerReactor
Under link, see documentCreated method and check if that is what you are looking for. It is actually a notification/event thing, so it probably might not be, but if you dig around (maybe AcApDocument class), I am preety sure you'll find the way.
Hi Fredrik Walka,
As per my understanding, you would like to synchronize loading of document and have the main script wait for the read operation to complete.
To better assist you with the issue you are facing, it would be helpful if you could share your code or share the command you are using to load the document.
Fredrik Walka
Fredrik Walka le 16 Août 2023
Modifié(e) : Fredrik Walka le 24 Août 2023
Hello,
This work has been postponed, but not resolved yet, so I have some more info on this case.
if obj.OK==1
% Add new drawing drawing
path = getPath;
targetDir = path.ProgramData;
obj.docHandle = invoke(obj.cadHandle.Application.Documents, 'Add',[targetDir,'\',obj.template]);
try
invoke(obj.docHandle, 'Activate');
invoke(obj.docHandle, 'SaveAs', obj.fileName, 36);
catch
obj.OK = 0;
warndlg('A drawing with this name is open, close it first!','WARNING');
end
if obj.OK == 1
feature('COM_SafeArraySingleDim', 1);
obj.cadHandle.Application.ZoomAll();
end
This is part of other code, but the main issue is the add document line, that sets the doccument handle. This handle will in most cases only provide partial data of the AutoCAD document, which can differ from time to time. Sometimes, all data is there and it works as intended.
Below are differences between ActiveX COM and .NET interfaces, in document object data accessible. Moving to .NET would solve this issue but introduce a number of others, both property data issues and the dreaded time-out issue we encountered in other applications (.NET Windows Form).
Edit: removed images
With ActiveX, mostly only partial fields, methods and properties are exposed and returned.
With .NET, all fields, mehtods and properties are exposed and returned.
BR
Fredrik Walka
We can't really write something sensible on this. I would suggest you to avoid using struct on objects as this may expose their hidden members that are not supposed to be public, use methods and properties instead. I would also verify that variables/object that you are showing is of the same type with class.
Fredrik Walka
Fredrik Walka le 24 Août 2023
Modifié(e) : Fredrik Walka le 24 Août 2023
The class is basically the same, only difference is the handle to AutoCAD, either COM ActiveX or as .NET.
The main issue is that using ActiveX, unless having a lucky day, only some fields are made available from the document object (ActiveX handle). This amount of fields may vary between tries. With .NET all of them seems to be loaded and available as intended, but this is very often not the case with ActiveX COM connection.
So, how do I ensure, that the ActiveX COM object handle returns all fields, methods and properties it should, not only a fraction?
When the AutoCAD document is loaded, I'm using altering the document in code. I then expect to have access to certain fields and properties, that I do not have when the COM object is not loaded correctly.
Ex.
An AutoCAD document is supposed to have a field/property called Layers. Using ActiveX, this field is often not returned or accessible, making code fail while trying to access the field. With .NET, this field seems to always be accessible.
Stepping through the code makes no difference using ActiveX COM handle to AutoCAD document. There seems to be no timing issue running the code or stepping through. It's like the COM handle creation does not care if the handle has fully loaded or not, only taking a snapshot of the object.
Using .NET and stepping through the code, there is a notable delay when the document handle is created and before the code proceedes. Here, it seems as Matlab actually waits for the full object to load before proceeding.
Br
Fredrik Walka
One thing you can try is to simply set a pause for several seconds and see if the properties are added after this time. Of course, it's not a great solution but it could reveal if what you are doing is right and document is opening in a corect way.
There is some info here https://forums.autodesk.com/t5/net/how-to-determine-when-a-document-is-completely-loaded/td-p/2684614 about the EndOpen event which could be a way to solve this.
Hi again,
After some research, I have made some changes to my code.
First, I have replaced requests of data from using ActiveX dot notation to access child objects at different levels. I know set local variable(s) and use get() to ensure I get the COM interface object correct.
Ex.
modelspace = get(obj.cadHandle.ActiveDocument,'ModelSpace');
retval = invoke(modelspace,'AddText',txt,position',textHeight);
obj.WaitForAutoCAD;
%retval = obj.cadHandle.activeDocument.modelSpace.AddText(txt,position',textHeight);
The commented code is the original. These fixes seems to have solved the undefined method/property errors.
I also created a function to wait for AutoCAD to be ready for further commands, since I got the Call was rejected by callee error alot. Adding this after every command manipulating the document seems to work as well. The code for this looks like:
function WaitForAutoCAD(obj)
while 1
try
retval=obj.cadHandle.Application.GetAcadState;
v = retval.IsQuiescent;
if v == 0
pause(1);
else
break;
end
catch err
%disp(err);
% Do nothing, just keep looping
end
end
end

Connectez-vous pour commenter.

Réponses (0)

Catégories

Produits

Version

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by