明经通道 发表于 2012-12-21 20:50:26

第十二章 反应器和回调函数 (四) 使用对象反应器

使用对象反应器

和其他AutoCAD反应器不同,对象反应器是附着在特定的AutoCAD图元(对象)上。定义对象反应器时,必须指定反应器所要附着的图元。创建对象反应器的函数vlr-object-reactor要求的参数如下所示:

VLA对象表,指定通知反应器的图形对象,这些对象也被称为反应器的所有者。

和反应器对象关联的AutoLISP数据。

点对列表,指明事件和与该事件相关联的回调函数: (event-name . callback_function)。

警告! 如果对象被包括在对象反应器的所有者列表之中,那么不能在回调函数中修改该对象。这样做会导致错误消息,并使AutoCAD崩溃。

例如,下列语句定义了只有一个所有者(由myCircle指定的对象)的对象反应器,然后将字符串“Circle Reactor”附着到反应器上,并告诉AutoCAD当用户修改myCircle时调用print-radius函数:

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

反应器对象保存在变量circleReactor中,可使用该变量引用反应器,详细信息请参见查询、修改和删除反应器。

在定义所有者列表时,只能指定VLA对象,而不允许使用ename对象。要求VLA对象是因为回调函数只能用ActiveX方法修改AutoCAD对象,而ActiveX方法要求使用VLA 对象。

注意尽管不能在回调反应器中使用由entlast和entget等函数获取的对象,但可以用vlax-ename->vla-object函数将ename对象转换成VLA对象,关于该函数的详细信息,请参见AutoLISP参考。

(vl-load-com)
(setq oAcad (vlax-get-acad-object)
      oDoc(vla-get-activedocument oAcad)
)
(cond
((and (setq ctrPt (getpoint "\n圆心: "))
(setq rad (distance ctrPt (getpoint ctrPt "\n半径: ")))
   )
   (setq CircleObject
   (vla-addCircle
   (vla-get-ModelSpace oDoc)
   (vlax-3d-point ctrPt)
   radius
   )
   )
)
)
(if CircleObject
(setq circleReactor
(vlr-object-reactor
    (list CircleObject)
    "Circle Reactor"
    '((:vlr-modified . rShowRadius))
)
)
)
(defun rShowRadius (notifier-object reactor parameter-list)
(cond
    ((vlax-property-available-p notifier-object "Radius")
   (princ "*** 半径为 ")
   (princ (vla-get-radius notifier-object))
    )
)
)

将数据附着到反应器对象

使用对象反应器中的对象反应器创建样例在调用 vlr-object-reactor 时包括了字符串“Circle Reactor”。并不要求一定要给反应器指定任何数据,可以将数据指定为 nil。然而,一个对象上可能附着有好几个反应器,如果给反应器指定文本字符串或应用程序能用的其他数据,就可以区分附着在同一对象上的不同反应器了。



http://bbs.mjtd.com/xwb/images/bgimg/icon_logo.png 该贴已经同步到 明经通道的微博

smartstar 发表于 2012-12-22 12:53:08

我来学习。

zyhandw 发表于 2012-12-22 15:04:59

楼主辛苦,向您致敬!

edata 发表于 2013-11-5 18:11:05

(setq rad (distance ctrPt (getpoint ctrPt "\n半径: ")))

应该是 (setq radius (distance ctrPt (getpoint ctrPt "\n半径: ")))
页: [1]
查看完整版本: 第十二章 反应器和回调函数 (四) 使用对象反应器