Visual LISP 程序设计 第11章_第1页
Visual LISP 程序设计 第11章_第2页
Visual LISP 程序设计 第11章_第3页
Visual LISP 程序设计 第11章_第4页
Visual LISP 程序设计 第11章_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第11章使用反应器 11 1反应器反应器是一种反馈机制 它可以在发生某些特定事件时 将所发生的事件通知给应用程序 应用程序将会根据发生的具体事件做出相应的决策 例如 在某个图元上链接了一个反应器 如果用户移动这个图元 应用程序就会接到反应器的通知 知道了该图元被移动这个事件 如果需要 应用程序可以用适当的动作 如移动与该图元相关的其它图元 或显示有关信息等 响应该通知 1 反应器的类型反应器有多种类型 每种反应器对应一个或多个AutoCAD事件 反应器可以分为以下几个大类 l数据库反应器 当图形数据库发生特定类型的事件时 该反应器将通知应用程序 l文档反应器 当前图形文档发生改变 如打开新的图形文档 激活其它文档窗口 改变文档的锁定状态等 时 该反应器将通知应用程序 l编辑器反应器 在调用AutoCAD命令 如打开图形 关闭图形 保存图形 输入输出DXF文件 改变系统变量的值等 时 该反应器将通知应用程序 l链接反应器 当加载和卸载ARX应用程序时 该反应器将通知应用程序 l对象反应器 当特定对象 AutoCAD图元 被修改 复制或删除时 该反应器将通知应用程序 调用函数vlr types可返回反应器类型的完整列表 表11 1列出了AutoCAD反应器类型及其标识符 表11 1AutoCAD反应器类型及其标识符 反应器类型的标识符说明 VLR AcDb Reactor数据库反应器 VLR DocManager Reactor文档管理反应器 VLR Editor Reactor通用编辑器反应器 VLR Linker Reactor链接反应器 VLR Object Reactor对象反应器 其中通用编辑器反应器被进一步细分为更加明确的几种反应器类型 见表11 2 表11 1中的通用编辑器反应器类型只是为了向后兼容才保留的 表11 2所示的各种编辑类型的反应器不能被通用编辑器 VLR Editor Reactor引用 表11 2编辑类型的各种反应器及其标识符 反应器类型的标识符说明 VLR Command Reactor通报命令事件 VLR DeepClone Reactor通报deepclone事件 VLR DWG Reactor通报打开或关闭图形文件的事件 VLR DXF Reactor通报和读写DXF文件相关的事件 VLR Insert Reactor通报和插入块有关的事件 VLR Lisp Reactor通报LISP事件 VLR Miscellaneous 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有关的事件 2 反应器回调事件大部分AutoCAD操作都会产生一些特定的事件 这些事件能够用来触发反应器的动作 这样的事件被称为回调事件 例如 当发出Save命令保存图形时 将会发生AutoCAD保存图形文件 vlr beginSave 的事件 当保存过程结束时 将会发生AutoCAD已将当前图形保存到磁盘 vlr saveComplete 的事件 设计基于反应器的应用程序就是根据回调事件的内容编写这些事件发生时所要激活的函数 vlr reaction names函数返回与给定反应器类型相关的所有事件组成的表 vlr reaction namesreactor type 参数reactor 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 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 加载并运行以下代码 将会打印出所有相关反应器事件的列表 按反应器类型排序 defunprint reactors and events foreachrtype vlr types princ strcat n vl princ to stringrtype foreachrname vlr reaction namesrtype princ strcat n t vl princ to stringrname princ AutoLISPReference列出了与各种反应器类型相关的所有事件 有关信息在创建反应器的函数部分做了说明 和ActiveX一样 必须首先调用vl load com函数 加载支持反应器和其它AutoLISP扩展函数之后 才能实现反应器的功能 11 2定义反应器的回调函数反应器的回调函数就是回调事件发生时所要执行的函数 反应器的回调函数是用AutoLISP定义的 编写回调函数有以下一些限制 不能使用command函数调用AutoCAD命令 只能用ActiveX函数访问图形对象 不能使用entget和entmod函数 不能使用选择集操作函数 不能使用交互输入函数 在事件处理函数中不要加载警告和信息之外的对话框 定义对象反应器回调函数和定义其它反应器的回调函数也不完全相同 11 2 1定义对象反应器的回调函数定义对象反应器的回调函数的格式如下 defunfunction notifier objectreactor objectparameter list 参数notifier object是事件发生的对象 参数reactor objec是调用这个函数的反应器对象 参数parameter list是回调事件返回的回调数据表 例如 例11 1定义了名为print radius的回调函数 notifier object是事件发生的对象 reactor object是调用这个函数的反应器对象 parameter list是回调事件返回的回调数据表 虽然在本例并不关心parameter list的值 但定义回调函数时 也要进行变量声明 例11 1 定义名字为print radius的回调函数 该函数用来打印圆的半径 defunprint radius notifier objectreactor objectparameter list vl load com cond vlax property available pnotifier object Radius 判断该图形对象是否具有radius特性 princ 这个圆的半径是 princ vla get radiusnotifier object 11 2 2定义其它反应器的回调函数由于其它反应器不需要链接到AutoCAD图元上 因此定义其它反应器的回调函数只需要以下两个参数 defunfunction reactor objectparameter list 参数reactor object是调用这个函数的反应器对象 参数parameter list是回调事件返回的回调数据表 例11 2定义了名为saveDrawingInfo的回调函数 参数calling reactor是调用该函数的反应器对象 参数commandInfo是回调事件返回的回调数据表 该函数在发生保存AutoCAD图形的事件时将被激活 显示文件的路径和大小等信息 例11 2 定义名字为saveDrawingInfo的回调函数 defunsaveDrawingInfo calling reactorcommandInfo dwgnamefilesize vl load com setqdwgname cadrcommandInfo filesize vl file sizedwgname alert strcat 这个文件 dwgname 的大小是 itoafilesize 字节 princ 在该例中 通过函数vl file size获取图形文件的大小 通过警告对话框显示这些信息 11 2 3AutoCAD预定义的回调函数AutoCAD提供了两个预定义的回调函数 可以在测试反应器时使用这些函数 1 vlr beep reaction函数vlr beep reaction的功能是让计算机发出 嘟嘟 声 2 vlr trace reaction函数vlr trace reaction函数的功能是将参数列表打印到VisualLISP的 跟踪 窗口 11 3创建反应器创建反应器的主要工作就是将事件和回调函数相关联 创建反应器用vlr reactor函数 每种类型的反应器都有一个与之对应的用于创建该反应器的AutoLISP函数 这些函数的名称和反应器类型的名称相同 只是没有前面的冒号 例如 vlr acdb reactor为创建数据库反应器函数 vlr toolbar reactor为创建工具栏反应器函数 所有创建反应器的构造函数都返回一个反应器对象 AutoLISPReference列出了与每种反应器类型相关的所有可能事件 例如 通过vlr DWG reactor条目 可看到表11 3所示与DWG反应器相关的所有可能事件 表11 3DWG反应器事件 事件名称说明 vlr beginClose图形数据库将被关闭 vlr databaseConstructed已经构建图形数据库 vlr databaseToBeDestroyed将从内存中删除图形数据库的内容 vlr beginDwgOpenAutoCAD将打开图形文件 vlr endDwgOpenAutoCAD已结束打开操作 vlr dwgFileOpened新图形已被加载到AutoCAD图形窗口 vlr beginSaveAutoCAD将保存图形文件 vlr saveCompleteAutoCAD已将当前图形保存到磁盘 11 3 1创建对象反应器因为对象反应器必须链接到特定的AutoCAD图元 对象 上 所以在定义对象反应器时 必须指定反应器所要链接的图元 创建对象反应器通过函数vlr object reactor 该函数的调用格式如下 vlr object reactorownersdatacallbacks 参数owners为VLA对象表 表内可以是多个VLA对象 这些对象也被称为反应器的所有者 参数data为与反应器对象相关联的数据 如果没有数据则该项为nil 参数callbacks为点对表 用于指明事件和与该事件相关联的回调函数 点对表的格式如下 event name callback function 该点对表的event name是表11 4所示Object事件中的名称标识 callback function为回调函数 表11 5是针表11 4所示对特定的回调事件返回的回调数据表 该函数的返回值为reactor object 对象反应器 名称标识事件 vlr cancelled对对象的修改已经取消 vlr copied对象已被复制 vlr erased对象的删除标志已被设置 vlr unerased对象的删除标志已被重置 vlr goodbye即将从内存中删除对象 vlr openedForModify即将修改对象 vlr modified对象已被修改 如果取消修改 还将激发 vlr cancelled和 vlr modifyUndone vlr subObjModified对象的子图元已被修改 在修改多段线或网格顶点时触发该事件 vlr modifyUndone对象的修改已被放弃 vlr modifiedXData对象的扩展图元数据已被修改 vlr unappended已从图形数据库中拆离对象 vlr reappended对象已被重新链接到图形数据库 vlr objectClosed对对象的修改已经完成 表11 4Object事件及其名称标识 名称表长度参数 vlr cancelled0 vlr erased vlr unerased vlr goodbye vlr openedForModify vlr modified vlr modifyUndone vlr modifiedXData vlr unappended vlr reappended vlr objectClosed vlr copied1由复制操作创建的对象 ename vlr subObjModified1已被修改的子对象 ename 表11 5Object事件回调数据 例如 下面的代码创建了一个对象反应器 该对象反应器只有一个所有者 即VLA对象myCircle 与该反应器对象相关联的数据为 CircleReactor 点对表为 vlr modified print radius 当发生myCircle对象被修改 即 vlr modified 事件时 调用print radius回调函数 setqcircleReactor vlr object reactor listmyCircle CircleReactor vlr modified print radius 上述反应器对象赋给了变量circleReactor 可以通过该变量实现对该反应器的查询 修改或删除等 创建对象反应器除了必须指定反应器所要链接的图元之外 还要注意以下几点 1 在定义所有者列表时 只能指定VLA对象 而不允许使用ename对象 要求VLA对象是因为回调函数只能用ActiveX方法修改AutoCAD对象 而ActiveX方法要求使用VLA对象 尽管不能在回调反应器中使用由entlast和entget等函数获取VLA对象 但可以用vlax ename vla object函数将ename对象转换成VLA对象 2 如果对象已被包括在对象反应器的所有者列表之中 那么就不能在回调函数中修改该对象 如果这样做 将会导致一个出错消息 并使AutoCAD崩溃 下面是实现对象反应器功能的实例 1 加载例11 3所示程序段 例11 3 生成一个圆的VLA对象 setqmyCircle progn setqctrPt getpoint n输入圆心 radius distancectrPt getpointctrpt n输入半径 vla addCircle vla get ModelSpace 将圆加入到图形模型空间 vla get ActiveDocument vlax get acad object vlax 3d pointctrPt radius 该代码使用vla addCircle画一个圆 将返回值赋给变量myCircle 该返回值是VLA对象 包含指向所画圆对象的指针 2 加载例11 1所示回调函数print radius 3 定义对象反应器 setqcircleReactor vlr object reactor listmyCircle CircleReactor vlr modified print radius 4 在AutoCAD图形窗口 选取该圆并修改其大小 print radius函数将在AutoCAD命令窗口显示一个消息 例如 如果用夹点或STRETCH命令改变了该圆的大小 将在命令提示区显示以下信息 STRETCH Specifystretchpointor Basepoint Copy Undo eXit 这个圆的半径是 190 0如果用夹点或STRETCH命令改变其他圆时的大小 将没有该提示信息中的 这个圆的半径是 这是因为在其他的圆上没有链接circleReactor反应器 11 3 2创建其它反应器其它反应器不需要链接AutoCAD图元 所以在定义时 只需要两个参数 创建其它反应器通过函数vlr reactor 该函数的调用格式如下 vlr reactordatacallbacks 参数data为任意要与反应器对象关联的数据 如果没有数据则该项为nil 参数callbacks为点对表 指明事件和与该事件相关联的回调函数 点对表的格式如下 event name callback function 例如 下列代码定义了一个DWG编辑器反应器 当用户发出Save命令时 该反应器将激活saveDrawingInfo函数 vlr dwg Reactornil vlr saveComplete saveDrawingInfo 在该例中 第一个参数为nil是因为没有与反应器相关联的数据 第二个参数是点对表 指明 vlr saveComplete事件与saveDrawingInfo回调函数相关联 当 vlr saveComplete事件发生时 AutoCAD传递给回调函数一个图形文件名字的字符串 每个点对表都指定了反应器要通报的事件 以及该事件发生时要调用的回调函数 在本例中 只指定了一个事件 vlr saveComplete 只要用户发出命令 不管是从AutoCAD命令行 菜单 工具栏或AutoLISP程序 都会通知编辑器反应器 所以 该DWG反应器的回调函数需要明确它应对什么事件作出响应 在本例中 回调函数saveDrawingInfo只是检查Save命令 下面是实现DWG反应器功能的实例 1 加载例11 2所定义的回调函数saveDrawingInfo 2 定义DWG反应器 vlr dwg Reactornil vlr saveComplete saveDrawingInfo 3 在AutoCAD图形窗口点取存盘的图标或调用存图的命令 当完成存图工作时将会弹出图11 1所示的AutoCADMessage对话框 说明该实例成功 图11 1AutoCAD信息对话框 11 3 3将数据附着到反应器对象利用创建反应器函数的参数data可以为反应器指定与其关联的数据 如果该项为nil 表示不需要为反应器指定与其关联的数据 一个对象可能链接多个反应器 如果它们的参数data都为nil 应用程序将无法区分它们 在这种情况下就应该为反应器指定文本字符串或应用程序能识别的其它数据 例如 前面创建对象反应器circleReactor的实例中 字符串 CircleReactor 就是与反应器circleReactor相关联的数据 11 4查询 修改和控制反应器的状态11 4 1查询反应器有多种不同的方法来获取反应器的信息 可以使用标准的VisualLISP数据查看工具查看反应器的信息 也可以用有关反应器的AutoLISP函数 1 了解图形中有关反应器的总体情况通过vlr reactors函数可以了解当前图形中总共用到了哪些反应器或有哪些指定类型的反应器 vlr reactors函数的调用格式如下 vlr reactors reactor type 参数reactor type为反应器类型的标识符 如果指定了reactor type参数 该函数返回由指定类型反应器组成的表 如果省略参数reactor type 该函数返回所有当前图形所有的反应器 以下表达式列出图形中的所有反应器 vlr reactors 返回 VLR Object Reactor VLR Editor Reactor 有一个对象反应器和一个编辑器反应器 以下表达式列出所有的对象反应器 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 用VisualLISP的检验工具检查反应器可以使用VisualLISP的检验工具检查反应器 在VisualLISP编辑器窗口选择circleReactor 单击按钮 将弹出图11 2所示检验窗口 该窗口显示以下信息 图11 2有关反应器的检验窗口 l反应器的类型标识符 如VLR Object Reactorl该反应器的所有者 如l事件和与之相关联的回调函数 如 VLR modifiedPRINT RADIUSl该反应器是否是活动的 如果是活动的 added p为T 否则它为nill附着到反应器上的用户数据 如 CircleReactor l反应器的文档范围 如active document onlyl该反应器所在文挡 如 VLA OBJECTIacadDocument01165340 3 用函数查询反应器VisualLISP还提供了可在应用程序或控制台提示处查看反应器定义的函数 1 vlr type函数返回指定反应器的类型 例如 vlr typecircleReactor 返回 VLR Object Reactor 对象反应器 2 vlr current reaction name函数返回当前反应器触发回调函数的事件名称 例如 vlr current reaction name 返回nil 3 vlr data返回附着到反应器的特定应用程序数据 可用该数据区分链接在同一个对象上的多个反应器 例如 vlr datacircleReactor 返回 CircleReactor 4 vlr owners函数返回向某对象反应器发出通报的AutoCAD图形中的对象 反应器所有者 列表 下述函数调用将列出circleReactor的所有者 vlr ownerscircleReactor 返回 5 vlr reactions函数返回指定反应器的回调条件 回调函数列表 下例将返回circleReactor的相关信息 例如 vlr reactionscircleReactor 返回 VLR modified PRINT RADIUS 11 4 2修改反应器1添加或替换反应器的回调函数通过函数vlr reaction set可以添加或替换反应器中的一个回调函数 该函数的调用格式如下 vlr reaction setreactoreventfunction 参数reactor为反应器对象 event为符号 表示该反应器类型可用的事件之一 Function为要添加或替换的AutoLISP函数名 返回值未确定 例如 下面的命令使反应器circleReactor在修改对象时调用print area函数 vlr reaction setcircleReactor vlr modified print area 返回PRINT AREA 2 修改与反应器相关联的数据通过函数vlr data set可以修改与反应器相关联的数据 该函数的调用格式如下 vlr data setobjdata 参数obj为反应器对象 表示要修改数据的反应器对象 data为新数据 返回值为参数data 例如 查看附着到反应器circleReactor的数据值 vlr datacircleReactor 返回 CircleReactor 用字符串 CircleAreaReactor 替换反应器circleReactor的原有数据 CircleReactor vlr data setcircleReactor CircleAreaReactor 返回 CircleAreaReactor 验证是否有了改变 vlr datacircleReactor 返回 CircleAreaReactor 注意 应小心使用vlr data set函数 以免构成循环结构 3 将一个数据库对象添加到反应器的所有者列表内通过函数vlr owner add可以将一个数据库对象添加到指定反应器的所有者列表内 该函数的调用格式如下 vlr owner addreactorowner 参数reactor为反应器对象 owner为要添加到反应器所有者列表中的VLA对象 返回值为已添加了反应器的VLA对象 例如 在下例中 名为archie的圆弧对象被添加到反应器circleReactor的所有者列表中 vlr owner addcircleReactorarchie 返回 可通过检验该反应器来验证这点 更新反应器circleReactor的检验窗口 用鼠标双击检验窗口的 Owners 开头的条目 将弹出图11 3所示的反应器所有者检验窗口 图11 3反应器所有者的检验窗口 4 从反应器所有者列表中删除某所有者对象通过函数vlr owner remove可以从反应器所有者列表中删除某所有者对象 该函数的调用格式如下 vlr owner removereactorowner 参数reactor为反应器对象 owner为要从反应器所有者列表中删除的VLA对象 返回值为被删除的VLA对象 例如 vlr owner removecircleReactorarchie 返回 11 4 3控制反应器的状态1 判断反应器是否是活动的通过函数vlr added p可以判断反应器是否是活动的 vlr added p函数的调用格式如下 vlr added pobj 参数obj为反应器对象 表示要测试的反应器 如果反应器是活动的 已在AutoCAD中注册 返回T 如果该反应器失效 则返回nil 例如 vlr added pcircleReactor 返回T 表示该反应器是活动的 2 使反应器失效通过函数vlr remove可以使指定的反应器失效 vlr remove函数的调用格式如下 vlr removeobj 参数obj为反应器对象 如果成功 返回反应器对象 否则 返回nil 例如 使反应器circleReactor失效 vlr removecircleReactor 返回 注意 失效的反应器 并没有从内存中被删除 该反应器仍然存在 2 恢复失效的反应器通过函数vlr add可以恢复指定的失效反应器 使之成为活动的 在AutoCAD中注册 vlr add函数的调用格式如下 vlr addobj 参数obj为反应器对象 表示要恢复的失效反应器 如果成功 返回反应器对象 否则 返回nil 例如 恢复失效的circleReactor反应器 vlr addcircleReactor 返回 通过函数vlr remove all可以使图形中所有的反应器失效 vlr remove all函数的调用格式如下 vlr remove all reactor type 可选参数reactor type为反应器类型的标识符 如果未指定reactor type 该函数禁用图形中所有的反应器 返回为包含若干个子表的表 每个子表的第一个元素表示反应器的类型 后续元素表示禁用的反应器对象 如果没有活动的反应器 该函数返回nil 例如 下面的函数调用将禁用所有编辑器反应器 vlr remove all vlr editor reactor 返回 VLR Editor Reactor 下面的调用函数将禁用所有反应器 vlr remove all 返回 VLR Object Reactor VLR Editor Reactor 11 5临时反应器和永久反应器反应器可以是临时的 也可以是永久的 二者的区别是 下一次打开该图形时 临时反应器将丢失 永久反应器则仍然存在 前者是反应器的默认模式 1 将临时反应器变成永久反应器通过函数vlr pers可以将临时反应器变成永久反应器 函数vlr pers的调用格式如下 vlr persobj 参数obj为反应器对象 如果成功则返回指定的反应器对象 否则返回nil 例如 vlr perscircleReactor 返回 2 将永久反应器改变为临时反应器通过函数vlr pers release可以将永久反应器改变为临时反应器 函数vlr pers的调用格式如下 vlr pers releaseobj 参数obj为反应器对象 如果成功则返回反应器对象 否则返回nil vlr pers releasecircleReactor 返回 3 判断反应器是否是永久反应器通过函数vlr pers p可以判断反应器是否是永久反应器 函数vlr pers p的调用格式如下 vlr pers pobj 参数obj为反应器对象 如果指定反应器是永久反应器 则返回指定的反应器对象 否则返回nil 例如 vlr pers pcircleReactor 返回 4 列出当前图形文档中的永久反应器通过函数vlr pers list可以列出当前图形文档中的永久反应器 函数vlr pers list的调用格式如下 vlr pers list reactor type 参数reactor type为要列出的反应器对象 如果未指定reactorr type 该函数列出所有永久反应器 返回值为由反应器对象组成的表 例如 vlr pers list 返回 打开含有永久反应器的图形时的注意事项反应器只是链接事件和回调函数的一种工具 回调函数本身不是反应器的一部分 它一般也不是图形的一部分 只有AutoCAD中加载了相关联的回调函数时 图形中保存的反应才有实际作用 如果将反应器和回调函数定义在独立名称空VLX中 则在打开图形时会自动加载回调函数 如果打开的图形包括VisualLISP反应器信息 但没有加载相关回调函数 AutoCAD会显示一个错误信息 可用函数vlr pers list返回图形文档中所有永久反应器组成的表 11 6反应器的使用规则由于将来可能修改反应器的内部实现机制 使用反应器时请尽量遵守下述规则 如果不遵守这些规则 可能会导致应用程序出现不可预料的结果 1 不要依赖于反应器通报的顺序除了少数特例之外 建议不要依赖于反应器通报的顺序 例如 OPEN命令将触发BeginCommand BeginOpen EndOpen和EndCommand事件 然而 它们发出的顺序可能不是这样的 可以依赖的顺序只有Begin事件是在相应End事件之前 例如commandWillStart 总是在commandEnded 之前发生 而beginInsert 总是在endInsert 之前发生 因为将来可能引入新的事件通报 可能会重新排列现有通报顺序 所以依赖于更复杂的顺序 可能会给您的应用程序带来问题 2 不要依赖于通报间函数调用的顺序在通报之间函数调用的顺序也是不能保证的 例如 当收到对象A的通报 vlr erased时 它仅表示对象A被删除 如果在收到对象A的通报 vlr erased之后收到了对象B的通报 vlr erased 这只是表示对象A和B都已被删除 并不能保证B是在A后面被删除 如果应用程序依赖于这个层次的关系 那么应用程序在后续版本的AutoCAD中很可能会崩溃 所以不要依赖于这些顺序 而应该依赖于用反应器来指示系统的状态 3 不要在反应器回调函数中使用任何需要和用户交互的函数在反应器回调函数中试图调用交互函数会导致严重问题 因为在事件发生时 AutoCAD可能仍在处理某命令 所以要避免使用要求用户输入的函数 如getpoint entsel和getkword等 也不要使用选择集操作函数和command函数 4 在事件处理函数中不要加载对话框对话框和用户交互函数一样 也会影响AutoCAD的当前操作 但是 消息对话框和警告对话框可认为是非交互的 所以可以使用它们 5 不要更新引发事件的对象引起对象触发回调函数的事件可能仍在处理之中 当调用回调函数时AutoCAD可能仍在使用该对象 所以 在回调函数中不要试图更新这样的对象 然而 可以从触发事件的对象中读取信息 例如 假设有一块用砖填充的地板 而且将反应器链接到地板边界上 如果修改地板的尺寸 反应器回调函数将自动添加或删除砖以填充新的地板面积 通过函数能够获取边界的新面积 但不能去修改边界本身 6 不要在回调函数中执行能触发相同事件的操作如果在反应器回调函数中执行的某操作过程中触发了同样的事件 将会陷入一个无限循环 例如 如果在BeginOpen事件的回调函数中试图打开一个图形 AutoCAD将持续打开更多的图形 直到打开的图形数目达到上限 无法再打开图形为止 7 能在发生同一事件时调用多个回调函数在设置反应器以前要确认当前没有设置该反应器 否则可能在发生同一事件时调用多个回调函数 8 显示有模对话框时 不会发生任何事件所谓有模对话框 是指操作其它窗口之前必须关闭的话框时 显示这样的对话框时 不会发生任何事件 11 7定义反应器实例 例11 4 定义将对象反应器链接到指定直线的命令 要求 当直线被修改时 弹出显示该直线长度的信息对话框 很明显 反应器的链接对象就是指定的直线 触发事件是直线被修改 从表11 4可以查找出图形对象被修改的事件是 vlr modified 回调函数的功能是调用信息对话框显示被选直线长度 程序的代码如下 定义将对象反应器链接到指定直线的命令 vl load com defunc rct line elrltvrl setqel car entsel n选择一条链接反应器的直线 setqrlt list vlax ename vla objectel 将图元名转换为VLA对象 创建对象反应器 回调事件是图元被修改 回调函数是show l setqvrl vlr pers vlr object reactorrltnil vlr modified show l princ 定义回调函数 defunshow l notifier objectreactor objectparameter list l setql vla get lengthnotifier object 将被选直线的长度赋给变量l setql rtosl24 将数值转换为字符串 alert strcat 直线的长度是 l 调用信息对话框 加载以上程序 在Command 提示下输入rct line命令 用鼠标指定一条直线 该反应器就会链接到指定的直线上 修改这条直线时 就会出现图11 4所示显示有该直线当前长度信息的对话框 图11 4显示直线当前长度信息的对话框 例11 5 定义绘制图11 5所示图形的命令 要求 将对象反应器链接到圆上 如果圆被修改 两条直线与圆的相对位置和相对比例不变 图11 5一个圆和两条直线组成的图形 根据题意 反应器的链接对象是圆 触发事件是圆被修改 从表11 4可以查找出图形对象被修改的事件是 vlr modified 回调函数的功能是两条直线随之被修改 且修改后与圆的相对位置和相对比例不变 两条直线是与该反应器相关联的对象 程序的代码如下 defunc rct circ1 p0p1p2p3p4rr1eceh1eh2l1 l2rltvrl setqp0 getpoint n输入圆心 setqr getdistp0 n输入半径 command circle p0r setqr1 1 25r setqec entlast setqp1 polarp00r1 setqp2 polarp0 0 5pi r1 setqp3 polarp0pir1 setqp4 polarp0 0 5pi r1 command line p1p3 setqeh1 cdr assoc5 entget entlast 第一条直线的句柄 command line p2p4 setqeh2 cdr assoc5 entget entlast 第二条直线的句柄 setql1 l2 listeh1eh2 两条直线的句柄表 setqrlt list vlax ename vla objectec 圆的图元名转换为VLA对象 setqvrl vlr pers vlr object reactorrltl1 l2 vlr modified c 2l 反应器链接到圆上 两条直线的句柄表为关联数据 当发生修改该圆的事件时 调用c 2l函数 princ 静默退出 定义c 2l函数 defunc 2l notifier objectreactor objectparameter list ecec lel1el2ell 1ell 2p0p1p2p3p4p0 xp0yp0z setqec vlax vla object enamenotifier object VLA对象的圆转换为图元名ec l entgetec 圆的图元表p0 cdr assoc10ec l 获取圆心的坐标r 1 25 cdr assoc40ec l 获取圆的半径之后 1 25 setqel1 handent car vlr datareactor object 第一条直线的图元名 setqel2 handent cadr vlr datareactor object 第二直条线的图元名 setqp0 x carp0 获取圆心的X坐标 setqp0y cadrp0 获取圆心的Y坐标 setqp0z caddrp0 获取圆心的Z坐标 setqp1 list p0 xr p0yp0z 修改直线端点的坐标 setqp2 listp0 x p0yr p0z 修改直线端点的坐标 setqp3 list p0 xr p0yp0z 修改直线端点的坐标 setqp4 listp0 x p0yr p0z 修改直线端点的坐标 setqell 1 entgetel1 第一条直线的图元表 setqell 1 subst vl list 10p1 assoc10ell 1 ell 1 直线的新端点替换直线的老端点 setqell 1 subst vl list 11p3 assoc11ell 1 ell 1 直线的新端点替换直线的老端点 entmodell 1 更新第一条直线 setqell 2 entgetel2 第二条直线的图元表 setqell 2 subst vl list 10p2 assoc10ell 2 ell 2 直线的新端点替换直线的老端点 setqell 2 subst vl list 11p4 assoc11ell

温馨提示

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

评论

0/150

提交评论