明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4817|回复: 10

[源码] 请教,vl-catch-all-apply方法之后如何判断是esc还是回车?

[复制链接]
发表于 2013-4-17 19:33 | 显示全部楼层 |阅读模式
就是怎么根据vl-catch-all-error-message的返回消息判断是按了esc,还是按了回车、空格或右键,然后分别处理?
检索了一下,没看到用lisp怎么解决这个问题的。
发表于 2013-4-17 20:29 | 显示全部楼层
本帖最后由 Gu_xl 于 2013-4-18 09:19 编辑

请举出具体实例来分析!有很多种方法进行错误处理分析!去参考下我的这篇帖子:
【Gu_xl】Lisp程序设计错误处理的技巧 ...

 楼主| 发表于 2013-4-17 20:33 | 显示全部楼层
以下代码来自于
出错处理案例解析 [url]http://bbs.mjtd.com/forum.php?mod=viewthread&tid=85081&fromuid=219579[/url]
  1. ;;;错误处理教程-1
  2. (defun c:tt1 (/  varlst var_old var_new)
  3.   (defun *error* (inf)
  4.     (setq inf (strcase inf t)) ;将出错信息转换为小写字符串
  5.     (cond
  6.          ((wcmatch inf "*break,*cancel*,*exit*,*取消*") ;|按了<Esc>键出错处理|;
  7.            (princ "\n用户按了<Esc>强制退出\n")
  8.            (mapcar 'setvar varlst var_old)
  9.           )
  10.         (t ;|其余错误处理|;
  11.             (princ (strcat "\n" inf))
  12.             (mapcar 'setvar varlst var_old)
  13.         )
  14.     ) ;_ 结束cond
  15.     (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  16.     (princ)
  17.   ) ;_ 结束defun
  18.   (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  19.   (setq varlst '("osmode")
  20.            var_new '(0)
  21.            var_old (mapcar 'getvar varlst)
  22.   ) ;_ 结束setq
  23.   (mapcar 'setvar varlst var_new)
  24.   (princ "\n按<Esc>强制退出, <空格>/<Enter>/<右键>错误...")
  25.   (rtos (getreal "\n请输入实数:"));出错后转到内部自定义的*error*函数
  26.   (mapcar 'setvar varlst var_old)
  27.   (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  28.   (princ)
  29. ) ;_ 结束defun
  30. ;;;错误处理教程-2
  31. (defun c:tt2 (/ err inf varlst var_old var_new)
  32.    (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  33.    (setq err (vl-catch-all-apply
  34.                                      '(lambda ()
  35.                                                   (setq varlst  '("osmode")
  36.                                                           var_new '(0)
  37.                                                           var_old (mapcar 'getvar varlst)
  38.                                                     ) ;_ 结束setq
  39.                                                    (mapcar 'setvar varlst var_new)
  40.                                                    (princ "\n按<Esc>强制退出, <空格>/<Enter>/<右键>错误...")
  41.                                                    (rtos (getreal "\n请输入实数:"))
  42.                                         ) ;_ 结束lambda
  43.                        ) ;_ 结束vl-catch-all-apply
  44.   ) ;_ 结束setq
  45.   (if (vl-catch-all-error-p err)
  46.           (progn ;|出错处理|;
  47.             (setq inf (strcase (vl-catch-all-error-message err) t)) ;将出错信息转换为小写字符串
  48.             (cond ((wcmatch inf "*break,*cancel*,*exit*,*取消*") ;|按了<Esc>键出错处理|;
  49.             (princ "\n用户按了<Esc>强制退出\n")
  50.             (mapcar 'setvar varlst var_old)
  51.             (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  52.            )
  53.            (t ;|其余错误处理|;
  54.             (princ (strcat "\n" inf))
  55.             (mapcar 'setvar varlst var_old)
  56.             (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  57.            )
  58.             ) ;_ 结束cond
  59.             (princ)
  60.           ) ;_ 结束progn
  61.           (progn ;|程序正常运行完毕的处理|;
  62.             (princ "\n")
  63.             (mapcar 'setvar varlst var_old)
  64.             (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  65.             (princ)
  66.           ) ;_ 结束progn
  67.   ) ;_ 结束if
  68. ) ;_ 结束defun
在上面两个出错处理函数教程中,vl-catch-all-apply方法之后按<Esc>强制退出与<空格>/<Enter>/<右键>都是一同退出,我想加一个判断,如果是按<Esc>就强制退出,按<空格>/<Enter>/<右键>就执行其它代码而不退出,关键是vl-catch-all-apply方法之后如何判断是esc还是回车?
 楼主| 发表于 2013-4-17 20:38 | 显示全部楼层
本帖最后由 yx5277 于 2013-4-17 20:41 编辑
Gu_xl 发表于 2013-4-17 20:29
请举出具体实例来分析!有很多种方法进行错误处理分析!去参考下我的这篇帖子:
【Gu_xl】Lisp程序设计错误 ...

    超版的帖子我看过,里面提到“简而言之就是使用Vl-Catch-All-Apply对函数进行包装,然后使用Vl-Catch-All-Error-P判断包装函数返回值是否异常,若有异常,可使用Vl-Catch-All-Apply-Error-Message函数输出错误信息,并再此对错误进行处理。”
现在我想知道在Vl-Catch-All-Apply-Error-Message函数输出的错误信息里,如何区分esc和回车?
发表于 2013-4-17 20:42 | 显示全部楼层
yx5277 发表于 2013-4-17 20:33
以下代码来自于
出错处理案例解析 http://bbs.mjtd.com/forum.php?mod=viewthread&tid=85081&fromuid=2195 ...

仔细研读我的帖子,你就会找到答案!
 楼主| 发表于 2013-4-17 20:49 | 显示全部楼层
Gu_xl 发表于 2013-4-17 20:42
仔细研读我的帖子,你就会找到答案!

    谢谢G版,难道要用*error*方法?恕我愚昧,参不透超版的答案,还请直接明示。可否在板凳的示例代码中添加代码解决?

点评

还没去研究,怎么就知道你不能搞明白!  发表于 2013-4-17 20:59
 楼主| 发表于 2013-4-17 21:30 | 显示全部楼层
本帖最后由 yx5277 于 2013-4-17 22:12 编辑
yx5277 发表于 2013-4-17 20:49
谢谢G版,难道要用*error*方法?恕我愚昧,参不透超版的答案,还请直接明示。可否在板凳的示例代码中 ...

我把你的tt6重建了一下,已经把好多的少掉的空格补上了,正在研究.....
直接运行的结果显示,esc和回车都是调用了同一个出错处理函数*error*,该如何让他们调用不同出错处理函数,G版就直接告诉了吧。。。
  1. (defun c:tt6 ()
  2. ;; 初始化错误处理,出错后回到初始状态
  3.         (gxl-error-init1 (list "cmdecho" 0 "osmode" 0) nil 2)
  4.         (setq p1 (getpoint "\n输入直角三角形直角边第一点: "))
  5.         (setq p2 (getpoint p1 "\n输入直角三角形直角边第二点: "))
  6.         (setq d1 (distance p1 p2))
  7.         (vl-cmdf "_line" p1 p2 "")
  8.         (setq dd (getdist p1 "\n请输入斜边长度: "))
  9.         ;;;根据勾股定理计算另一条直角边长度
  10.      (setq d2  
  11.         (VL-CATCH-ALL-APPLY ;_ 捕捉sqrt函数的错误
  12.           'sqrt
  13.           (list
  14.             (- (* dd dd) (* d1 d1))
  15.           )
  16.         )
  17.      )
  18.    (if(VL-CATCH-ALL-ERROR-P d2) ;_ 当输入的斜边长度小于直角边长度时sqrt函数会出错
  19.      (progn ;_ sqrt 函数结果异常
  20.      (alert (VL-CATCH-ALL-ERROR-MESSAGE d2)) ;_ 提示错误信息
  21.      (exit) ;_ 制造一个错误退出程序
  22.      )
  23.      ;;;绘制三角形
  24.      (progn
  25.        (setq ang (+ (angle p1 p2) (* 0.5 pi)))
  26.        (command "_line" p2 (polar p2 ang d2) p1 "")
  27.        )
  28.      )
  29.      (gxl-error-end) ;_ 恢复错误处理
  30.      (princ)
  31.      )

  32. (defun gxl-error-init1 (syslst fun UndoMode / sysname sysvar)
  33.         (setq *olderror* *error*
  34.               *Function* fun
  35.               *UndoMode* UndoMode
  36.      )
  37.      (defun *error* ( msg / sysname sysvar)
  38.        (if (= 2 *UndoMode*)
  39.          (progn
  40.        (if (= 8 (logand (getvar "undoctl") 8))
  41.          (command "_undo" "_e")
  42.        )
  43.        (command "_U")
  44.          )
  45.          (progn
  46.        (if *sysvarInit*
  47.          (while (and (setq sysname (car *sysvarInit*))
  48.                  (setq sysvar (cadr *sysvarInit*))
  49.             )
  50.            (setq *sysvarInit* (cddr *sysvarInit*))
  51.            (setvar sysname sysvar)
  52.          )
  53.        )
  54.        (if *Function* (VL-CATCH-ALL-APPLY *Function*)) ;_执行函数
  55.        (if (= *UndoMode* 1)
  56.          (if(= 8 (logand (getvar "undoctl") 8))
  57.            (command "_undo" "_e")
  58.          )
  59.        )
  60.          )
  61.        )
  62.        (setq *error* *olderror*
  63.          *olderror* nil
  64.          *Function* nil
  65.          *UndoMode* nil
  66.        )
  67.        (or (wcmatch(strcase msg) "*BREAK,*CANCEL*,*EXIT*")
  68.        (princ (strcat "\n** Error: " msg " **"))
  69.        )
  70.      );defun
  71.    
  72.      (if (or (= *UndoMode* 1) (= *UndoMode* 2))
  73.        (progn
  74.          ;;如果有活动编组,先结束编组
  75.          (if (= 8 (logand (getvar "undoctl") 8))
  76.        (command "_undo" "_e")
  77.          )
  78.          (command "_undo""_BE") ;_ 编组开始
  79.        )
  80.      )
  81.      (if syslst
  82.        (while (and (setq sysname (car syslst))
  83.            (setq sysvar (cadr syslst))
  84.           )
  85.          (setq *sysvarInit*
  86.             (append *sysvarInit*
  87.                 (list sysname (getvar sysname))
  88.             )
  89.          )
  90.          (setq syslst (cddr syslst))
  91.          (setvar sysname sysvar)
  92.        )
  93.      )
  94.      (princ)
  95.    )

  96. ;;(gxl-error-end) 恢复*error*
  97.        (defun   gxl-error-end()
  98.            (if(= 8 (logand (getvar "undoctl") 8))
  99.            (command "_undo" "_e")
  100.          )
  101.          (if *olderror*
  102.            (setq *error* *olderror*
  103.                  *olderror* nil
  104.            ) ;_ 恢复*error*函数
  105.       )
  106.       (if *sysvarInit* ;_ 恢复储存的系统变量
  107.         (while (and (setq sysname (car *sysvarInit*))
  108.             (setq sysvar (cadr *sysvarInit*))
  109.            )
  110.           (setq *sysvarInit* (cddr *sysvarInit*))
  111.           (setvar sysname sysvar)
  112.         )
  113.       )
  114.       (setq *Function* nil
  115.             *UndoMode* nil
  116.       )
  117.       (princ)
  118.      )

复制代码


发表于 2013-4-18 08:32 | 显示全部楼层
本帖最后由 Gu_xl 于 2013-4-18 12:19 编辑
yx5277 发表于 2013-4-17 21:30
我把你的tt6重建了一下,已经把好多的少掉的空格补上了,正在研究.....
直接运行的结果显示,esc和回车都 ...

两点提示:1、不同的错误,*error*函数的错误信息 是不同的,这个是判断错误类型的一种方法,根据不同的错误类型进行相应的处理!
2、用VL-CATCH-ALL-APPLY 就地捕捉错误,根据VL-CATCH-ALL-ERROR-MESSAGE函数提供的错误信息来判断错误类型,然后进行相应的处理!
自己体会一下下面的例子:
  1. (defun c:tt (/ *error*)
  2.   (defun *error* (s)
  3.     (princ "**error提示有错** ")
  4.     (princ s) ;_ 按esc退出,打印出错信息
  5.     (princ)
  6.     )
  7.   (setq loop t)
  8.   (while loop
  9.     (setq p (VL-CATCH-ALL-APPLY 'rtos (list (getreal "\n输入实数:"))))
  10.     (if (VL-CATCH-ALL-ERROR-P p)
  11.       (princ (strcat "**VL-CATCH-ALL-ERROR-P提示有错:** "
  12.                      (VL-CATCH-ALL-ERROR-MESSAGE p)
  13.                      )
  14.              ) ;_ 按回车或右键,输入错误,打印提示信息
  15.       (setq loop nil) ;_ 输入正确,结束while
  16.       )
  17.     )
  18.   (princ)
  19.   )


 楼主| 发表于 2013-4-18 16:47 | 显示全部楼层
Gu_xl 发表于 2013-4-18 08:32
两点提示:1、不同的错误,*error*函数的错误信息 是不同的,这个是判断错误类型的一种方法,根据不同的错 ...

你的办法不错,我想到了用    (if (= 52 (getvar "errno"))  也应该可以解决
 楼主| 发表于 2013-4-18 17:21 | 显示全部楼层
真是庸人自扰,学艺不精,板凳里的代码其实已经解决了我的问题
就下面的代码就可以了。
  1. (defun c:tt2 (/ err inf varlst var_old var_new)
  2.    (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  3.    (setq err (vl-catch-all-apply
  4.                                      '(lambda ()
  5.                                                   (setq varlst  '("osmode")
  6.                                                           var_new '(0)
  7.                                                           var_old (mapcar 'getvar varlst)
  8.                                                     ) ;_ 结束setq
  9.                                                    (mapcar 'setvar varlst var_new)
  10.                                                    (princ "\n按<Esc>强制退出, <空格>/<Enter>/<右键>错误...")
  11.                                                    (rtos (getreal "\n请输入实数:"))
  12.                                         ) ;_ 结束lambda
  13.                        ) ;_ 结束vl-catch-all-apply
  14.   ) ;_ 结束setq
  15.   (if (vl-catch-all-error-p err)
  16.           (progn ;|出错处理|;
  17.             (setq inf (strcase (vl-catch-all-error-message err) t)) ;将出错信息转换为小写字符串
  18.             (cond
  19.               ((wcmatch inf "*break,*cancel*,*exit*,*取消*") ;|按了<Esc>键出错处理|;
  20.               (princ (strcat "\n用户按了<Esc>强制退出!   " inf))
  21.               (mapcar 'setvar varlst var_old)
  22.               (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  23.               )
  24.               (t ;|其余错误处理|;
  25.               (princ (strcat "\n用户按了enter退出!   " inf))
  26.               (mapcar 'setvar varlst var_old)
  27.               (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  28.               )
  29.            ) ;_ 结束cond
  30.            (princ)
  31.          );_ 结束progn
  32.          (progn ;|程序正常运行完毕的处理|;
  33.             (princ "\n正常退出!")
  34.             (mapcar 'setvar varlst var_old)
  35.             (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
  36.             (princ)
  37.          ) ;_ 结束progn
  38.   ) ;_ 结束if
  39. ) ;_ 结束defun
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-3 11:27 , Processed in 6.411843 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表