AutoLISP使用反应器.ppt

上传人:xt****7 文档编号:17037035 上传时间:2020-11-07 格式:PPT 页数:60 大小:212.50KB
收藏 版权申诉 举报 下载
AutoLISP使用反应器.ppt_第1页
第1页 / 共60页
AutoLISP使用反应器.ppt_第2页
第2页 / 共60页
AutoLISP使用反应器.ppt_第3页
第3页 / 共60页
资源描述:

《AutoLISP使用反应器.ppt》由会员分享,可在线阅读,更多相关《AutoLISP使用反应器.ppt(60页珍藏版)》请在装配图网上搜索。

1、第 11章 使用反应器 11.1 反应器 反应器是一种反馈机制 , 它可以在发生某些特定事件时 , 将所发生的事件通知给应用程序 , 应用程序将会根据发生的具 体事件做出相应的决策 。 例如 , 在某个图元上链接了一个反应 器 , 如果用户移动这个图元 , 应用程序就会接到反应器的通知 , 知道了该图元被移动这个事件 , 如果需要 , 应用程序可以用适 当的动作 ( 如移动与该图元相关的其它图元 , 或显示有关信息 等 ) 响应该通知 。 1. 反应器的类型 反应器有多种类型 , 每种反应器对应一个或多个 AutoCAD事 件 。 反应器可以分为以下几个大类: l 数据库反应器:当图形数据库发

2、生特定类型的事件时 , 该 反应器将通知应用程序 。 l文档反应器:当前图形文档发生改变 ( 如打开新的图形文档 、 激活其它文档窗口 、 改变文档的锁定状态等 ) 时 , 该反应器将 通知应用程序 。 l编辑器反应器:在调用 AutoCAD命令 ( 如打开图形 、 关闭图 形 、 保存图形 、 输入输出 DXF文件 、 改变系统变量的值等 ) 时 , 该反应器将通知应用程序 。 l 链接反应器:当加载和卸载 ARX应用程序时 , 该反应器将通 知应用程序 。 l对象反应器:当特定对象 ( AutoCAD图元 ) 被修改 、 复制或 删除时 , 该反应器将通知应用程序 。 调用函数 vlr-t

3、ypes可返回反应器类型的完整列表。表 11-1列 出了 AutoCAD反应器类型及其标识符。 表 11-1AutoCAD反应器类型及其标识符 反应器类型的标识符 说明 :VLR-AcDb-Reactor 数据库反应器 :VLR- DocManager- Reactor 文档管理反应器 :VLR-Editor- Reactor 通用编辑器反应器 :VLR-Linker- Reactor 链接反应器 :VLR-Object- Reactor 对象反应器 其中通用编辑器反应器被进一步细分为更加明确的几种反应器类型, 见表 11-2。表 11-1中的通用编辑器反应器类型只是为了向后兼容才保留的, 表

4、 11-2所示的各种编辑类型的反应器不能被通用编辑器 :VLR-Editor- Reactor引用。 表 11-2 编辑类型的各种反应器及其标识符 反应器类型的标识符 说明 :VLR-Command-Reactor 通报命令事件 :VLR-DeepClone-Reactor 通报 deep clone 事件 :VLR-DWG-Reactor 通报打开或关闭图形文件的事件 :VLR-DXF-Reactor 通报和读写 DXF 文件相关的事件 :VLR-Insert-Reactor 通报和插入块有关的事件 :VLR-Lisp-Reactor 通报 LISP 事件 :VLR-Miscellaneou

5、s-Reactor ( 表中未列出的 ) 其它编辑器反应器类型 :VLR-Mouse-Reactor 通报鼠标事件 ( 例如双击 ) :VLR-SysVar-Reactor 通报对系统变量的修改 :VLR-Toolbar-Reactor 通报对工具栏上位图的修改 :VLR-Undo-Reactor 通报 undo 事件 :VLR-Wblock-Reactor 通报和写块有关的事件 :VLR-Window-Reactor 通报和移动或改变 AutoCAD窗口大小的事件 :VLR-XREF-Reactor 通报附着或修改 XREF 有关的事件 3. 反应器回调事件 大部分 AutoCAD操作都会产

6、生一些特定的事件 , 这些事件能 够用来触发反应器的动作 , 这样的事件被称为回调事件 。 例如 , 当发出 Save命令保存图形时 , 将会发生 AutoCAD保存图形文件 ( :vlr-beginSave) 的事件 , 当保存过程结束时 , 将会发生 AutoCAD已将当前图形保存到磁盘 ( :vlr-saveComplete) 的事 件 。 设计基于反应器的应用程序就是根据回调事件的内容编写这 些事件发生时所要激活的函数 。 vlr-reaction-names函数返回与给定反应器类型相关的所有 事件组成的表: (vlr-reaction-names reactor-type) 参数 r

7、eactor-type是反应器类型的标识 , 见表 11-1和表 11-2。 例如 , 下列代码将返回和图形反应器相关的所有事件组成的表: (vlr-reaction-names :VLR-DWG-Reactor) 返回 (:VLR-beginDwgOpen :VLR-endDwgOpen :VLR-dwgFileOpened :VLR- databaseConstructed :VLR-databaseToBeDestroyed :VLR- beginSave :VLR-saveComplete :VLR-beginClose) 下列代码将返回和对象反应器相关的所有事件组成的表: (vlr-

8、reaction-names :vlr-object-reactor) ;返回 (:VLR-cancelled :VLR-copied :VLR-erased :VLR-unerased :VLR- goodbye :VLR-openedForModify :VLR-modified :VLR- subObjModified :VLR-modifyUndone :VLR-modifiedXData :VLR- unappended :VLR-reappended :VLR-objectClosed) 加载并运行以下代码 , 将会打印出所有相关反应器事件的列表 ( 按反应 器类型排序 ) 。 (

9、defun print-reactors-and-events () (foreach rtype (vlr-types) (princ (strcat n (vl-princ-to-string rtype) (foreach rname (vlr-reaction-names rtype) (princ (strcat nt (vl-princ-to-string rname) (princ) ) AutoLISP Reference列出了与各种反应器类型相关的所有事件 , 有关信 息在创建反应器的函数部分做了说明 。 和 ActiveX一样 , 必须首先调用 vl-load-com函数

10、, 加载支持反应器和其 它 AutoLISP扩展函数之后 , 才能实现反应器的功能 。 11.2 定义反应器的回调函数 反应器的回调函数就是回调事件发生时所要执行的函数 。 反 应器的回调函数是用 AutoLISP定义的 。 编写回调函数有以下一 些限制: 不能使用 command函数调用 AutoCAD命令 , 只能用 ActiveX函数访问图形对象 。 不能使用 entget和 entmod函数 。 不能使用选择集操作函数 。 不能使用交互输入函数 。 在事件处理函数中不要加载警告和信息之外的对话框 。 定义对象反应器回调函数和定义其它反应器的回调函数也 不完全相同 。 11.2.1 定义

11、对象反应器的回调函数 定义对象反应器的回调函数的格式如下: (defun function (notifier-object reactor-object parameter-list) ) 参数 notifier-object是事件发生的对象 。 参数 reactor-objec是调用这个函数的反应器对象 。 参数 parameter-list是回调事件返回的回调数据表 。 例如 , 例 11-1定义了名为 print-radius的回调函数 。 notifier-object是事件发生的对象 , reactor-object是调用 这个函数的反应器对象 , parameter-list是回

12、调事件返回的回 调数据表 。 虽然在本例并不关心 parameter-list的值 , 但定义 回调函数时 , 也要进行变量声明 。 【 例 11-1】 定义名字为 print-radius的回调函数 , 该函数用来 打印圆的半径 。 (defun print-radius (notifier-object reactor-object parameter-list) (vl-load-com) (cond (vlax-property-available-p notifier-object Radius) ;判断该 图形对象是否具有 radius特性 (princ “这个圆的半径是: ) (

13、princ (vla-get-radius notifier-object) ) ) ) 11.2.2 定义其它反应器的回调函数 由于其它反应器不需要链接到 AutoCAD图元上 , 因此定义其 它反应器的回调函数只需要以下两个参数: (defun function(reactor-object parameter-list) ) 参数 reactor-object是调用这个函数的反应器对象 。 参数 parameter-list是回调事件返回的回调数据表 。 例 11-2定义了名为 saveDrawingInfo的回调函数。参数 calling- reactor是调用该函数的反应器对象。参数

14、 commandInfo是回调 事件返回的回调数据表。该函数在发生保存 AutoCAD图形的事件 时将被激活,显示文件的路径和大小等信息。 【 例 11-2】 定义名字为 saveDrawingInfo的回调函数 。 (defun saveDrawingInfo(calling-reactor commandInfo / dwgname filesize) (vl-load-com) (setq dwgname (cadr commandInfo) filesize (vl-file-size dwgname) (alert(strcat 这个文件 ( dwgname ) 的大小是 (itoa

15、 filesize) 字节 .) (princ) ) 在该例中 , 通过函数 vl-file-size获取图形文件的大小 , 通过警告对话 框显示这些信息 。 11.2.3. AutoCAD预定义的回调函数 AutoCAD提供了两个预定义的回调函数 , 可以在测 试反应器时使用这些函数: ( 1) vlr-beep-reaction函数 vlr-beep-reaction的功能是让计算机发出 “ 嘟嘟 ” 声 。 ( 2) vlr-trace-reaction函数 vlr-trace-reaction函数的功能是将参数列表打印到 VLISP的 “ 跟踪 ” 窗口 。 11.3 创建反应器 创建

16、反应器的主要工作就是将事件和回调函数相关联 。 创建 反应器用 vlr-reactor函数 。 每种类型的反应器都有一个与 之对应的用于创建该反应器的 AutoLISP函数 , 这些函数的名称 和反应器类型的名称相同 , 只是没有前面的冒号 。 例如 , vlr- acdb-reactor为创建数据库反应器函数 , vlr-toolbar-reactor 为创建工具栏反应器函数 。 所有创建反应器的构造函数都返回 一个反应器对象 。 AutoLISP Reference列出了与每种反应器类型相关的所有可 能事件 。 例如 , 通过 vlr-DWG-reactor条目 , 可看到表 11-3所示

17、 与 DWG反应器相关的所有可能事件 。 表 11-3 DWG反应器事件 事件名称 说明 :vlr-beginClose 图形数据库将被关闭 。 :vlr-databaseConstructed 已经构建图形数据库 。 :vlr-databaseToBeDestroyed 将从内存中删除图形数据库的内容 。 :vlr-beginDwgOpen AutoCAD将打开图形文件 。 :vlr-endDwgOpen AutoCAD已结束打开操作 。 :vlr-dwgFileOpened 新图形已被加载到 AutoCAD图形窗口 。 :vlr-beginSave AutoCAD将保存图形文件 。 :vl

18、r-saveComplete AutoCAD已将当前图形保存到磁盘 。 11.3.1创建对象反应器 因为对象反应器必须链接到特定的 AutoCAD图元 ( 对象 ) 上 , 所以在定义 对象反应器时 , 必须指定反应器所要链接的图元 。 创建对象反应器通过函数 vlr-object-reactor, 该函数的调用格式如下: (vlr-object-reactor owners data callbacks) 参数 owners为 VLA对象表 , 表内可以是多个 VLA对象 。 这些对象也被称为 反应器的所有者 。 参数 data为与反应器对象相关联的数据 , 如果没有数据则该项为 nil。

19、参数 callbacks为点对表 , 用于指明事件和与该事件相关联的回调函数 。 点对表的格式如下: (event-name . callback_function) 该点对表的 event-name是表 11-4所示 Object事件中的名称标识 , callback_function为回调函数 。 表 11-5是针表 11-4所示对特定的回调事件 返回的回调数据表 。 该函数的返回值为 reactor_object(对象反应器)。 名称标识 事件 :vlr-cancelled 对对象的修改已经取消 。 :vlr-copied 对象已被复制 。 :vlr-erased 对象的删除标志已被设置

20、 。 :vlr-unerased 对象的删除标志已被重置 。 :vlr-goodbye 即将从内存中删除对象 。 :vlr-openedForModify 即将修改对象 。 :vlr-modified 对象已被修改 。 如果取消修改 , 还将激发 :vlr-cancelled 和 :vlr-modifyUndone。 :vlr-subObjModified 对象的子图元已被修改 。 在修改多段线或网格顶 点时触发该事件 。 :vlr-modifyUndone 对象的修改已被放弃 。 :vlr-modifiedXData 对象的扩展图元数据已被修改 。 :vlr-unappended 已从图形数

21、据库中拆离对象 。 :vlr-reappended 对象已被重新链接到图形数据库 。 :vlr-objectClosed 对对象的修改已经完成 。 表 11-4 Object事件及其名称标识 名称 表长度 参数 :vlr-cancelled 0 :vlr-erased :vlr-unerased :vlr-goodbye :vlr-openedForModify :vlr-modified :vlr-modifyUndone :vlr-modifiedXData :vlr-unappended :vlr-reappended :vlr-objectClosed :vlr-copied 1 由复

22、制操作创建的对象 (ename)。 :vlr-subObjModified 1 已被修改的子对象 (ename)。 表 11-5 Object 事件回调数据 例如 , 下面的代码创建了一个对象反应器 。 该对象反应器 只有一个所有者 , 即 VLA对象 myCircle;与该反应器对象相关 联的数据为 Circle Reactor;点对表为 (:vlr-modified . print-radius) , 当 发 生 myCircle 对 象 被 修 改 ( 即 :vlr- modified) 事件时 , 调用 print-radius回调函数: (setq circleReactor (vl

23、r-object-reactor (list myCircle) Circle Reactor (:vlr-modified . print-radius) 上述反应器对象赋给了变量 circleReactor。 可以通过该变 量实现对该反应器的查询 、 修改或删除等 。 创建对象反应器除了必须指定反应器所要链接的图元之外 , 还要注意以下几点: ( 1) 在定义所有者列表时 , 只能指定 VLA对象 , 而不允许使用 ename对象 。 要求 VLA对象是因为回调函数只能用 ActiveX方法 修改 AutoCAD对象 , 而 ActiveX方法要求使用 VLA对象 。 尽管不能在回调反应器

24、中使用由 entlast和 entget等函数获取 VLA对象 , 但可以用 vlax-ename-vla-object函数将 ename对象 转换成 VLA对象 。 ( 2) 如果对象已被包括在对象反应器的所有者列表之中 , 那么 就不能在回调函数中修改该对象 。 如果这样做 , 将会导致一个 出错消息 , 并使 AutoCAD崩溃 。 下面是实现对象反应器功能的实例 : ( 1) 加载例 11-3所示程序段 【 例 11-3】 生成一个圆的 VLA对象 。 (setq myCircle (progn (setq ctrPt (getpoint n输入圆心 : ) radius (dista

25、nce ctrPt (getpoint ctrpt n输入半径 : ) ) (vla-addCircle (vla-get-ModelSpace ;将圆加入到图形模型空间 (vla-get-ActiveDocument (vlax-get-acad-object) (vlax-3d-point ctrPt) radius ) 该代码使用 vla-addCircle画一个圆 , 将返回值赋给变量 myCircle。 该返 回值是 VLA对象 , 包含指向所画圆对象的指针 。 ( 2) 加载例 11-1 所示回调函数 print-radius。 ( 3) 定义对象反应器 (setq circleR

26、eactor (vlr-object-reactor (list myCircle) Circle Reactor (:vlr-modified . print-radius) ( 4) 在 AutoCAD图形窗口 , 选取该圆并修改其大小 , print-radius 函 数将在 AutoCAD命令窗口显示一个消息 。 例如 , 如果用夹点或 STRETCH命令改 变了该圆的大小 , 将在命令提示区显示以下信息: * STRETCH * Specify stretch point or Base point/Copy/Undo/eXit:这个圆的 半径是 :190.0 如果用夹点或 STRE

27、TCH命令改变其他圆时的大小 , 将没有该提示信息中的 “ 这个圆的半径是 :”, 这是因为在其他的圆上没有链接 circleReactor反应 器 。 11.3.2 创建其它反应器 其它反应器不需要链接 AutoCAD图元 , 所以在定义时 , 只需要两个参数 。 创建其它反应器通过函数 vlr-reactor, 该函数的调用格式如下: (vlr-reactor data callbacks) 参数 data为任意要与反应器对象关联的数据 , 如果没有数据则该项为 nil。 参数 callbacks为点对表 , 指明事件和与该事件相关联的回调函数 , 点对 表的格式如下: (event-na

28、me . callback_function) 例如 , 下列代码定义了一个 DWG编辑器反应器 。 当用户发出 Save命令时 , 该反应器将激活 saveDrawingInfo函数 。 (vlr-dwg-Reactor nil (:vlr-saveComplete . saveDrawingInfo) 在该例中 , 第一个参数为 nil是因为没有与反应器相关联的数据;第二个 参数是点对表 , 指明 :vlr-saveComplete事件与 saveDrawingInfo回调函数相 关联 。 当 :vlr-saveComplete事件发生时 , AutoCAD传递给回调函数一个图形 文件名字

29、的字符串 。 每个点对表都指定了反应器要通报的事件 , 以及该事件发生时要调用的 回调函数 。 在本例中 , 只指定了一个事件 :vlr-saveComplete。 只要用户发出命令 , 不管是从 AutoCAD命令行 、 菜单 、 工具栏或 AutoLISP 程序 , 都会通知编辑器反应器 。 所以 , 该 DWG反应器的回调函数需要明确它 应对什么事件作出响应 。 在本例中 , 回调函数 saveDrawingInfo只是检查 Save命令 。 下面是 实现 DWG反应器功能的实例: ( 1) 加载例 11-2所定义的回调函数 saveDrawingInfo。 (2) 定义 DWG反应器

30、(vlr-dwg-Reactor nil (:vlr-saveComplete . saveDrawingInfo) ( 3) 在 AutoCAD图形窗口点取存盘的图标或调用存图的命令 。 当完成存 图工作时将会弹出图 11-1所示的 AutoCAD Message对话框 。 说明该实例成功 。 图 11-1AutoCAD的 Message对话框 11.3.3 将数据附着到反应器对象 利用创建反应器函数的参数 data可以为反应器指定与其关联的数据 , 如 果该项为 nil, 表示不需要为反应器指定与其关联的数据 。 一个对象可能链接多个反应器 , 如果它们的参数 data都为 nil, 应用

31、程 序将无法区分它们 。 在这种情况下就应该为反应器指定文本字符串或应用程 序能识别的其它数据 。 例如 , 前 面 创 建 对 象 反 应 器 circleReactor 的 实 例 中 , 字符串 “ CircleReactor”就是与反应器 circleReactor相关联的数据 。 11.4 查询 、 修改和控制反应器的状态 11.4.1 查询反应器 有多种不同的方法来获取反应器的信息 。 可以使用标准的 VLISP数据查 看工具查看反应器的信息 , 也可以用有关反应器的 AutoLISP函数 。 1.了解图形中有关反应器的总体情况 通过 vlr-reactors函数可以了解当前图形中

32、总共用到了哪些 反应器或有哪些指定类型的反应器 。 vlr-reactors函数的调用 格式如下: (vlr-reactors reactor-type.) 参数 reactor-type为反应器类型的标识符 。 如果指定了 reactor-type参数 , 该函数返回由指定类型反应器组成的表 。 如果省略参数 reactor-type, 该函数返回所有当前图形所有的 反应器 。 以下表达式列出图形中的所有反应器: (vlr-reactors) ;返回 (:VLR-Object-Reactor #) (:VLR-Editor-Reactor #), 有一个对象 反应器和一个编辑器反应器 。 以

33、下表达式列出所有的对象反应器: (vlr-reactors :vlr-object-reactor) ;返回 (:VLR-Object- Reactor #), 有一个对象反应器 以下表达式列出所有数据库反应器: (vlr-reactors :vlr-acdb-reactor) ;返回 nil, 没有数据库反应器 以下表达式列出所有 DWG反应器: (vlr-reactors :vlr-dwg-reactor) ;返回 (:VLR-DWG-Reactor # #), 有一个 DWG反应器 , 有两个指 向该 DWG反应器的指针 。 2. 用 VLISP的检验工具检查反应器 可以使用 VLISP

34、的检验工具检查反应器。在 VLISP编辑器窗口选择 circleReactor,单击按钮 ,将弹出图 11-2所示检验窗口,该窗口显示 以下信息: 图 11-2有关反应器的检验窗口 l 反应器的类型标识符 , 如 VLR-Object-Reactor l 该反应器的所有者 , 如 l 事件和与之相关联的回调函数 , 如 : VLR-modified PRINT-RADIUS l 该反应器是否是活动的:如果是活动的 , added-p 为 T, 否则它为 nil l 附着到反应器上的用户数据 , 如 “ Circle Reactor” l 反应器的文档范围:如 active-document-o

35、nly l 该反应器所在文挡:如 双击以 Owners 开头的条目,可查看反应器所有者的列表。 3. 用函数调用 、 查询反应器 VLISP还提供了可在应用程序或控制台提示处查看反应器定义的函数: ( 1) vlr-type函数返回指定反应器的类型 , 例如: (vlr-type circleReactor) ;返回 :VLR-Object-Reactor( 对象反应器 ) ( 2) vlr-current-reaction-name 函数返回当前反应器触发回调函数的事 件名称 。 例如: (vlr-current-reaction-name) ;返回 nil ( 3) vlr-data 返回

36、附着到反应器的特定应用程序数据 , 可用该数据区分链 接在同一个对象上的多个反应器 。 例如: (vlr-data circleReactor) ;返回 Circle Reactor“ ( 4) vlr-owners函数返回向某对象反应器发出通报的 AutoCAD图形中的对象 ( 反应器所有者 ) 列表 , 下述函数调用将列出 circleReactor 的所有者: (vlr-owners circleReactor) ;返回 (#) ( 5) vlr-reactions函数返回指定反应器的回调条件回调函数列表 , 下例 将返回 circleReactor 的相关信息 。 例如: (vlr-r

37、eactions circleReactor) ;返回 (:VLR-modified . PRINT-RADIUS) 11.4.2 修改反应器 1 添加或替换反应器的回调函数 通过函数 vlr-reaction-set可以添加或替换反应器中的一个 回调函数 。 该函数的调用格式如下: (vlr-reaction-set reactor event function) 参数 reactor为反应器 对象 。 event为符号 , 表示该反应器 类型可用的事件之一 。 Function为要添加或替换的 AutoLISP函 数名 。 返回值未确定 。 例如 , 下面的命令使反应器 circleRea

38、ctor在修改对象时调 用 print-area函数: (vlr-reaction-set circleReactor :vlr-modified print- area) ;返回 PRINT-AREA 2. 修改与反应器相关联的数据 通过函数 vlr-data-set可以修改与反应器相关联的数据 。 该函数的调用 格式如下: (vlr-data-set obj data) 参数 obj为反应器对象 , 表示要修改数据的反应器对象 。 data为新数据 。 返回值为参数 data。 例如 , 查看附着到反应器 circleReactor的数据值: (vlr-data circleReactor

39、) 返回 Circle Reactor 用字符串 Circle Area Reactor替换反应器 circleReactor的原有数据 Circle Reactor: (vlr-data-set circleReactor Circle Area Reactor) ;返回 Circle Area Reactor 验证是否有了改变: (vlr-data circleReactor) ;返回 Circle Area Reactor 注意,应小心使用 vlr-data-set函数,以免构成循环结构。 3. 将一个数据库对象添加到反应器的所有者列表内 通过函数 vlr-owner-add可以将一个数

40、据库对象添加到指定 反应器的所有者列表内 。 该函数的调用格式如下: (vlr-owner-add reactor owner) 参数 reactor为反应器对象 。 owner为要添加到反应器所有 者列表中的 VLA对象 。 返回值为已添加了反应器的 VLA对象 。 例如 , 在下例中 , 名为 archie的圆弧对象被添加到反应器 circleReactor的所有者列表中: (vlr-owner-add circleReactor archie) ;返回 # 可通过检验该反应器来验证这点:更新反应器 circleReactor 的检验窗口 , 用鼠标双击检验窗口的 Owners 开头的条目

41、 , 将弹出图 11 3所示的反应器所有者检验窗口 。 图 11 3反应器所有者的检验窗口 4. 从反应器所有者列表中删除某所有者对象 通过函数 vlr-owner-remove可以从反应器所有者列表中删 除某所有者对象 。 该函数的调用格式如下: (vlr-owner-remove reactor owner) 参数 reactor为反应器 对象 。 owner为要从反应器所有者列 表中删除的 VLA对象 。 返回值为被删除的 VLA对象 。 例如: (vlr-owner-remove circleReactor archie); 返 回 # 11.4.3 控制反应器的状态 1. 判断反应器

42、是否是活动的 通过函数 vlr-added-p可以判断反应器是否是活动的 。 vlr- added-p函数的调用格式如下: (vlr-added-p obj) 参数 obj为反应器对象 , 表示要测试的反应器 。 如果反应器 是活动的 ( 已在 AutoCAD 中注册 ) , 返回 T, 如果该反应器失 效 , 则返回 nil。 例如: (vlr-added-p circleReactor) ;返回 T, 表示该反应器是活动的 2. 使反应器失效 通过函数 vlr-remove可以使指定的反应器失效 。 vlr-remove 函数的调用格式如下: (vlr-remove obj) 参数 obj

43、为反应器对象 。 如果成功 , 返回反应器对象 , 否则 , 返回 nil。 例如 , 使反应器 circleReactor失效: (vlr-remove circleReactor);返回 # 注意,失效的反应器,并没有从内存中被删除,该反应器仍 然存在。 2. 恢复失效的反应器 通过函数 vlr-add可以恢复指定的失效反应器 , 使之成为活 动的 ( 在 AutoCAD中注册 ) 。 vlr-add函数的调用格式如下: (vlr-add obj) 参数 obj为反应器对象 , 表示要恢复的失效反应器 。 如果成 功 , 返回反应器对象 , 否则 , 返回 nil。 例如 , 恢复失效的

44、circleReactor反应器: (vlr-add circleReactor) ;返回 # 通过函数 vlr-remove-all可以使图形中所有的反应器失效 。 vlr-remove-all函数的调用格式如下: (vlr-remove-all reactor-type) 可选参数 reactor-type为反应器类型的标识符 , 如果未指定 reactor-type, 该函数禁用图形中所有的反应器 。 返回为包含 若干个子表的表 , 每个子表的第一个元素表示反应器的类型 , 后 续元素表示禁用的反应器对象 。 如果没有活动的反应器 , 该函数 返回 nil。 例如 , 下面的函数调用将禁

45、用所有编辑器反应器: (vlr-remove-all :vlr-editor-reactor) 返回 (:VLR-Editor-Reactor #) 下面的调用函数将禁用所有反应器: (vlr-remove-all) 返回 (:VLR-Object-Reactor # #) (:VLR-Editor-Reactor #) 11.5 临时反应器和永久反应器 反应器可以是临时的 , 也可以是永久的 。 二者的区别是:下 一次打开该图形时 , 临时反应器将丢失 , 永久反应器则仍然存 在 。 前者是反应器的默认模式 。 1. 将临时反应器变成永久反应器 通过函数 vlr-pers可以将临时反应器变成

46、永久反应器 。 函数 vlr-pers的调用格式如下: (vlr-pers obj) 参数 obj为反应器对象 。 如果成功则返回指定的反应器对象 , 否则返回 nil。 例如: (vlr-pers circleReactor) ;返回 # 2.将永久反应器改变为临时反应器 通过函数 vlr-pers-release可以将永久反应器改变为临时反应器 。 函数 vlr- pers的调用格式如下: (vlr-pers-release obj) 参数 obj为反应器对象 。 如果成功则返回反应器对象 , 否则返回 nil。 (vlr-pers-release circleReactor) ;返回 #

47、 3. 判断反应器是否是永久反应器 通过函数 vlr-pers-p可以判断反应器是否是永久反应器 。 函数 vlr-pers-p的 调用格式如下: (vlr-pers-p obj) 参数 obj为反应器对象 。 如果指定反应器是永久反应器 , 则返回指定的反 应器对象 , 否则返回 nil。 例如: (vlr-pers-p circleReactor) ;返回 # 4. 列出当前图形文档中的永久反应器 通过函数 vlr-pers-list可以列出当前图形文档中的永久反应器 。 函数 vlr-pers- list的调用格式如下: (vlr-pers-list reactor-type) 参数 r

48、eactor-type为要列出的反应器对象 。 如果未指定 reactorr- type, 该函数列出所有永久反应器 。 返回值为由反应器对象组成 的表 。 例如: (vlr-pers-list) ; 返回 (# # (#) 5. 打开含有永久反应器的图形时的注意事项 反应器只是链接事件和回调函数的一种工具 , 回调函数 本身不是反应器的一部分 , 它一般也不是图形的一部分 。 只 有 AutoCAD中加载了相关联的回调函数时 , 图形中保存的 反应才有实际作用 。 如果将反应器和回调函数定义在独立名 称空 VLX中 , 则在打开图形时会自动加载回调函数 。 如果打开的图形包括 VLISP反应

49、器信息 , 但没有加载相 关回调函数 , AutoCAD会显示一个错误信息 。 可用函数 vlr- pers-list返回图形文档中所有永久反应器组成的表 。 11.6 反应器的使用规则 由于将来可能修改反应器的内部实现机制 , 使用反应器时请 尽量遵守下述规则 , 如果不遵守这些规则 , 可能会导致应用程 序出现不可预料的结果 。 ( 1) 不要依赖于反应器通报的顺序 除了少数特例之外 , 建议不要依赖于反应器通报的顺序 。 例 如 , OPEN 命 令 将 触 发 BeginCommand 、 BeginOpen 、 EndOpen 和 EndCommand事件 。 然而 , 它们发出的顺

50、序可能 不是这样的 。 可以依赖的顺序只有 Begin事件是在相应 End事件 之前 。 例如 commandWillStart()总是在 commandEnded()之前发 生 , 而 beginInsert()总是在 endInsert()之前发生 。 因为将来可能 引入新的事件通报 , 可能会重新排列现有通报顺序 , 所以依赖 于更复杂的顺序 , 可能会给您的应用程序带来问题 。 ( 2) 不要依赖于通报间函数调用的顺序 在通报之间函数调用的顺序也是不能保证的 。 例如 , 当收到 对象 A 的通报 :vlr-erased 时 , 它仅表示对象 A被删除 , 如果在 收到对象 A的通报

51、:vlr-erased 之后收到了对象 B的通报 :vlr- erased, 这只是表示对象 A和 B都已被删除 。 并不能保证 B是在 A后面被删除 。 如果应用程序依赖于这个层次的关系 , 那么应 用程序在后续版本的 AutoCAD中很可能会崩溃 。 所以不要依赖 于这些顺序 , 而应该依赖于用反应器来指示系统的状态 。 ( 3) 不要在反应器回调函数中使用任何需要和用户交 互的函数 在反应器回调函数中试图调用交互函数会导致严重问题 , 因 为在事件发生时 , AutoCAD可能仍在处理某命令 。 所以要避免 使用要求用户输入的函数 , 如 getpoint、 entsel和 getkwo

52、rd等 , 也不要使用选择集操作函数和 command函数 。 (4)在事件处理函数中不要加载对话框 对话框和用户交互函数一样 , 也会影响 AutoCAD的当前操 作 。 但是 , 消息对话框和警告对话框可认为是非交互的 , 所以可 以使用它们 。 (5)不要更新引发事件的对象 引起对象触发回调函数的事件可能仍在处理之中 , 当调用回 调函数时 AutoCAD可能仍在使用该对象 。 所以 , 在回调函数中 不要试图更新这样的对象 。 然而 , 可以从触发事件的对象中读取 信息 。 例如 , 假设有一块用砖填充的地板 , 而且将反应器链接到 地板边界上 。 如果修改地板的尺寸 , 反应器回调函

53、数将自动添加 或删除砖以填充新的地板面积 。 通过函数能够获取边界的新面积 , 但不能去修改边界本身 。 (6) 不要在回调函数中执行能触发相同事件的操作 如果在反应器回调函数中执行的某操作过程中触发了同样的 事件 , 将会陷入一个无限循环 。 例如 , 如果在 BeginOpen事件 的回调函数中试图打开一个图形 , AutoCAD将持续打开更多的 图形 , 直到打开的图形数目达到上限 , 无法再打开图形为止 。 (7) 能在发生同一事件时调用多个回调函数 在设置反应器以前要确认当前没有设置该反应器 , 否则可能 在发生同一事件时调用多个回调函数 。 (8) 显示有模对话框时 , 不会发生任

54、何事件 所谓有模对话框 , 是指操作其它窗口之前必须关闭的话框时 。 显示这样的对话框时 , 不会发生任何事件 。 11.7定义反应器实例 1. 定义将对象反应器链接到指定直线的命令 。 要求:当直线被 修改时 , 弹出显示该直线长度的信息对话框 。 很明显 , 反应器的链接对象就是指定的直线 。 触发事件是直 线被修改 , 从表 11-4可以查找出图形对象被修改的事件是 :vlr- modified。 回调函数的功能是调用信息对话框显示被选直线长 度 。 程序的代码如下: 【 例 11-4】 定义将对象反应器链接到指定直线的命令 。 (vl-load-com) (defun c:rct-li

55、ne(/ el rlt vrl) (setq el(car (entsel n选择一条链接反应器的直线 :) (setq rlt(list (vlax-ename-vla-object el);将图元名转换为 VLA对象 ;创建对象反应器 , 回调事件是图元被修改 , 回调函数是 show-l (setq vrl (vlr-pers(vlr-object-reactor rlt nil (:vlr-modified . show-l) (princ) ) ;定义回调函数 (defun show-l(notifier-object reactor-object parameter-list /

56、l) (setq l(vla-get-length notifier-object);将被选直线的长度赋给变量 l (setq l(rtos l 2 4);将数值转换为字符串 (alert (strcat 直线的长度是: l);调用信息对话框 ) 加载以上程序,在 Command:提示下输入 rct-line命 令,用鼠标指定一条直线,该反应器就会链接到指定 的直线上。修改这条直线时,就会出现图 11 4所示显 示有该直线当前长度信息的对话框。 图 11 4显示直线当前长度信息的对话框 2. 定义绘制图 11 5所示图形的命令。要求:将对象反应器链接 到圆上,如果圆被修改,两条直线与圆的相对位

57、置和相对比例 不变。 图 11 5一个圆和两条直线组成的图形 根据题意,反应器的链接对象是圆。触发事件是圆被修改, 从表 11-4可以查找出图形对象被修改的事件是 :vlr-modified。 回调函数的功能是两条直线随之被修改,且修改后与圆的相 对位置和相对比例不变。两条直线是与该反应器相关联的对 象。 【 例 11-5】 定义将对象反应器链接到圆上的命令 , 如果圆被修 改 , 两条直线与圆的相对位置和相对比例不变 。 (vl-load-com) (defun c:c1l2( / p0 p1 p2 p3 p4 r r1 eh1 eh2 l1-l2 rlt vrl) (setq p0(get

58、point n输入圆心: ) (setq r(getdist p0 n输入半径: ) (command circle p0 r) (setq r1(* 1.25 r) (setq ec(entlast) (setq p1(polar p0 0 r1) (setq p2(polar p0 (* 0.5 pi) r1) (setq p3(polar p0 pi r1) (setq p4(polar p0 (* -0.5 pi) r1) (command line p1 p3 ) (setq eh1(cdr (assoc 5 (entget (entlast);第一条直线的句柄 (command l

59、ine p2 p4 ) (setq eh2(cdr (assoc 5 (entget(entlast);第二条直线的句柄 (setq l1-l2(list eh1 eh2);两条直线的句柄表 (setq rlt(list (vlax-ename-vla-object ec);圆的图元名转换为 VLA对 象 (setq vrl (vlr-pers(vlr-object-reactor rlt l1-l2 (:vlr-modified . c- 2l);反应器链接到圆上 , 两条直线的句柄表为关联数据 , 当发生修改该圆 的事件时 , 调用 c-2l函数 (princ);静默退出 ) ;定义 c-

60、2l函数 (defun c-2l(notifier-object reactor-object parameter-list / ec ec_l el1 el2 ell_1 ell_2 p0 p1 p2 p3 p4 p0 x p0y p0z) (setq ec(vlax-vla-object-ename notifier-object);VLA对象的圆转换 为图元名 ec_l(entget ec);圆的图元表 p0(cdr(assoc 10 ec_l);获取圆心的坐标 r(* 1.25 (cdr(assoc 40 ec_l);获取圆的半径之后 1.25 ) (setq el1(handent

61、(car (vlr-data reactor-object);第一条直线的图 元名 (setq el2(handent (cadr (vlr-data reactor-object);第二直条线的图 元名 (setq p0 x (car p0);获取圆心的 X坐标 (setq p0y (cadr p0);获取圆心的 Y坐标 (setq p0z (caddr p0);获取圆心的 Z坐标 (setq p1 (list (+ p0 x r) p0y p0z);修改直线端点的坐标 (setq p2 (list p0 x (+ p0y r) p0z);修改直线端点的坐标 (setq p3 (list (

62、- p0 x r) p0y p0z);修改直线端点的坐标 (setq p4 (list p0 x (- p0y r) p0z);修改直线端点的坐标 (setq ell_1(entget el1);第一条直线的图元表 (setq ell_1(subst (vl-list* 10 p1)(assoc 10 ell_1)ell_1);直线的新端点 替换直线的老端点 (setq ell_1(subst (vl-list* 11 p3)(assoc 11 ell_1)ell_1);直线的新端点 替换直线的老端点 (entmod ell_1);更新第一条直线 (setq ell_2(entget el2)

63、;第二条直线的图元表 (setq ell_2(subst (vl-list* 10 p2)(assoc 10 ell_2)ell_2);直线的新端点替换直线 的老端点 (setq ell_2(subst (vl-list* 11 p4)(assoc 11 ell_2)ell_2);直线的新端点替换直线 的老端点 (entmod ell_2);更新第二条直线 ) 加载以上程序 , 在 Command:提示下输入 c1l2命令 , 输入圆心和半径 , 即可绘制出图 11 5所示图形 。 修改这个圆 , 两条直线将随之按题意的要求 改变 。 在本程序中 , 与反应器相关联的数据是两条直线的句柄 。 获取圆心和半径 的途径是: 将圆的 VLA对象转换为图元名 。 根据圆的图元名获取圆的 图元表 。 从圆的图元表获取圆的圆心和半径 。 修改直线的途径是: 从 关联的数据表获取是两条直线的句柄 。 根据直线的句柄获取直线的图元名 。 根据直线的图元名获取直线的图元表 。 修改

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!