In VLX kompilierte Dateien lassen sich unter anderem DCL-Dateien integrieren, was einige Vorteile mit sich bringt. So braucht man z.B. nur eine Datei und man ist nicht an einem Suchpfad von Autocad gebunden. Mittels Drag&Drop lassen sich so bequem Tools in Autocad laden.

Schön wäre es doch, wenn man das auch mit Lisp-Quelldateien machen könnte. Mit dem hier vorgestellten Trick ist das umsetzbar und bietet darüber hinaus sogar den Vorteil gegenüber der VLX-Variante, dass man vor dem Start des Dialoges dynamisch am DCL-Design noch arbeiten kann. Somit ist die etwas größere Lisp-Datei, als einzigen Nachteil betrachtet, vernachlässigbar.



Und so kann es umgesetzt werden.

 

1.

Die DCL-Datei kann ganz normal mit dem VLisp-Editor erstellt und als DCL abgespeichert werden. Sobald das Design fertig ist, benötigt man nur noch eine Funktion, mit der man die Datei als Liste einlesen kann:

; Argument: #FlN = Dateinname, ggf. mit Pfad
; sexy coded by Rolf Wischnewski (www.cadmaro.de)
(defun :L-File2List (#FlN / RetVal OpF)
   (cond ((setq #FlN (findfile #FlN))
     (setq OpF (open #FlN "r"))
     (while (car (setq RetVal (cons (read-line OpF) RetVal))))
     (close OpF)
     (reverse (cdr RetVal))
     )
    )
  )

Diese Funktion liest textbasierte Dateien zeilenweise ein und gibt diese als Liste zurück. Sollte die Datei nicht gefunden werden erfolgt ein nil als Rückgabe. Aufruf der Funktion als Beispiel:

(:L-File2List "c:\DCLworkDateien\MeinDCL.dcl")
(formatierte Rückgabe) => ("BSP : dialog {"
" label = \"Eingabe\";"
" : text {"
" key = \"TXT\";"
" }"
" : row {"
" : column {"
" : text {"
" key = \"BEZ1\";"
" value = \"Hier kommt dann der Text hin\";"
" }"
" : text {"
" key = \"BEZ2\";"
" value = \"Hier kommt dann der Text hin\";"
" }"
" }"
" : column {"
" : edit_box {"
" width = 8;"
" key = \"WERT1\";"
" }"
" : edit_box {"
" width = 8;"
" key = \"WERT2\";"
" }"
" }"
" }"
" ok_cancel;"
" }"

 )

 

 

2.

Die Funktion load_dialog benötigt explizit einen Dateinamen. Sollte beim Dateinamen keine Erweiterung angegeben sein, nimmt die Funktion als Suffix ein .dcl an. Die oben stehende Liste muss also als Datei gespeichert werden, nur
a) wohin und
b) wie soll der Dateiname sein, um nicht andere Dateien eventuell zu überschreiben?

Die Lösung ist die Visual-Lisp Funktion vl-filename-mktemp. Diese Funktion erstellt eine "einmalige" Datei, also ein Unikat. vl-filename-mktemp hat 3 optionale Parameter [pattern directory extension].

Mit Hilfe dieser Funktion können wir uns nun eine eigene Funktion programmieren:

; Argument : #List-of-Content = Liste mit Stringwerten
; sexy coded by Rolf Wischnewski (www.cadmaro.de)
(defun :F-DCLinlisp (#List-of-Content / opfile tmpf)
   (setq tmpf (vl-filename-mktemp "dcl~.dcl"))
   (cond ((setq opfile (open tmpf "w"))
     (foreach line #List-of-Content (write-line line opfile))
     (close opfile)
     tmpf
     )
   )
)

Schauen wir uns die Funktion näher an:

(setq tmpf (vl-filename-mktemp "dcl~.dcl"))

=> "C:\DOKUME~1\Rolf\LOKALE~1\Temp\dcl~001.dcl"

Es wird eine einmalige (Unikat) Datei im Temp-Ordner des Windows-Betriebssytems erstellt. Als Pattern wurde ein Dateinamen beginnend mit dcl~xxx.dcl gewählt.

(setq opfile (open tmpf "w"))

=> #<file "C:\DOKUME~1\Rolf\LOKALE~1\Temp\dcl~001.dcl">

Der Zugriff auf diese Datei und der Lesezugriff für andere Anwendungen wird gesetzt.

(foreach line #List-of-Content (write-line line opfile))

Die Zeilen werden in die Datei geschrieben und durch

(close opfile)

die Datei wieder geschlossen.

Zum Schluss gibt die Funktion den Dateinamen (tmpf) zurück.
Der Aufruf schließlich im Programm könnte so aussehen

(defun c:MeinProgramm (/ dcl_id DclFilename . . .)
  'machwas
  ;; starten des Dialoges
  (setq DclFilename
    (:F-DCLinLisp
      (list
        "BSP : dialog {"
        " label = \"Eingabe\";"
        " : text {"
        " key = \"TXT\";"
        " }"
        " : row {"
        " : column {"
        " : text {"
        " key = \"BEZ1\";"
        " value = \"Hier kommt dann der Text hin\";"
        " }"
        " : text {"
        " key = \"BEZ2\";"
        " value = \"Hier kommt dann der Text hin\";"
        " }"
        " }"
        " : column {"
        " : edit_box {"
        (strcat "width = "(if 'irgendwas "12;" "8;"));_ Breite der Texteingabebox in Abhängigkeit von irgendwas festlegen!
        " key = \"WERT1\";"
        " }"
        " : edit_box {"
        " width = 8;"
        " key = \"WERT2\";"
        " }"
        " }"
        " }"
        " ok_cancel;"
        " }"
        )
       )
     )
     ;; dialog laden
     (setq dcl_id (load_dialog DclFilename))
     (new_dialog "BSP" dcl_id)
     'actions
     (start_dialog)
     'tue_was
     (unload_dialog dcl_id)
     ;; Programmende
     (vl-file-delete DclFilename)
  )

Dadurch, dass die DCL-Datei durch Lisp heraus erstellt wird, besteht nun auch die Möglichkeit vor dem Start dynamisch Werte festzulegen (siehe hierzu das Beispiel innerhalb der Liste den strcat-Funktionsaufruf). Weiterhin lässt sich mit dieser Methode auch die Lisp-Quelldatei als Drag&Drop in Autocad laden.

 

Mit freundlicher Genehmigung von Rolf Wischnewski. Originalbeitrag im Februar 2006, CADmaro.de

Diese Internetseite ist urheberrechtlich geschützt. Alle Rechte vorbehalten.     © 2024 Markus Hoffmann (─┼──) www.CADmaro.de