我们一起学习lisp开发(第六辑)
这一辑介绍反应器,它分好几类:数据库反应器,文档反应器,编辑器反应器,链接反应器,对象反应器。下面引例就是一个编辑器反应器,当发出关闭图形命令时应用程序作出反应。Vlisp开发语言可以做反应器,反应器是真正的智能:
(defun savedrawinginfo (calling-reactor commandinfo / dwgname filessze)
(vl-load-com)
(setq dwgname (cadr commandinfo)
filesize (vl-file-size dwgname)
)
(alert (strcat "这个文件(" dwgname ")的大小是" (itoa filesize) "字节"))
(princ)
)
先定义如上函数并加载
然后在命令行输入:
(vlr-dwg-reactor nil '((:vlr-savecomplete . savedrawinginfo)))回车
当前图形就被加载了一个反应器,该反应器判断用户通过任何方式发出save命令后,显示出当前文件的大小
下面通过一个实例来说明:
;;;reac命令,修改反应器练习
(defun c:reac (/); cp r1 r2 p1 p2 p3 p4 vc eh1 eh2 eh_l vc_l)
(vl-load-com)
(setvar "cmdecho" 0)
(setvar "osmode" 0)
(setq cp (getpoint "\n指定圆的中心点: "))
(setq r1 (getdist cp "\n输入园的半径: "))
(setq r2 (* 1.2 r1))
(setq p1(polar cp 0 r2)
p2(polar cp (* pi 0.5) r2)
p3(polar cp pi r2)
p4(polar cp (* pi 1.5) r2)
)
(command "layer" "m" "cuxian" "")
(command "layer" "lw" 0.3 "cuxian" "");更改cuxian线宽为0.3
(command "circle" cp r1)
(setq vc (vlax-ename->vla-object (entlast)))
(command "layer" "m" "xixian" "")
(command "layer" "c" 1 "xixian" "l" "center" "xixian" "");更改xixian为红色点划线
(command "line" p1 p3 "")
(setq eh1 (cdr (assoc 5 (entget (entlast)))))
(command "line" p2 p4 "")
(setq eh2 (cdr (assoc 5 (entget (entlast)))))
(setq eh_l (list eh1 eh2));句柄表,它们将是反应器的关联数据
(setq vc_l (list vc));vla对象表,它们将是反应器的所有者
(vlr-pers (vlr-object-reactor vc_l eh_l '((:vlr-modified . change))))
;反应器链接到圆c上,两直线为关联数据,当修改圆c时调用函数change
(vlr-pers (vlr-object-reactor vc_l nil '((:vlr-modified . show))))
;反应器链接到圆c上,无关联数据,当修改圆c时调用函数show
(setvar "cmdecho" 1)
(setvar "osmode" 4133)
(princ)
)
;;;change函数
(defun change(notifier-object reactor-object parameter-list /)
;ec ec_l r2 eh_l e1_l e2_l p1 p2 p3 p4 )
(vl-load-com)
(setq ec (vlax-vla-object->ename notifier-object)
ec_l (entget ec)
cp (cdr (assoc 10 ec_l))
r2 (* 1.2 (cdr (assoc 40 ec_l)))
);新数据
(setq eh_l (vlr-data reactor-object));获取反应器的关联数据: 句柄表
(setq e1_l (entget (handent (car eh_l)));读出直线一图元表
e2_l (entget (handent (cadr eh_l)));直线二图元表
)
(setqp1(polar cp 0 r2)
p2(polar cp (* pi 0.5) r2)
p3(polar cp pi r2)
p4(polar cp (* pi 1.5) r2)
);从新计算直线个端点
(setq e1_l (subst (vl-list* 10 p1) (assoc 10 e1_l) e1_l));修改直线一的起点
(setq e1_l (subst (vl-list* 11 p3) (assoc 11 e1_l) e1_l));修改直线一的端点
(entmod e1_l);更新直线一的图元表
(setq e2_l (subst (vl-list* 10 p2) (assoc 10 e2_l) e2_l))
(setq e2_l (subst (vl-list* 11 p4) (assoc 11 e2_l) e2_l))
(entmod e2_l);更新直线二的图元表
)
;;;show函数
(defun show (notifier-object reactor-object parameter-list / r1)
(vl-load-com)
(setq r1 (vla-get-diameter notifier-object));获取直径
(setq r1 (rtos r1 2 4 ));转换为字符串
(alert (strcat "圆的内径是: " r1));报告操作结果
)反应器做起来比前面的难度大一些,整体思想是:对象链接了反应器后,当发生某些事件时,反应器将所发生的事件通知给应用程序,而应用程序根据具体事件作出相应决策。
呵呵,如果将反应器显示的内容直接改为标注,那就有点proe的味道了,画了一个圆,马上自动标注半径了......
回复 #2 truezx 的帖子
呵呵,从理论上讲是可以做到的。 有些东西还看不懂。 楼主厉害 啊 真厉害 非常有用, 感谢楼主的分享。 谢版主分享,辛苦了。
页:
[1]