本帖最后由 作者 于 2009-2-19 13:55:36 编辑
众所周知,在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系统命令一样,在对象捕捉控制方面相同的效果。
|