It works with no problems on my system. NT 4 ADT 3.3
It is amazing how far such a seemingly simple idea goes for the interest of
good & proper coding.....
Beau
Doug Broad wrote in message
news:2F74E5F686EACD0F88C83B977C7AEA0C@in.WebX.maYIadrTaRb...
> Nice tutorial Bobby.
>
> Can't get the final routine to work however. No matter what I
> pick for the break, it doesn't exit the object select loop. Am running
AC2000 with Arch
> Desktop 2.
> Errno should work but doesn't on my system. Anyone else experience the
problem?
>
> And don't forget another possibility
>
> E) User selected an object not supported by the command.
> In this case blocks, text....
>
> That's where filtering the selection is important.
>
> (while (null (setq ss (ssget ":s" (list (cons 0
> "line,arc,circle,trace,lwpolyline,spline,"))))))
> could be better, filtering out incorrect object selection of insert, xref,
text....)
>
> Or entget could be used to get entity info from entsel ename and filter an
incorrect
> entity
> type prior to feeding to command.
>
> Doug
>
>
>
> "Bobby Jones" wrote in message
> news:40894B0A7B5E96C308F318FA7D85D1F5@in.WebX.maYIadrTaRb...
> > Several things can happen when you are asking the user to select an
object
> > with ENTGET.
> >
> > A) they will successfully select an object
> > B) they will mis-pick and select empty space in the drawing
> > C) they will hit enter to exit out of the selection process
> > D) they will hit escape to exit out of the entire routine
> >
> > Your routine should be smart enough to catch all of those events and
handle
> > them. The sign of a good lisp routine is one that emulates how acad
> > commands function so that the user has a consistent interface. So start
the
> > break command and see what it does in each of the four situations above.
If
> > the user selects an object, the routine runs with that object. If the
user
> > mis-picks, it asks him to select again. If they hit enter or escape the
> > command simply exits, with the exception that hitting escape prints
*Cancel*
> > to the command line. I think what you're really asking is how to do
that.
> > Let's re-write your routine and see just how to accomplish this.
> >
> > While ENTSEL honors keywords set up with the INITGET function, it does
not
> > honor the no null bit, so we will need to set up a while loop.
Basically we
> > are saying, "While the user hasn't selected anything, keep asking."
> > (while (not ent)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> >
> > Then you can ask for a break point on the line with GETPOINT. GETPOINT
does
> > honor the no null bit of INITGET, so use it.
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> >
> > Finally feed all this collected info to the break command.
> > (command "_.break" ent "f" pnt pnt)
> >
> > Also, since we are collecting all needed information prior to calling
the
> > COMMAND function, we will want to suppress any output to the command
line
> > from the actuall break command. Do this by setting the CMDECHO sysvar
to 0,
> > and then setting it back at the end of the routine. A nice clean exit
with
> > PRINC is always a nice touch.
> >
> > The complete function:
> > ((defun c:bb (/ ent pnt cmd)
> > (setq cmd (getvar "cmdecho"))
> > (setvar "cmdecho" 0)
> > (while (not ent)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> > (command "_.break" ent "f" pnt pnt)
> > (setvar cmdecho cmd)
> > (princ)
> > )
> >
> > Wow. That little function has really grown. Give it a try. How does
it
> > handle all the possible events listed above? It works beautifully when
the
> > user selects the line...Yea. It asks for a re-pick when they mis-pick
the
> > line...Yea. What? It won't exit the selection process when they hit
enter?
> > And WHAT!!!???!!! It leaves the CMDECHO sysvar set to 0 when they hit
> > escape??!!?? That's totally unacceptable. Let's fix it. First lets
fix
> > that escape key bug. Yes, it's a bug in your routine. To fix the bug
you
> > will need to implement a custom *error* handler. There has been much
> > discussion on this topic in the recent past, so I'm just going to put
one in
> > and let you either do the research yourself or come back and ask
specific
> > questions:
> >
> > The routine with the custom *error* handler:
> > (defun c:bb (/ ent pnt cmd *error*)
> >
> > (defun *error* (msg)
> > (if (not (member Msg '(nil "console break" "Function cancelled"
"quit /
> > exit abort")))
> > (princ (strcat "\nError: " Msg))
> > )
> > (setvar "cmdecho" cmd)
> > (princ)
> > )
> >
> > (setq cmd (getvar "cmdecho"))
> > (setvar "cmdecho" 0)
> > (while (not ent)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> > (command "_.break" ent "f" pnt pnt)
> > (*error* nil)
> > )
> >
> > Wow. Now our little function can't really be called a "little" function
> > anymore. Okay, so is it ready for prime time now? Well, give it a test
run
> > and see. How'd it do? You mean it still doesn't exit when the user
hits
> > enter while selecting an object? Well that's not so bad, is it? For
many
> > that's good enough, but I can tell that you're a perfectionist and that
you
> > want this thing perfect. So let's fix this one more time. Currently
our
> > function doesn't distinguish between a user mispick on the screen and
the
> > user hitting the enter key, or spacebar. All it knows is that nothing
was
> > selected and it wants something. The answer for how to determine the
> > difference between a mispick and an enter key lies in the ERRNO sysvar.
> > When ENTSEL fails with a user mispick, ERRNO is set to 7. Looking up
ERRNO
> > in the help files reveals a chart that lists error #7 as, "Object
selection:
> > pick failed". But when ENTSEL fails with a user hitting enter, ERRNO is
set
> > to 52, "Entity selection: null response". We can now use that in our
while
> > loop to determine why ENTSEL failed. Instead of looping until our
variable
> > 'ent' contains something, we can loop as long as the user mis-picks,
while
> > ERRNO = 7, and stop our loop only when they pick an object or if they
hit
> > enter, ERRNO = 52. Then we'll need to test our 'ent' variable to see if
the
> > user did indeed select an object or just hit enter. If they simply hit
> > enter, then we'll want to skip the code that asks for the break point
and
> > runs the break command.
> >
> > Final routine:
> > (defun c:bb (/ ent pnt cmd *error*)
> >
> > (defun *error* (msg)
> > (if (not (member Msg '(nil "console break" "Function cancelled"
"quit /
> > exit abort")))
> > (princ (strcat "\nError: # " (itoa (getvar "errno")) Msg))
> > )
> > (setvar "errno" 0)
> > (setvar "cmdecho" cmd)
> > (princ)
> > )
> >
> > (setq cmd (getvar "cmdecho"))
> > (setvar "cmdecho" 0)
> > (setvar "errno" 7)
> > (while (= (getvar "errno") 7)
> > (setq ent (entsel "\nSelect object to break: "))
> > )
> > (if ent
> > (progn
> > (initget 1)
> > (setq pnt (getpoint "\nSelect break point: "))
> > (command "_.break" ent "f" pnt pnt)
> > )
> > )
> > (*error* nil)
> > )
> >
> > Now that wasn't so hard, was it?
> > --
> > Bobby C. Jones
> > Dots & Parens living in harmony...
> >
> >
> >
>
>