In memory of Rolf Wischnewski
Die Funktion ssget unterstützt nicht, wie die Funtionen (n)entsel, eine eigene Meldung am Eingabefenster (Befehlsprompt) auszugeben. Schade eigentlich, denn oftmals möchte man gerne den CAD-Anwender informieren, daß er nur bestimmte Objekte wählen soll. Als Abhilfe gibt es natürlich die Möglichkeit vor dem ssget-Aufruf einen Hinweistext auszugeben, aber mal ehrlich, dass sieht irgendwie nicht ganz so toll aus wenn da steht
Bitte nur Kreise auswählen
Objekte wählen
Aber mit ein paar Tricks läßt sich eine eigene ssget-Funktion basteln. Was wir also brauchen ist eine Möglichkeit, die Meldung von ssget zu unterdrücken. Das geht mit Hilfe der Systemvariablen NOMUTT.
Auszug aus der Hilfe...
Unterdrückt die Anzeige von Meldungen, wenn die Meldungen ansonsten nicht unterdrückt würden. In der Regel werden alle Meldungen in AutoCAD angezeigt, nicht jedoch bei Skripten, LISP-Routinen usw.
0 Normales Anzeigeverhalten.
1 Unterdrückt die Anzeige von Meldungen grundsätzlich.
Doch Vorsicht!
Einmal gesetzt, werden alle Meldungen von Autocad unterdrückt. Man muß also darauf aupassen, daß bei einem Fehlerabbruch NOMUTT wieder zurückgesetzt wird!
Und noch ein Problem gilt es zu bewältigen. ssget unterstützt optionale Parameter und mit Lisp kann man bekannterweise keine optionalen Parameter verwenden... oder doch?
Fassen wir zusammen wie unsere eigene ssget-Funktion aussehen soll.
- Eigenen Meldungstext verwenden
- NOMUTT Variable muß unbedingt wieder zurückgestellt werden (auch bei einem Abbruch mittes ESC!)
- optionale Parameter
Schritt 1: Eigene Meldung
(setq oldsysvar (getvar "NOMUTT")) ;_ Speichern der aktuellen Einstellung
(princ (strcat " " #msg)) ;_ Ausgabe des eigenen Textes
(setvar "NOMUTT" 1) ;_ Systemvariable nomutt aktivieren und somit alle Meldungen unterdrücken
Schritt 2 : Fehlerabbruch, z.B. durch drücken der Taste ESC
Seit Autocad 2000 stehen neue Funktionen (Visual LISP) zur Verfügung. Unter anderem eine Funktion, die einen Fehler abfängt:
(vl-catch-all-apply
(list 'lambda '() '(setq retval (ssget)))
)
Wenn man diesen Befehl aufruft und schliesslich ESC drückt erhält man folgende Meldung.
#<%catch-all-apply-error%>
Damit wir uns jetzt nicht zu weit vom eigentlichen Thema entfernen, möchte ich an dieser Stelle nicht weiter hierauf eingehen, nur soviel sei gesagt, das hierbei es zu keinem Funktionsabbruch kommt, sondern innerhalb der Funktion, sofern noch Befehle anschliessend aufgerufen werden, weitere Befehle evaluiert werden.
Schritt 3 : optionale Parameter
Die Lösung ist eigentlich ganz einfach, wir übergeben die Argumente für ssget als Liste und übergeben diese Liste mittels apply (!) an die Funktion ssget!!
Und so könnte nun eine eigene ssget Funktion aussehen:
; Argumente
; #msg = Eingabeaufforderungstext (String)
; #arg-list = ([sel-method] [pt1 [pt2]] [pt-list] [filter-list]))
; sexy coded by Rolf Wischnewski (www.cadmaro.de)
(defun :SS-ssget (#msg #ArgList / OldSysVar RetVal)
(if #msg
(progn (setq OldSysVar (getvar "NOMUTT"))
(princ (strcat " " #msg))
(setvar "NOMUTT" 1))
)
(vl-catch-all-apply
(list 'lambda '() '(setq RetVal (apply 'ssget #ArgList)))
)
(if #msg
(setvar "NOMUTT" OldSysVar)
)
RetVal
)
Aufruf sieht dann so aus:
(:ss-ssget "Bitte nur weisse Linien auswählen " '(((0 . "LINE") (62 . 7))))
=> Bitte nur weisse Linien auswählen
oder auch so:
(:ss-ssget nil '(((0 . "LINE") (62 . 7))))
=> Objekte wählen:
Diese Möglichkeit geht natürlich auch:
(:ss-ssget "Für eine Auswertung benötige ich weitere Elemente :" nil)
=> Für eine Auswertung benötige ich weitere Elemente:
Und noch ein Aufruf zum Schluß:
(:ss-ssget "Moment bitte, ich sammle alle Punkte... " '("_X" ((0 . "POINT"))))
=> Moment bitte, ich sammle alle Punkte... <Selection set: f>
Viel Spaß mit der "neuen" ssget Funktion.
Mit freundlicher Genehmigung von Rolf Wischnewski. Originalbeitrag im Februar 2006, CADmaro.de