I have some AutoLISP functions that run during document open (via acaddoc.lsp) and have to be modified to behave a little differently depending on the value of ACAD's visible property. (Basically, they have to detect when AutoCAD is running "invisible" so that they can change it to visible in order to allow an alert to appear, and then change it back.) In the process of testing and troubleshooting, I have discovered the code works exactly as I want (1) when AutoCAD is already running (visible), but screws up (2) when it is being launched (presumably visible, or not explicitly invisible).
To help see what was going on, I added an alert message to report the visible property (to my acaddoc.lsp which runs at document open). The alert indicates "true" for case (1), but for case (2) the alert indicates "false".
To add intrigue to this, if I run the alert twice, one right after the other, in case (2) the first alert will indicate "false", while the second will indicate "true". It appears that the act of issuing the alert changes the visible property (but I suspect it's not that simple).
It appears that AutoCAD considers itself "invisible" while it is launching, perhaps until acaddoc.lsp is finished running, or unless an alert is issued during its run. This is very unexpected, and complicates things for me.
Can anyone shed any light on this, and maybe suggest some way that I can account for it? Is there any way to distinguish between acad running explicitly invisible versus effectively (or temporarily) invisible during launch?
In case it helps, here is a variation on the code I added to my acaddoc.lsp to report the visible property:
(setq app (vlax-get-acad-object))
(cond
((= (vla-get-Visible app) :vlax-false) (setq getvis "false"))
((= (vla-get-Visible app) :vlax-true) (setq getvis "true"))
(T (setq getvis "limbo"));just in case it's possible
)
(alert (strcat "(1)Visibility is: " getvis))
(alert (strcat "(2)Visibility is: " getvis))
Solved! Go to Solution.
Solved by Gary_J_Orr. Go to Solution.
There are a few things to consider for your case (2) that will create different circumstances:
First the setting of "AcadLispAsDoc"... but, according to mention of "AcadDoc.lsp" in your post, I think that we can rule that out.
Second would be: how are you launching ACAD? Programmatically? Double-clicking on a drawing file in Explorer? etc.
But, in truth, you should never put any user interaction calls within AcadDoc.lsp unless it's called from within S:Startup.
From the help files there is a caution about similar calls (they reference any functions that call any "command" calls, but it holds true for any user interaction calls such as your alert box which requires user interaction to hit a button to close it):
"The startup LISP files (acad.lsp, acaddoc.lsp, and MNL) are all loaded into memory before the
drawing is completely initialized. Typically, this does not pose a problem,
unless you want to use the command function, which is not guaranteed
to work until after a drawing is initialized."
If you want to simply report a value of something during startup print it to the command line using Princ or wrap the call within a function and add a call to that function within a defun-q function that can be appended to the S:StartUp function.
All of this assumes that you are not launching ACAD via ActiveX calls. If this IS the case you must also explicitly set the visible property to true and manually activate the app/drawing.
Clear as the Missippi River? (which is sometimes called "The Big Muddy" in case you're not familiar with it)
Hope it helps,
-Gary
In my original post I (and my posted code) suggested that the message would change when running the alert twice in a row. What I meant to say (and post) was that the message would change when running the entire code twice in a row.
Here is the corrected code:
(setq app (vlax-get-acad-object))
(cond
((= (vla-get-Visible app) :vlax-false) (setq getvis "false"))
((= (vla-get-Visible app) :vlax-true) (setq getvis "true"))
(T (setq getvis "limbo"));just in case it's possible
)
(alert (strcat "(1)Visibility is: " getvis))
(setq app (vlax-get-acad-object))
(cond
((= (vla-get-Visible app) :vlax-false) (setq getvis "false"))
((= (vla-get-Visible app) :vlax-true) (setq getvis "true"))
(T (setq getvis "limbo"));just in case it's possible
)
(alert (strcat "(2)Visibility is: " getvis))
Thanks for your reply, Gary.
Just to confirm, I have things set up to run acad.lsp once only at application startup (ACADLSPASDOC = 0).
I am launching AutoCAD by dbl-clicking a DWG in Explorer, or by desktop shortcut (whose target = "C:\Program Files\Autodesk\AutoCAD 2013\acad.exe"). In either case, the check/alert in acaddoc.lsp reports acad's visible property as "false".
Once AutoCAD is running, if I dbl-click a DWG in Explorer, the file opens in the running session and the check/alert in acaddoc.lsp reports acad's visible property as "true".
"If you want to simply report a value of something during startup print it to the command line..."
I do this all the time, but for just a few special cases I need an alert to pop up in the user's face to be sure there is no excuse for not seeing the message. (Not seeing it is my fault; not reading it is their's.)
"...you should never put any user interaction calls within AcadDoc.lsp unless it's called from within S::startup."
I get this when it comes to the command function, and I guess I agree that the principle would/could/should apply to the alert function as well, but the warning in help seems to be referring to document initialization, not application initialization, so it still seems odd that application visibility would be reported as false while acaddoc.lsp is running in my case (2) scenario.
I would like to see if I can resolve this using the s::startup function, but in all my days using and customizing AutoCAD, I've never really understood it. I see it flash across the command line during launch or open, so it appears to be defined somewhere, but I don't know where it's coming from. I have not deliberately defined this function in any of my custom startup stuff. I'm currently doing a search for it, but do you know where exactly it might be coming from?
Correction:
It's actually "s::startup-load" that flashes across the commandline (then disappears altogether). Clearly not the same thing (but close).
Apparently there is no LSP or MNL file in my setup that defines an s::startup function.
Time to make one...
Here is a sample (ancient, from 2008 or so so there may be additional considerations now as there are new functions such as defun-q-list-get and defun-q-list-set that may be a replacement for the append function that you will see below) from an AcadDoc.lsp file that I built for a previous employer.
(defun-q Forum_startup ( / ) (if runupdate (progn (Princ "\nLoading Updater") (load "Functions\\Sys-Tools\\ACADConfig.lsp") (C:ACADConfig) (ACADSYSUPRESTART) );progn );if (if (= (getvar "dwgtitled") 1) (progn (setprojnumb) (setvar "proxygraphics" 1) (setvar "annoautoscale" -1) (setvar "LayerEval" 1) (setvar "LayerNotify" 0) (princ "\nResetting Drawing Scale List...\n") (command "-scalelistedit" "R" "Y" "E") ) ) (princ "\nStartUp Done.") (princ) );defun (if s::startup (setq s::startup (append s::startup Forum_startup)) (setq s::startup Forum_startup) )
Hope it helps
-Gary
"Your method of starting AutoCAD by double-clicking on a file can and will create a host of problems during startup...
...especially once you start doing any real customization that requires specific things to happen in a specific order (as in this case where you need full drawing initialization of the drawing before calling your alert function)."
I appreciate the warnings and words of wisdom, and this may be true, but the method has worked fine (until now, as you note). None of the things you list are issues in my case. The new variable in the equation is a third-party software that wants to use a running acad session to do things with drawings. We do not normally have any reason to run acad invisible, and I don't really think it is necessary, but the developer insists that it is faster and more reliable to do it this way. We discovered that things were getting hung up by one of my alerts, and the developer is either incapable or unwilling to take responsibility for resolving this on his end. It may eventually come back to him, but that will only add time and cost to the project. Since we are launching the AutoCAD session and running these startup routines, it seemed like it would be easier and made more sense for me to add the visibility checks and adjust the property as needed to conform to the new scenario. This stuff works exactly as expected in every scenario but this one. Who'd have thunk that acad's visible property would behave this way? It just makes no sense.
I am still working on it, but I'm hopeful that the s::startup thing will resolve it. I'll let you know how it turns out.
Thanks, again.
I don't think the 'visible' property is a reliable way to detect the case where AutoCAD was started for automation. Better would be to check the startup command line switches for the /automation switch (assuming that is how it is being started in your case). Unfortunately I don't know of any way to do this from pure AutoLISP. Kean Walmsley recently demonstrated how to do it from .NET. There might be some scripting object that could access the command line, but I don't know of one offhand.
Gary_J_Orr wrote:
I truly hate to be the bearer of bad news but... if you have alerts that pop up then you will never see them (as they are functioning within that "invisible" application and will therefore be invisible themselves) you will never be able to hit the "ok" button so that invisible Acad will sit there forever waiting you to answer that invisible prompt...
You will need to build the startup function and, within it test for the visible property, if ACAD is visible then make whatever calls and tests and alerts that you are performing, otherwise, don't make any of the user interaction calls (which may be exactly what you are trying to accomplish for all I know).
Exactly. Thus the reason for posting this topic. (And don't worry that you are in any way the "bearer of bad news". The news was already delivered to me by the situation itself.)
Gary_J_Orr wrote:
I also missed commenting on one of your other statements about document vs application initialization... when you double-click on a file you change some of the initialization processes... some application processes are still occuring even while it is trying to start the opening of the drawing... the two processes get a little out of sync as it were.
And this is now clear to me as the crux of the issue. As I began work on this, I was operating on the assumption that acad would be visible by default (unless explicitly "told" to be otherwise), but through this experience and exchange I have learned that this is not correct. It still strikes me as illogical, but as long as there is a way to deal with it, I will just accept it and move on.
"I don't think the 'visible' property is a reliable way to detect the case where AutoCAD was started for automation."
I appreciate the response, Owen, but I think if you read through the previous messages you will see that this does not describe my situation. The 3rd-party automation I'm dealing with relies on the user to launch acad "normally" (as s/he would for everyday use). So AutoCAD is always running "visible" when the automation "takes control" of the already running acad and makes it invisible for the duration of the operations it automates. My initial challenge was to ensure certain error condition alerts would appear when appropriate during document startup while acad was invisible, and the changes I had made were working exactly as they needed to work. They correctly detected that acad was invisible, made acad visible to display the alert, and then switched it back to invisible after the alert was dismissed. Perfect! The changes also worked perfectly fine when opening DWGs "normally", apart from the automation, with one exception.
Ironically, apart from the automation, when a user launches acad with a DWG file and there happens to be an error condition, the changes I made work exactly backwards because it detects that acad is invisible when I (reasonably, I think) assumed it would be considered "visible". I think (hope) there is a solution in the s::startup function, which I will find out today.
Well, as it turns out, the solution works for me but now it's causing a new problem with the 3rd-party program.
I don't know what's happening exactly, but while his program has control of acad and has turned it "invisible", if one of my alerts is triggered, AutoCAD is made visible and the alert can be seen and dismissed, but then the process stops. AutoCAD does not go back to invisible (so my routine is being interrupted somehow), and the 3rd-party app throws an error message indicating a problem opening the drawing. The DWG does open, but the expected process (in this case plot) doesn't occur.
So on we go... now the ball's in his court.
"You can always choose to log any information that you would have supplied to the user in a text file and pop the text file up afterwards or some such..."
Good thought - it seems awfully convoluted, but I will see if I can make that work.
Ironically, the way it works right now is actually "better" (IMHO) in that it prevents the user from completing the automated task without resolving the reason for the alert.
@dmfrazier wrote:"You can always choose to log any information that you would have supplied to the user in a text file and pop the text file up afterwards or some such..."
Good thought - it seems awfully convoluted, but I will see if I can make that work.
Ironically, the way it works right now is actually "better" (IMHO) in that it prevents the user from completing the automated task without resolving the reason for the alert.
Except for the fact that you have potential unhandled errors, associated variables, object references, etc. that that could end up crashing Acad at some point or other...