Jump to content

vlr-dwg-reactor or vlr-docmanager-reactor


lfe011969

Recommended Posts

Has anyone successfully used either of these two reactors to initiate some code right after a drawing has been opened? I have a lisp that allows the user to select a template to start a new drawing and this works fine. Once the template drawing is opened, I'd like to have a lisp that displays a dialog where the user can populate various drawing properties which are then stored in custom drawing fields.

 

Here's what I have so far:

 

The code to open the template file:

(defun open_template ()
   (load "open_reactor.lsp") ;; Loads the reactor lisp
   (c:myreact) ;; Starts the reactor
   (vla-activate (vla-add (vla-get-documents (vlax-get-acad-object) template_name)) ;; template_name is obtained in a different subroutine
)


 

The reactor code from open_reactor.lsp:

(defun c:myreact ()
   (if myreact (vlr-remove myreact))
   (setq myreact (vlr-dwg-reactor nil '((:vlr-endDwgOpen . DoAfterOpen))))
   (vlr-set-notification myreact 'all-documents)
)

(defun DoAfterOpen ( Caller CmdSet )
   (c:load_dwg_props)
   (clear_open_react)
)

(defun clear_open_react ()
   (if (and (myreact (vlr-added-p myreact))
       (vlr-remove myreact)
   )
)

 

 

I've tried every relevant drawing opening reactor callback for vlr-dwg-reactor and when I couldn't get any of them to work correctly, I then read about vlr-docmanager-reactor and so I tried all the relevant callbacks for that reactor too. Still it never quite works.

 

The load_dwg_props.lsp does get executed for a few of the callbacks but it always executes before the template is completely opened and after entering all the data into the dialog box and clicking the "Update Drawing Data" button, a check of the drawing properties box shows no custom fields :(. Yet if I run the load_dwg_props.lsp immediately after the drawing finishes opening, all the custom fields are created.

 

So my question is this: Is there any way lisp-wise to accomplish what I'm trying to do? I've read enough to know I could use ObjectARX or VB.NET to do this but since I still don't know LISP that well, I am hesitant to begin learning something that has a much steeper learning curve.

Link to comment
Share on other sites

Lee,

 

I reread my post and now realize I wasn't clear enough. In addition to having the load_dwg_props.lsp in my acaddoc.lsp so that it can be executed whenever it is called through c:load_dwg_props, I would also like to have this code executed automatically after the user selects a template to start a new drawing in a separate lisp. In our templates we are using fields tied to custom drawing properties as the data for our titleblocks. After opening a template, all fields show as "----" since the custom drawing property has not been loaded yet. I was just thinking it would be nice if immediately after starting a new drawing from our template lisp the Load Drawing Properties routine start.

Link to comment
Share on other sites

Do you have the load_dwg_props loaded & executed in the ACADDOC.lsp?

 

When a user selects a template to start a new drawing, is the ACADDOC.lsp not loaded following this action?

 

Lee

Link to comment
Share on other sites

Do you have the load_dwg_props loaded & executed in the ACADDOC.lsp?

 

When a user selects a template to start a new drawing, is the ACADDOC.lsp not loaded following this action?

 

Lee

 

Yes to both questions. The only lisp I don't have loading automatically in my acaddoc.lsp is the open_reactor.lsp. This is because I only want this to load immediately right before the selected template is opened in a new window. Then immediately after the template has been opened, the reactor is cleared so that opening other drawings does not fire the reactor.

Link to comment
Share on other sites

Yes to both questions.

 

So if the load_dwg_props LISP is set to execute from the ACADDOC.lsp, which is being loaded when the user selects a template to start a new drawing - surely this is accomplishing your goal and the reactor is not needed, no?

Link to comment
Share on other sites

There are only two scenarios where I want the load_dwg_props.lsp to run:

 

1) Each time the user runs the new_project.lsp to begin a new drawing

2) The user types "load_dwg_props" in the command line.

 

If I add (c:load_dwg_props) to my acaddoc.lsp then the program runs every time a new drawing is started or every time an existing drawing is opened. I was thinking the only way to get the load_dwg_props.lsp program to automatically run when a template is opened from the new_project.lsp was to use a reactor.

 

I hope I'm being clearer. When I post messages on any message board, I'm always worried that I will either sound stupid or lame :oops:

Link to comment
Share on other sites

I'm just trying to offer an alternative route - I would try to avoid reactors where possible, it makes things simpler sometimes.

 

Perhaps use a test condition in the ACADDOC.lsp, i.e.

 

(load "load_dwg_props" nil)

(if (and c:load_dwg_props <Some Test Condition>)
 (c:load_dwg_props)
)

 

Lee

Link to comment
Share on other sites

Suddenly the lightbulb is coming on :idea:

 

So I guess I could have the new_project.lsp set a value for a variable that when tests true in the acaddoc.lsp, the load_dwg_props.lsp gets executed. Then I could have the load_dwg_props.lsp reset the value of the variable so that it tests false the next time any drawing is opened or started. Then only the new_project.lsp will set the condition so that the load_dwg_props.lsp initializes.

 

I will play around with this concept and report back my findings. As always Lee, thanks for your help!!

Link to comment
Share on other sites

I will play around with this concept and report back my findings. As always Lee, thanks for your help!!

 

You're welcome :)

 

I'm just providing the inspiration - you did all the work :)

Link to comment
Share on other sites

Ok so nothing I do works :cry:

 

I added this to my acaddoc.lsp:

(if (and c:load_dwg_props (= *TEST* "YES"))
 (c:load_dwg_props)
)

 

 

I also added these two lines to the new_project.lsp right before the command is invoked to open the selected template:

(setq *TEST* "YES")
(vl-propagate '*TEST)

 

 

Finally at the end of the load_dwg_props.lsp, I reset the *TEST* variable to nil:

(setq *TEST* nil)
(vl-propagate '*TEST)

 

 

So after the new template is loaded, the load_dwg_props.lsp doesn't execute. However when I type:

Command: load_dwg_props

 

at the command line, the routine runs. I tested for the value of my test variable both before and after running the load_dwg_props.lsp and the values are as they should be: "YES" before running the lisp and "nil" after.

 

Now my head hurts :ouch:

Link to comment
Share on other sites

I wouldn't use the Global, as the namespace is wiped when the drawing is closed and the global won't appear in the new drawing namespace (I know you have used vl-propagate, but this won't work as the drawing is opened when it is executed).

 

Perhaps using setenv/getenv to store the value in the registry under:

 

(strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\FixedProfile\\General")

 

I would rely on the Globals keeping their value between drawings with so many codes running at different times.

Link to comment
Share on other sites

Thanks Lee, your suggestion to use a registry key as the test works the way I want. I added this to my acaddoc.lsp:

 

(setq reg_key (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) \\Fixed Profile\\General"))
(setq read_reg_key (vl-registry-read reg_key "TEST"))
(if (= read_reg_key "YES")
   (c:load_dwg_props)
)

 

 

Then in my new_project.lsp, right before the command to open the template, I added:

(vl-registry-write reg_key "TEST" "YES")

 

 

Finally, in the load_dwg_props.lsp I added this line to the top of the code:

(vl-registry-write reg_key "TEST" "NO")

 

 

I've tested this over and over and it works now but I'm sure there will be some situation or configuration where this code might not work. Is there anything you would suggest to improve this code?

 

Thanks again.

Link to comment
Share on other sites

Glad it works Lonnie! :)

 

There may have been some confusion over my earlier post, you could replace:

 

(setq reg_key (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) \\Fixed Profile\\General"))
(setq read_reg_key (vl-registry-read reg_key "TEST"))

With just:

 

(getenv "TEST")

Similarly:

 

(vl-registry-write reg_key "TEST" "YES")

With:

 

(setenv "TEST" "YES")

In my earlier post, I was noting that these functions (getenv/setenv) will read/write the key to this location:

 

(strcat "HKEY_CURRENT_USER\\" (vlax-product-key) \\Fixed Profile\\General")

Apologies for the confusion - of course, both solutions would function identically.

 

I would suggest that you use a little more unique registry key (instead of "TEST"), such as "IFE_Test" or something that would be less likely to already appear in the registry - since, there is the slight chance that existing entries could be overwritten.

 

Other than that, good job!

 

Lee

Link to comment
Share on other sites

Ahhh...."I see," said the code-blind man....

 

I had read about reading and writing to the registry through vlisp but I don't remember seeing anything about getenv / setenv. So thanks for the tip. I've found the hardest thing for me is not knowing what all the available options are to code any one thing so I find myself stuck in one or two mindsets on trying to accomplish what I'm thinking. I'm glad we have forums to educate me such as this one, The Swamp, the Autodesk forums and the AUGI....oops.....LOL

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...