Author Topic: when error, I want Restore the "textstyle"  (Read 6021 times)

0 Members and 1 Guest are viewing this topic.

liuhaixin88

  • Guest
when error, I want Restore the "textstyle"
« on: May 16, 2014, 07:59:01 AM »
This code is restore the layer
Code: [Select]
(defun c:xxx(/ *error* cl  )
Code: [Select]
(defun *error* (msg)
    (redraw)
    (if cl
      (setvar 'clayer cl)
    )
    (if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
      (princ msg)
      (princ (strcat "\n** Error: " msg " **"))
    )
  )

I want restore the layer and textstyle together, how to modify?
« Last Edit: May 16, 2014, 08:45:32 AM by liuhaixin88 »

ronjonp

  • Needs a day job
  • Posts: 7524
Re: when error, I want Restore the "textstyle"
« Reply #1 on: May 16, 2014, 08:37:34 AM »
Try something like this:
Code: [Select]
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle")))
(defun *error* (msg)
  ;; Reset variables
  (mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
  (if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
    (princ (strcat "\nError: " msg))
  )
  (princ)
)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

liuhaixin88

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #2 on: May 16, 2014, 08:47:26 AM »
Modify it like this ? ok?
Code: [Select]
(defun c:xxx(/ *error* cl ts )
Code: [Select]
(defun *error* (msg)
    (redraw)
    (if cl
      (setvar 'clayer cl)
    )
    (if ts
      (setvar 'TEXTSTYLE ts)
    )
    (if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
      (princ msg)
      (princ (strcat "\n** Error: " msg " **"))
    )
  )

liuhaixin88

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #3 on: May 16, 2014, 09:55:19 AM »
Try something like this:
Code: [Select]
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle")))
(defun *error* (msg)
  ;; Reset variables
  (mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
  (if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
    (princ (strcat "\nError: " msg))
  )
  (princ)
)


Hi, ronjonp ,
Thank you
At the end of  routine(normal finish) ,how to restore ?

ronjonp

  • Needs a day job
  • Posts: 7524
Re: when error, I want Restore the "textstyle"
« Reply #4 on: May 16, 2014, 10:25:19 AM »
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

liuhaixin88

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #5 on: May 16, 2014, 10:34:32 AM »
(mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)

OK! is good ! thank you!

liuhaixin88

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #6 on: May 16, 2014, 12:42:10 PM »
Try something like this:
Code: [Select]
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle")))
(defun *error* (msg)
  ;; Reset variables
  (mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
  (if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
    (princ (strcat "\nError: " msg))
  )
  (princ)
)


Hi ,ronjonp,
Your routine is good , can add in "osmode" ?

Lee's rountine
Code: [Select]
(defun c:test ( / *error* osm )
 
    (defun *error* ( msg )
        (if osm (setvar 'osmode osm))
        (if (not (member msg '("Function cancelled" "quit / exit abort")))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

    (setq osm (getvar 'osmode))
    (setvar 'osmode 0)

    (rtos (getreal "\nPress Esc to exit, press Enter to force an error ..."))

    (setvar 'osmode osm)
    (princ)
)

ronjonp

  • Needs a day job
  • Posts: 7524
Re: when error, I want Restore the "textstyle"
« Reply #7 on: May 16, 2014, 12:44:47 PM »
You can add whatever other variables you want to this portion of the code:


'("clayer" "textstyle")


That's the beauty of it :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

liuhaixin88

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #8 on: May 16, 2014, 12:58:13 PM »
You can add whatever other variables you want to this portion of the code:


'("clayer" "textstyle")


That's the beauty of it :)

This ?
Code: [Select]
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle" "osmode")))
(defun *error* (msg)
  ;; Reset variables
  (mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
  (if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
    (princ (strcat "\nError: " msg))
  )
  (princ)
)

ronjonp

  • Needs a day job
  • Posts: 7524
Re: when error, I want Restore the "textstyle"
« Reply #9 on: May 16, 2014, 01:16:16 PM »
Yes

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

gile

  • Water Moccasin
  • Posts: 2493
  • Marseille, France
Re: when error, I want Restore the "textstyle"
« Reply #10 on: May 16, 2014, 01:42:15 PM »
Hi,

To set and restore system variables, you can also the ai_sysvar function.
This function is available in AutoCAD since a while.
It's defined in acaddoc20XX.lsp (ai_utils.lsp or acad.mnl in older versions), so it's automatically loaded in each document.

Quote
;;; --- ai_sysvar ------------------------------------------
;;; Change system variable settings and save current settings
;;; (Note: used by *merr* to restore system settings on error.)
;;;
;;; The <vars> argument is used to...
;;;   restore previous settings (ai_sysvar NIL)
;;;   set a single sys'var (ai_sysvar  '("cmdecho" . 0))
;;;   set multiple sys'vars (ai_sysvar '(("cmdecho" . 0)("gridmode" . 0)))
;;;
;;; defun-q is needed by Visual Lisp for functions which redefine themselves.
;;; it is aliased to defun for seamless use with AutoLISP.

Anywhere in the code, you can call ai_sysvar to save the current value of one or more sysvar and set it a new value (or not).

Example:
Code - Auto/Visual Lisp: [Select]
  1. ;; save and set "osmode" to 0
  2. (ai_sysvar '("osmode" . 0))
  3. ...
  4. ;; save and set "orthomode" to 1 and only save "autosnap"
  5. (ai_sysvar '(("orthomode" . 1) ("autosnap" . nil)))
  6. ...
  7. ;; restor all sysvars
  8. (ai_sysvar nil)

<EDIT> I forgot to say, the implementation of ai_sysvar is quite interesting with the use of defun-q which allows to store the list of var names ans values within the function.
« Last Edit: May 16, 2014, 02:19:18 PM by gile »
Speaking English as a French Frog

liuhaixin88

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #11 on: May 17, 2014, 12:45:51 PM »
Hi,

To set and restore system variables, you can also the ai_sysvar function.
This function is available in AutoCAD since a while.
It's defined in acaddoc20XX.lsp (ai_utils.lsp or acad.mnl in older versions), so it's automatically loaded in each document.

Quote
;;; --- ai_sysvar ------------------------------------------
;;; Change system variable settings and save current settings
;;; (Note: used by *merr* to restore system settings on error.)
;;;
;;; The <vars> argument is used to...
;;;   restore previous settings (ai_sysvar NIL)
;;;   set a single sys'var (ai_sysvar  '("cmdecho" . 0))
;;;   set multiple sys'vars (ai_sysvar '(("cmdecho" . 0)("gridmode" . 0)))
;;;
;;; defun-q is needed by Visual Lisp for functions which redefine themselves.
;;; it is aliased to defun for seamless use with AutoLISP.

Anywhere in the code, you can call ai_sysvar to save the current value of one or more sysvar and set it a new value (or not).

Example:
Code - Auto/Visual Lisp: [Select]
  1. ;; save and set "osmode" to 0
  2. (ai_sysvar '("osmode" . 0))
  3. ...
  4. ;; save and set "orthomode" to 1 and only save "autosnap"
  5. (ai_sysvar '(("orthomode" . 1) ("autosnap" . nil)))
  6. ...
  7. ;; restor all sysvars
  8. (ai_sysvar nil)

<EDIT> I forgot to say, the implementation of ai_sysvar is quite interesting with the use of defun-q which allows to store the list of var names ans values within the function.

Thanks  gile, I can't understand. Can you give me a routine ? like ronjonp.

liuhaixin88

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #12 on: June 06, 2014, 04:51:21 AM »
Yes

Hi, ronjonp , How are you!

If I want add "(command ".undo" "e")"  and "DIMSTYLE" to your function, how to do?


Code: [Select]
(setq vars (mapcar '(lambda (x) (cons x (getvar x))) '("clayer" "textstyle" "osmode")))
(defun *error* (msg)
  ;; Reset variables
  (mapcar '(lambda (x) (setvar (car x) (cdr x))) vars)
  (if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
    (princ (strcat "\nError: " msg))
  )
  (princ)
)

Code: [Select]
;;start;(command "_.undo" "be")
(defun _StartUndo (*DOC*)
  (_EndUndo *DOC*)
  (vla-StartUndoMark *DOC*)
)
;;end;(if (= 8 (logand (getvar "undoctl") 8)) (command "_.undo" "_e"))
(defun _EndUndo (*DOC*)
  (if (= 8 (logand 8 (getvar 'UNDOCTL)))
    (vla-EndUndoMark *DOC*)
  )
)
« Last Edit: June 06, 2014, 07:59:01 AM by liuhaixin88 »

reltro

  • Guest
Re: when error, I want Restore the "textstyle"
« Reply #13 on: June 06, 2014, 05:13:11 AM »
Hey People...

This is what I use, includes also a mechanism to undo all stuff done...

*error*-functions can also be nested

Code - Auto/Visual Lisp: [Select]
  1. ;Note:
  2. ;    *error* should not be localized!!!
  3.  
  4.  
  5. (defun ini*error* (name sysvars / *doc*)
  6.     (eval
  7.         (list 'defun '*error* '(msg / )
  8.             (list
  9.                 (lambda (name prevErrorHandler SysVars *doc* currentcmdecho / )
  10.                     (mapcar
  11.                         'setvar
  12.                         (mapcar 'car SysVars)
  13.                         (mapcar 'cdr SysVars)
  14.                     )
  15.                     (vla-endundomark *doc*)
  16.                     (setq *error* prevErrorHandler)
  17.                     (if msg
  18.                         (progn
  19.                             (setvar 'cmdecho 0)
  20.                             (command-s "_.undo" 1 "")
  21.                             (setvar 'cmdecho currentcmdecho)
  22.                            
  23.                             (if (not (wcmatch msg "*EXIT*,*BREAK*,*CANCEL*"))
  24.                                 (progn
  25.                                     (princ "\n*** error ***\n")
  26.                                     (princ (strcat "\t" name ": " (vl-princ-to-string msg) "\n"))
  27.                                    
  28.                                     (*error* msg)
  29.                                     (princ)
  30.                                 )
  31.                             )
  32.                         )
  33.                     )
  34.                 )
  35.                 (vl-princ-to-string name)
  36.                 *error*
  37.                 (list 'quote
  38.                     (mapcar
  39.                         '(lambda (a / ) (cons a (getvar a)))
  40.                         sysvars
  41.                     )
  42.                 )
  43.                 *doc*
  44.                 (getvar 'cmdecho)
  45.             )
  46.         )
  47.     )    
  48. )
  49.    
  50. (ini*error* ;initialize error-handler
  51.     "String to display if an error occurs to identify wich function fails: "
  52.     '("CLAYER" "OSMODE" "CMDECHO" "DIMZIN") ;LIST of Sysvars to save/restore; String or Sym
  53. )
  54.  
  55. ;other stuff to do....
  56.  
  57. (*error* nil) ;restore Sys-Vars, and a previous-error-handler

reltro

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: when error, I want Restore the "textstyle"
« Reply #14 on: June 06, 2014, 10:47:08 AM »
@ Reltro:
Interesting code. I have a question about this portion:
Code: [Select]
(if (not (wcmatch msg "*EXIT*,*BREAK*,*CANCEL*"))
  (progn
    (princ "\n*** error ***\n")
    (princ (strcat "\t" name ": " (vl-princ-to-string msg) "\n"))

    (*error* msg)
    (princ)
  )
)

If an EXIT/BREAK/CANCEL error occurs the restored *error* function is not called meaning only a single level is undone.

If a different error occurs the restored *error* function is called meaning all levels are undone. And there will also be a superfluous call to the 'default' *error* function.

I may be missing something but this does not seem logical.