Using Object Reactors

AutoCAD AutoLISP & Visual LISP

 
Using Object Reactors
 
 
 

Unlike other AutoCAD reactors, object reactors are attached to specific AutoCAD entities (objects). When you define an object reactor, you must identify the entity to which the reactor is to be attached. The vlr-object-reactor function, which creates object reactors, requires the following arguments:

  • A list of VLA-objects identifying the drawing objects that are to fire notifications to the reactor. These objects are referred to as the reactor owners.
  • AutoLISP data to be associated with the Reactor object.
  • A list of pairs naming the event and the callback function to be associated with that event (event-name . callback_function).
WarningYou cannot modify an object in a callback function if it is included in the object reactor's owner list. Attempts to do so will generate an error message and can cause AutoCAD to fail.

For example, the following statement defines an object reactor with a single owner (the object identified by myCircle), then attaches the string “Circle Reactor” to the reactor and tells AutoCAD to invoke the print-radius function when a user modifies myCircle:

(setq circleReactor (vlr-object-reactor (list myCircle)
         "Circle Reactor" '((:vlr-modified . print-radius))))

The Reactor object is stored in variable circleReactor; you can refer to the reactor using this variable, as described in Querying, Modifying, and Removing Reactors.

When defining a list of owners, you must specify VLA-objects only; Ename objects are not allowed. VLA-objects are required because callback functions can only use ActiveX methods to modify AutoCAD objects, and ActiveX methods require a VLA-object to work on.

Note that, although you cannot use objects obtained through functions such as entlast and entget with callback reactors, you can convert these Ename objects into VLA-objects using the vlax-ename->vla-object function. See the AutoLISP Reference for more information on vlax-ename->vla-object.

To see how an object reactor works

  1. Load the following code to define a circle object; you will be prompted to draw the circle:
    (setq myCircle
       ; Prompt for the center
    point and radius:
          (progn (setq ctrPt  
             (getpoint "\nCircle center point: ")
                 radius (distance ctrPt
                          (getpoint ctrpt "\nRadius: ")
                        )
          )
       ; Add a circle to the
    drawing model space. Nest the function
       ; calls to obtain the
    path to the current drawing's model
       ; space: AcadObject >
    ActiveDocument > ModelSpace
           (vla-addCircle           
              (vla-get-ModelSpace   
                 (vla-get-ActiveDocument (vlax-get-acad-object)) 
              )
            (vlax-3d-point ctrPt)
            radius
           )
        )
    )

    This code uses vla-addCircle to draw a circle, assigning the return value to variable myCircle. The return value is a VLA-object, which contains a pointer to the Circle object drawn.

  2. Load the print-radius callback function shown in Defining Object Reactor Callback Functions.
  3. Define the reactor with the following command:
    (setq circleReactor (vlr-object-reactor (list myCircle)
             "Circle Reactor" '((:vlr-modified . print-radius))))
  4. In the AutoCAD drawing window, select the circle and change its size. The print-radius function will display a message in the AutoCAD Command window. For example, if you use the STRETCH command to enlarge the circle, the message looks like the following:

    Specify stretch point or [Base point/Copy/Undo/eXit]: The radius is 3.75803