lisp turns off osnaps

Discussion in 'AutoCAD' started by jb4pres, Jul 15, 2004.

  1. jb4pres

    jb4pres Guest

    Problem has come back with a lisp. The lisp breaks a line at a user given point. If you cancel out of the command it turns all osnaps off. Can this be fixed or can I at least create a toolbar button that will put my osnaps back?

    code:


    ;Cut or break pline ***** bb
    ;Code written by someone else... Thank you!
    (defun c:bb (/ pt1 pt2 pt3 aa aantal teller bb)
    (setq cmde (getvar "cmdecho"))(setvar "cmdecho" 0)
    (setq osm (getvar "osmode" ))(setvar "osmode" 679)
    (setq pt1 (getpoint "\nBreekpunt. "))
    (setvar "osmode" 0)
    (setq pt2 (polar pt1 (/ PI 6) 1)
    pt3 (polar pt1 (+ (/ PI 6) PI) 1)
    aa (ssget "C" pt2 pt3)
    aantal (sslength aa)
    )
    (setq teller 0)
    (repeat aantal
    (setq bb (ssname aa teller))
    (command "BREAK" bb pt1 pt1)
    (setq teller (1+ teller))
    )
    ( setvar "osmode" osm );
    ( setvar "cmdecho" cmde )
    (princ)
    )
     
    jb4pres, Jul 15, 2004
    #1
  2. jb4pres

    Devin Guest

    jb4pres,

    You have to put it into your *error* function, ie:

    (defun *error* ( msg / )
    (if
    *osmode*
    (progn
    (vla-setVariable curdoc "OSMODE" *osmode*)
    (setq *osmode* nil)
    )
    )
    (princ)
    )

    Then simply use *osmode* as the variable in your code where you store the
    osnap value. just remember to set it to nil at the end of your code. It
    also must be global I think so *error* can access it (so don't declare it in
    the function your making).

    HTH,

    Devin
     
    Devin, Jul 15, 2004
    #2
  3. jb4pres

    ECCAD Guest

    JB,
    Add this to your acaddoc.lsp file.
    ;;
    ;;
    ;; *********** Local Error Trap Function ************
    ;;
    (defun myerror (sxx)
    (if (= sxx nil)
    (setq sxx "console break")
    ); end if
    (if (not (member sxx '("console break" "Function cancelled")))
    (princ (strcat "\nError: " sxx))
    ); end if
    (if (= (member sxx '("console break" "Function cancelled")))
    (progn
    (prompt "\nError: Break...")
    (setvar "MENUECHO" 0)
    (setvar "HIGHLIGHT" 1)
    (setvar "SORTENTS" 1)
    (setvar "ATTDIA" 0); No Attribute Dialog Boxes, please
    (setvar "ATTREQ" 1); Attributes Required
    (setvar "CMDDIA" 1); Plot command dialog on
    ); end progn
    ); end if
    (setvars); reset all old system variables
    (setvar "CMDECHO" 0)
    (setq sxx nil)
    (princ)
    ); end function err
    (setq olderr *error* *error* myerror)
    ;;
    ;; Get Old System Variables
    ;;
    (defun getvars ()
    (setq osm (getvar "OSMODE"))
    ;; add any other system variables here
    ); end function
    (defun setvars ()
    (setvar "OSMODE" osm)
    ;; reset any other system variables here
    ); end function
    ;; *************** end of error trapping *****************
    ;;

    And, in any .lsp program that may be 'escaped', add:
    (getvars)

    Then, when the operator hits 'escape', or the program boms,
    the error trap will reset old settings..

    Cheers

    Bob
     
    ECCAD, Jul 15, 2004
    #3
  4. jb4pres

    jb4pres Guest

    Thanks Bob & Devin!!
     
    jb4pres, Jul 15, 2004
    #4
  5. jb4pres

    Tom Smith Guest

    Bob, several comments.

    Your generic error handler depends on having a list of variables which will
    always be saved and restored. Since you can't adjust this list to suit the
    particular lisp that invokes the error handler, people who take this
    approach inevitably wind up with a very long list of just about every
    variable that might ever be changed. This seems cumbersome.

    In your method, all those settings are saved in global variables, bringing
    up all the potential perils of having loads of globals flying around. If you
    have to do this, it would be preferable IMHO to keep all that stuff in a
    single global association list of the form (("variable1" . savedvalue1)
    ("variable2" . savedvalue2) ...), and for goodness sakes give the global a
    distinctive name that's unlikely to be stomped on , like
    *saved_variable_list*. One global beats many.

    What is the point of setting those 6 variables to hard-coded values in the
    event of a cancel, when the next statement will reset any or all of them to
    saved values? Why set CMDECHO to a hard-coded value after doing this? Why
    null out the ssx argument?

    My approach is to use a local error handler which is defined on the fly when
    a lisp executes. In my startup sequence for each document I define a
    function to build an error handler:

    (defun *init-error* (varlist / oce)
    (setq *error*
    (append
    '((msg / oce))
    (mapcar
    '(lambda (var) (list 'setvar var (getvar var)))
    varlist)
    '((setq oce (getvar "cmdecho")))
    '((setvar "cmdecho" 0))
    '((command "undo" "end"))
    '((setvar "cmdecho" oce))
    '((princ))))
    (setq oce (getvar "cmdecho"))
    (setvar "cmdecho" 0)
    (command "undo" "begin")
    (setvar "cmdecho" oce)
    (princ))

    This takes a list of variables to be saved, and defines an *error* function
    which will restore them to their saved values. Usage:

    (defun c:mylisp (/ *error* var1 var2) ;declare *error* local
    (*init-error* '("cmdecho" "osmode" "etc" "etc")) ;list variables to be
    saved
    (setvar "osmode" 0) ;change variables as needed in this lisp
    (do-whatever)
    (*error* nil)) ;reset variables

    Note that the normal clean exit is taken care of simply by calling the same
    error handler that is invoked by a program crash or a cancel, so the same
    cleanup happens no matter what. I don't echo the error message to the user.
    This is just my preference -- the messages are generally meaningless to
    anyone but a programmer, and I think the program logic should effectively
    rule them out anyway. For debugging purposes I simply comment out the
    *init-error* statement.

    Also not that *error* can be declared local now, eliminating the (setq
    olderr *error* *error* myerror) business.

    This method involves the theoretical overhead of redefining *error* each
    time the function is run, but it doesn't require global variables, can be
    targeted at only the variables that need saving, and it eliminates the need
    to define a different local error handler in each lisp.
     
    Tom Smith, Jul 19, 2004
    #5
  6. jb4pres

    ECCAD Guest

    Tom,
    I see all your points. Input taken. Thanks.
    As for the posted routine, I should have cleaned it up
    prior to posting. ...

    On the globals..yes the list is a little longer, but most people can handle adding a couple, or removing a couple - without getting into trouble. (keep it simple, and make it readable)..

    On the echo thing. I think you should echo someting - just to
    indicate that 'something' went wrong..otherwise, the operator
    may think all is ducky, and miss the fact that a routine blows..

    Bob
     
    ECCAD, Jul 19, 2004
    #6
  7. jb4pres

    Tom Smith Guest

    On the echo thing. I think you should echo someting - just to
    I'm a little undecided. I may add that, if only to be able to call (*error*
    "\nDone.") on normal termination. The user is normally well aware when a
    function "didn't work" and it doesn't do them much good to see gibberish
    like "bad argument type: (or stringp symbolp): nil" on their screen. Nobody
    in our company except me can deduce any meaning from that! But maybe just an
    all-purpose "Unknown Error" message would be good.
     
    Tom Smith, Jul 19, 2004
    #7
  8. jb4pres

    ECCAD Guest

    Tom,
    I find it useful when I support a cutomer via phone or E-Mail.
    They can cut/paste or tell me what the error said, and I can
    generally track it down that way. For 'internal' use, I agree, just *error* \nDone. would be adequate.

    Bob
     
    ECCAD, Jul 19, 2004
    #8
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.