![]() |
[建议]【再论vlisp中关于对象捕捉编程问题】
[建议]【再论vlisp中关于对象捕捉编程问题】
www.dimcax.com [建议]【再论vlisp中关于对象捕捉编程问题】 众所周知,在autocad的lisp程序开发中,最多的使用函数为(command ....), 正式因为这个函数给了在autocad应用领域的非程序员开发者令人振奋的、极其便捷的、 简明直观和高效率的编程实现,省去了object arx开发的繁琐。也是lisp到vlisp的整 个成长历程中,有多少莘莘学子和热血青年,花费多少个日日夜夜,舍弃咖啡屋的浪漫、 丢下月光下的温馨,陪伴它“good good study,day day up”,也就才拥有了我们各 方论坛中的繁荣昌盛的今天。然而,lisp编程中,绘制对象时关闭对象捕捉和程序出错 /系统取消引起的错误处理问题也是困扰多年的老话题了。常规程序片段如下: (setq oldosmode (getvar "osmode")) (setvar "osmode" 0) (command "_.line" pt1 pt2 "") ...... (setvar "osmode" oldosmode) 这段程序可以看出,为防止绘制对象(如: line)是因捕捉未关闭而造成cad绘制直线 对象时产生错误,而进行了在绘制直线前,先关闭捕捉,再绘制直线,然后恢复捕捉设置 的方法。当然对于这段程序的设计思路和编制首先是没有问题的,同时常规测试运行也正 确。然而实际操作中,因在autocad命令行按esc键等终止后,且采用(defun *error()) 函数无法捕捉到错误的情况下,上面的程序就会大相径庭了:程序运行之前的捕捉设置丢 失了! 如何解决这个问题呢,各家论坛上曾介绍了不少关于错误信息捕获(defun *error()) 函数的加强编程,但是对于捕捉丢失的问题收效甚微。下面来看看伟大的autocad帮州文件 中关于【osmode 系统变量】是如何介绍的: 【osmode 系统变量】 类型:整数 保存位置:注册表 初始值:4133 使用以下位码设置“对象捕捉”的运行模式: 0 non(无) 1 end(端点) 2 mid(中点) 4 cen(圆心) 8 nod(节点) 16 qua(象限点) 32 int(交点) 64 ins(插入点) 128 per(垂足) 256 tan(切点) 512 nea(最近点) 1024 qui(快速) 2048 app(外观交点) 4096 ext(尺寸线) 8192 par(平行) 要指定多个对象捕捉方式,请输入各个位码值之和。例如,输入 3 指定“端点”( 位 码1)和“中点”(位码 2)对象捕捉。输入 16383 指定全部对象捕捉方式。 使用状态行的“对象捕捉”按钮关闭对象捕捉模式,除了返回 osmode 的普通值,还将 返回位码16384(0x4000)。这个附加值有助于开发人员编写 autocad 应用程序并将此模式与 “绘图设置”对话框关闭的对象捕捉模式区别开来。设置此位码值将关闭对象捕捉。在该位 码值关闭时将osmode设置为其他值可以打开对象捕捉。 请注意仔细阅读“使用状态行的....”这段。其中这个返回码:16384,应该引起程序员 的非常重视!简而言之:在(getvar "osmode")值加上16384,就等于用鼠标单击命令行下方 的[捕捉对象]按钮,例如: 若: osmode=3,即打开对象捕捉开关,且设置为“端点”和“中点”; 则: osmode=3+16384=16387,即关闭对象捕捉开关,而“端点”和“中点”仍然存在, 仅仅是被屏蔽掉了。当再次设置: osmode=16387-16384=3 时捕捉对象被打开了,且为“端 点+中点”模式。 综上所述,根据以上分析,则该段程序改写如下: (setvar "osmode" (+ (rem (getvar "osmode") 16384) 16384));关闭捕捉. (command "_.line" pt1 pt2 "") ...... (setvar "osmode" (rem (getvar "osmode") 16384));打开捕捉. 编写为函数则,如下: ;;;************************** ;;; no.0 对象捕捉开关 函数 ;;;************************** (defun ayosmode (isopensnap) (if isopensnap (setvar "osmode" (rem (getvar "osmode") 16384));打开捕捉. (setvar "osmode" (+ (rem (getvar "osmode") 16384) 16384));关闭捕捉. );end_if );end_defun 则上述程序段则改写为: (ayosmode nil);关闭捕捉. (command "_.line" pt1 pt2 "") ...... ((ayosmode t);打开捕捉. 【解释说明】如上的对象捕捉设置函数,和采用(setvar "osmode" 0)后恢复到原来的设置值有何不同 呢? 1、函数(defun ayosmode ...)没有显示的设置对象捕捉为: osmode=0,仅仅是加上系统提供的16384值, 暂时屏蔽了对象捕捉,等同于用鼠标单击命令行下方的[捕捉对象]按钮关闭对象捕捉,没有重新设置对象捕捉 码数值。 2、无论系统中发生什么错误/取消/终止,即便是程序中(defun *error())函数捕捉不到的错误信息也好, 系统任然能够隐式保留对象捕捉设置值,仅仅是像[捕捉对象]按钮被用鼠标单击后关闭一样而已。 3、能够和autocad系统中提供的命令一样,对象捕捉总是保存最近用户设置过的设置码,因而完成了程序 员开发的程序和auotcad系统命令一样,在对象捕捉控制方面相同的效果。 d 呀,真想不到还有这东西存在,lisp实在,魅力无穷呀 d (defun set-osmode (flag) (setvar "osmode" (boole (cond (flag 2) (7) ) (getvar "osmode") 16384 ) ) ) d 我觉得这样比较实用: (command "line" "_non" pt1 "_non" pt1 "") 省去了osmode的设置 d |
所有的时间均为北京时间。 现在的时间是 07:01 AM. |