利用对话框语言DCL在CAD二次开发中对LSP语言编写的程序进行可视化管理的探讨
利用对话框语言DCL在CAD二次开发中对LSP语言编写的程序进行可视化管理的探讨,管理科学,
姚艳霞 约6233字
摘 要:随着AutoCAD 新版本的不断推出,其用户也越来越多,其用户涉及各行各业,但对AutoCAD 本身而言,它的通用性很强,而专业性并不强,因此对其进行二次开发就非常有必要,而且AutoCAD 也给用户留出了二次开发接口,由于支持AutoLISP、ADS、ARX与脚本编程,用户完全可以按照自己的要求对AutoCAD进行定制,这也就是所说的利用AutoCAD提供的编程接口对其进行二次开发。这也是AutoCAD应用广泛的魅力所在。但是随着程序开发的越来越多,对程序的管理必须提到议事日程。
本文利用对话框语言DCL为例对CAD二次开发中的LSP程序管理的一点探讨。
关键词:AutoCAD AutoLISP DCL语言
一、AutoLSP和DCL语言简介
1.1AUTOLSP简介
LSP(List Processing Language)它产生于50年代后期,是一种资格最老的程序设计语言之一。LSP语言是一种计算机的
处理语言,是在人工智能学科广泛应用的一种程序设计语言。AutoLISP语言是嵌套于AutoCAD内部,将LISP语言和AutoCAD有机结合的产物。使用AutoLISP可直接调用几乎全部AutoCAD命令。AutoLISP语言既具备一般高级的基本结构和功能,又具有一般高级语言所没有的强大的图形处理功能,是当今世界上CAD软件中被广泛采用的语言之一。AutoLISP语言能力虽强,但可视化性能差,在AutoLISP程序中配合对话控制语言(Dialog Contro Language,简称DCL语言),实现了程序的人机互动,使AutoLIS程序的应用更加人性化。
1.2DCL语言简介
对话框是现今最流行的人机互动面接口。AutoCAD从R12起,引入了可编程对话框(Programmable Dialog Box,简称PDB)。PDB的引入是对AutoCAD的一项革新,它改进了图形用户接口(Graohics Users Interface,简称GUI),使用户能够更加容易、直观的进行操作。通过简单的手段,用户便可创建自己的对话框,从而为操作提供了一个友好的图形界面。创建一个对话框至少要两种不同语言来编写两个程序段。一个是DCL语言编写的对话框定义程序;另一个是用AutoLISP语言或ADS语言编写的对话框驱动程序。
二、DCL语言实现管理过程及源程序
用DCL语言编写了对话框程序对自制的lisp程序进行管理, 可通过选择自动加载运行load 并运行对话框驱动程序, 即可进入对话框. 对话框内左边为程序列表, 选[工具管理...]可将自制的lisp程序加入列表,双击列表内程序名即可运行该程序, 程序较多时还可分组存放,在acad命令状态下, "xx"命令可重复上次执行的程序,特点: 使用方便,通常用它装一些不必编入菜单的小程序,非常实用
对话框源程序如下:
//
//
tbox :dialog {
label="LSP程序管理工具箱";
key = "box";
fixed_width = true ;
initial_focus = "listb" ;
: row {
:image_button {key="slide";width=9;aspect_ratio = 0.75 ;
color = dialog_background; fixed_height = true;
fixed_width = true; is_tab_stop = false ; }
: column {
fixed_height = true ;
: text { key = "text1" ; width = 30 ; }
: text { key = "text2" ; width = 30 ; }
: text { key = "text3" ; width = 30 ; }
}
}
: row {
key="buttons";
: boxed_column {
label="LSP程序命令列表:";
: list_box { width = 30 ; height = 15 ; key = "listb" ;
allow_accept = true ;
}
}
: column {
fixed_width = true;
spacer_1 ;
: button { key="tmode";label = "工具管理M..."; mnemonic = "M" ; }
spacer_1 ;
: button { key="readf";label = "读取文件R..."; mnemonic = "R" ; }
: button { key="writf";label = "保存文件W..."; mnemonic = "W" ; }
: spacer { height = 4.5 ; }
: column { fixed_height = true ;
: ok_button { width = 14 ; label = "执行命令N" ; alignment = right ;
mnemonic = "N" ; }
spacer_1 ;
: cancel_button { width = 14 ; alignment = right ; label = "退出界面
E" ;
mnemonic = "E" ; }
spacer_1 ;
spacer_1 ;
//: help_button { width = 14 ; alignment = right ; }
}
}
}
: errtile {width = 30 ;}
}
tmode : dialog {
label = "lsp程序工具管理" ;
: boxed_row {
label = "编辑工具项目:" ;
: list_box { width = 20 ; height = 8 ; key = "listb" ; }
spacer_1 ;
: column {
: edit_box { key = "spec" ; label = "说明S:" ; mnemonic = "S" ; }
: row {
: button { key = "bt-fname" ; label = "程序文件F:" ; mnemonic = "F" ;
fixed_width = true ;}
: edit_box { key = "filename" ; edit_width = 13 ;}
}
: edit_box { key = "fnc-name" ; label = "函数名N:" ; mnemonic = "N" ; }
: row {
: button { key = "mod" ; label = "添加/修改M" ; mnemonic = "M" ; }
: button { key = "del" ; label = "删除D" ; mnemonic = "D" ; }
}
}
}
ok_cancel_err ;
}
用AutoLISP编写的对话框驱动程序,源程序如下:
;;
(defun c:tbox(/dslide tmodedo_okflistdo_readf
do_writf clerrfnamefnmfunfunc
fdataspec rstdcl_id mdo_write
do_read)
(defun do_read(fname / lst fn f1 item ln)
(if (setq fn (findfile fname))
(progn
(setq f1 (open fn "r"))
(while (setq ln (read-line f1))
(if (/= nil (setq item (read ln)))
(setq lst (cons item lst)))
)
(close f1)
));if
(reverse lst)
)
(defun do_write(fname data / lst fn f1 item)
(or (setq fn (findfile fname)) (setq fn fname))
(setq f1 (open fn "w"))
(foreach item data (print item f1))
(close f1)
)
(defun dslide(sldnm)
(start_image "slide")
(slide_image
0
0
(dimx_tile "slide")
(dimy_tile "slide")
sldnm)
(end_image)
)
(defun clerr () (set_tile "error" ""))
(defun tmode(/ rst newdata sub1 do_fname do_mod do_del)
(defun sub1(/ n it)
(clerr)
(setq n(atoi $value)
it (nth n newdata))
(mapcar 'set '(spec fname func) it)
(set_tile "spec" spec)
(set_tile "filename" fname)
(set_tile "fnc-name" func)
)
(defun do_fname(/ f1)
(clerr)
(if (setq f1 (getfiled "选择程序文件"
(get_tile "filename")
"lsp"
8))
(set_tile "filename" f1)
)
)
(defun do_mod(/ it ls)
(clerr)
(setq spec(get_tile "spec")
fname (strcase (get_tile "filename"))
func(get_tile "fnc-name"))
(if (not (wcmatch fname "*.LSP"))
(setq fname (strcat fname ".LSP")))
(cond
((not (and (findfile fname) (load fname))) (set_tile "error" "程序文件无效.")
(mode_tile "filename" 2)
)
((/= (type (eval (read func))) 'list) (set_tile "error" "程序名无效.")
(mode_tile "fnc-name" 2)
)
((= "" spec)
(set_tile "error" "请给出说明文字.")
(mode_tile "spec" 2)
)
(t
(setq it (list spec fname func))
(if (setq ls (assoc spec newdata)) (setq newdata (subst it ls newdata)) (setq newdata (append newdata (list it))) );if
(flist newdata)
)
) ;cond
)
(defun do_del(/ ls n)
(clerr)
(setq n (atoi (get_tile "listb")))
(repeat n
(setq ls(cons (car newdata) ls)
newdata (cdr newdata)))
(setq newdata (append (reverse ls) (cdr newdata)))
(flist newdata)
)
(setq newdata fdata)
(if (not (new_dialog "tmode" dcl_id))
(exit))
(if (setq newdata fdata)
(flist newdata))
(if spec
(set_tile "spec" spec))
(if fname
(set_tile "filename" fname))
(if func
(set_tile "fnc-name" func))
(action_tile "accept" "(done_dialog 1)")
(action_tile "mod" "(do_mod)")
(action_tile "del" "(do_del)")
(action_tile "bt-fname" "(do_fname)")
(action_tile "listb" "(sub1)")
(setq rst (start_dialog))
(if (and (= rst 1) (not (equal newdata fdata)))
(progn
(flist (setq fdata newdata))
(do_write "tbox.dat" fdata)
(set_tile "error" "程序库文件已改写.")
));if
)
(defun flist(lst)
(start_list "listb")
(mapcar 'add_list (mapcar 'car lst))
(end_list)
)
(defun do_ok(/ n)
(setq n (get_tile "listb"))
(if (/= n "")
(progn
(setq n (atoi n)
fun (nth n fdata))
(done_dialog 2)
) ;progn
(progn
(setq fun nil)
(set_tile "error" "没有选择程序.")
)
) ;if
)
(defun do_readf(/ fnm)
(clerr)
(if (setq fnm (getfiled "读取工具箱文件" "" "tbx" 0))
(progn
(flist (setq fdata (do_read fnm)))
(do_write "tbox.dat" fdata)
(set_tile "error" (strcat "载入工具箱文件: \"" fnm "\""))
));if
)
(defun do_writf(/ fnm)
(clerr)
(if (setq fnm (getfiled "写入工具箱文件" "" "tbx" 1))
(progn
(do_write fnm fdata)
(set_tile "error" (strcat "保存工具箱文件: \"" fnm "\""))
));if
)
;main
(setvar "cmdecho" 0)
(setq fdata (do_read "tbox.dat"))
(setq m $tbox_dat)
(setq dcl_id (load_dialog "tbox"))
(if (not (new_dialog "tbox" dcl_id))
(exit))
(set_tile "text1" "程序工具箱 版本号为: 2.00")
(set_tile "text2" " ")
(set_tile "text3" " ")
(if fdata
(flist fdata))
(action_tile "help" "(do_help \"pack\")")
(action_tile "tmode" "(tmode)")
(action_tile "accept" "(do_ok)")
(action_tile "readf" "(do_readf)")
(action_tile "writf" "(do_writf)")
(action_tile "listb" "(setq m $value)")
(set_tile "error" "\"XX\"重复上次命令.")
;;(dslide "flag")
(if m
(set_tile "listb" m))
(setq rst (start_dialog))
(unload_dialog dcl_id)
(if m
(setq $tbox_dat m))
(if (and (= rst 2) fun)
(progn
(setq fnm(cadr fun)
func (read (caddr fun)))
(load fnm)
(setq c:xx (eval func)) ; 定义临时命令
(apply func nil)
));progn
(princ)
)
以上两个程序就能将开发的LISP程序很方便的进行管理,在程序运行过程中,自动形成一个TBOX.DAT数据库文件,来管理LSP程序,数据库文件格式如下:
("程序功能说明" "C:\\程序所在目录\\程序名.LSP" "c:命令
")
………….
("程序功能说明" "C:\\程序所在目录\\程序名.LSP" "c:命令")
通过上述程序非常方便的对所开发的LISP程序进行管理,可大大提高绘图效率。(以上程序在CAD2004以下版本调试通过)
参考文献:
1.《Auto CAD 使用教程》,清华大学出版社。
2.《Auto Lisp&DCL基础篇》,中国铁道出版社。