How to use :vlr-dwgfileopened reactor event in drawing load

Hello.

I have a lisp that activates a reactor callback for :vlr-dwgfileopened. It is in the on_doc_load.lsp file. The lisp kind of works. Activates the callback only when a drawing is already open and I call open another or a new drawing. If I open a dwg file when another drawing is not open it fails to call the callback. To make it interesting though, it will call the callback on any attached xrefs to that drawing. I think it is a timing problem but I don't know how to get around this. Here is the code:

;; This file should be saved as 'on_doc_load.lsp' (or 'acaddoc.lsp' for AutoCAD)
;; and placed in your BricsCAD/AutoCAD support file search path. ;; Ensure the Visual LISP COM library is loaded.
(vl-load-com) ;; --- Global Variable for the Reactor ---
;; This variable will store the reactor object.
;; It's set to nil initially and will hold the reactor if it's successfully attached.
(setq simpleDwgOpenReactor nil) ;; --- Callback Function for the Drawing Open Event ---
;; This function will be executed whenever a drawing is opened.
;; 'reactor-object' is the reactor that triggered the event.
;; 'event-info' is a list containing a string (path to template/file).
(defun SimpleDrawingOpenAlertCallback (reactor-object event-info / docName processedEventInfo)
;; --- CRITICAL FIX: Ensure COM library is loaded at callback execution ---
(vl-load-com) ;; For debugging:
(print "event-info (raw): ") (print event-info) ;; As established, event-info is consistently a list. Extract the first item.
(setq processedEventInfo (car event-info)) ;; For debugging:
(princ (strcat "Hello yor event info is: " processedEventInfo)) (princ) ; Suppress nil return in the command line
) ;; --- Function to Attach the Drawing Open Reactor ---
;; This function ensures the reactor is attached only once per AutoCAD/BricsCAD session.
;; It prevents redundant reactor attachments if on_doc_load.lsp is loaded multiple times.
(defun AttachSimpleDwgOpenReactor ()
(vl-load-com) ; Ensure COM is loaded ;; Check if the reactor is NOT already attached in this session
(if (not simpleDwgOpenReactor)
(progn
;; Create and store the vlr-dwg-reactor
(setq simpleDwgOpenReactor
(vlr-dwg-reactor "MySimpleTestReactor" ; A unique name for this reactor
'(
(:vlr-dwgfileopened . SimpleDrawingOpenAlertCallback) ; Event-callback pair
)
)
)
(princ "\nSimple Drawing Open Reactor ATTACHED successfully.")
)
(princ "\nSimple Drawing Open Reactor is ALREADY active.")
)
(princ)
) ;; --- Initial Call to Attach the Reactor ---
;; This line ensures that when 'on_doc_load.lsp' is loaded (which happens
;; every time a drawing is opened), it attempts to attach the reactor.
;; The 'AttachSimpleDwgOpenReactor' function's internal check prevents
;; it from attaching more than once per BricsCAD/AutoCAD session.
(AttachSimpleDwgOpenReactor) (princ "\n'on_doc_load.lsp' script loaded. Reactor setup complete.")
(princ)

Does anyone know what is going on and how to fix this.

This lisp's only function is to print the name of the callback event. It is just for me to figure out how to us the reactor. Eventually I will be using it to load data from dictionaries on drawing open but that is for later.

Comments

  • Hello.

    For a lisp code to run, first a drawing needs to be opened or created.

    So, if nothing is opened, the sequence would be like this:

    Create / open drawing > (the event occurs here) > on_doc_load.lsp is loaded and run > the reactor is loaded and ready.

    So, with the first open, the event occurs before the reactor is loaded.
    With this, the reactor can't capture the event of opening the first drawing.
    It will capture only the subsequent openings.

    In this case, for doing something when a drawing is opened, on_doc_load.lsp should be enough, because it is run with every document.

  • Why use a reactor "load data from dictionaries" just do that. Do you know how to get info from a dictionary. ?

    I use LDATA a lot to store information in a dwg much easier that say a dictionary.

  • Thanks. That's exactly what I ended up doing. 😊

  • I'm just dabbling in dictionaries. I couldn't fine any reference to LDATA though. Is that lisp or a command ?

  • Like this

    (vlax-ldata-get "AlanH" "Layoutname")

    (vlax-ldata-put "AlanH" "Layoutname" "Layout1")

  • LDATA are just a way to comfortably use DICTIONARIES. Because LDATA had a severe bug when they were introduced and could destroy DWG files, until today not much people make use of them.

    But there is a much more powerful way, when you program your own code, or if you use my free CADCAL+CALSCRIPT (free download from https://www.calscript.com/home.html)with it's Lisp library.

    There is a function (dictionary-put <appname> <key> <data>)

    <appname> and <key> are strings,and data can be anything, including symbols, dotted pairs, lists and even entity-names. i.e. you can store the ENTGET list of an entity in a DICTIONARY:

    (setq el (entget (car (entsel))))
    (dictionary-put "MYAPPNAME" "AKEY" el)

    And you can retrieve that data again with
    (dictionary-get "MYAPPNAME" "AKEY")

    Indeed you can store full Lisp applications in a DWG file, as is done in CALSCRIPT, where every CALSCript object stores the function to create and modify itself as an XDICTIONARY at the object itself.

    I use this a lot to store system variables of my applications to a DWG:

    (defun mysetvar (varname data)
    (dictionary-put "MYAPPNAME" varname data)
    )

    (defun mygetvar (varname)
    (dictionary-get "MYAPPNAME" varname)
    )

    BTW: there are similar functions to write and read XDATA and XDICTIONARIES:

    (xdata-put <ename> <key> <data>)
    (xdata-get <ename> <key>)

    (xdictionary-put <ename> <key> <data>)
    (xdictionary-get <ename> <key>)

  • Thanks everyone. I ended up using the on_doc_load.lsp