摘要:本文主要讲述了在AutoCAD中,通过对其进行二次开发而开发出的AutoCAD图形标准图纸图栏系统解决方案。
随着计算机技术的发展,计算机操作系统已经逐渐由DOS系统转向Windows系统,AutoCAD自从12版本开始,已经有Windows的版本,直至14版本以后,已经是完全的Windows版本。AutoCAD除了操作简便之外,它还可以让用户重新定义其界面以及建立自己的程序运行,国内各不同的电脑开发商也通过对AutoCAD的二次开发而开发出应用于不同领域的实用软件。自从AutoCAD R12版开始,AutoCAD引进了对话框技术——DCL对话框语言,它通过与AutoLISP语言相结合,能够编写出界面友好的实用程序。
本人所在公司旧版的图栏填写是基于AutoCAD R10版本而开发出来,操作过程是通过命令行提示,让用户根据提示,逐一输入相应的内容。这种方法程序编写简单,基本的语句如下:
(setq txmc(getstring "图形名称:")) ;提示用户输入图形名称
(command "text" pt txmc) ;填写图形名称到图形中
采用此种方法填写的图栏内容与图形中的其他文字一样,编辑时也是通过文字编辑进行操作,不太方便,在制图的过程中,图栏内容的编辑也占用了很大部分的时间。
一. 总体方案:
图栏分为图样栏、标题栏、明细栏、附加栏、更改表、签名表共六部分,标准图纸的图幅分为A0图、A1图、A2图、A3图、A4图共五种,所以系统应该能生成此五种图幅的图样栏以及相应的标题栏等。由于其他除图样栏外其他图栏内容都是依附于图样栏中,所以在更改图样栏的图幅时,其他图栏的相应位置会随着图样栏的改变而改变。由于该系统必须与旧版系统兼容(本公司的全部图纸都由旧版图栏生成,如果手工修改,所费时间将无可估计),所以进入该系统后,系统必须自动地将旧版的图栏更改为新的图栏格式。 图栏的格式采用在图块中增加属性,通过属性的方法显示图栏的文字内容。而图栏的填写是通过在插入图块的同时输入属性的内容。而图栏的编辑则通过对相应图块的属性进行提取而显示于对话框中让用户进行修改。 图1为图样栏的工作流程图,图2为标题栏的工作流程图。
图 1 图样栏的工作流程图
图 2 标题栏的工作流程图
二. 程序的设计
程序设计的重点主要有以下几个方面:①对话框的设计;②怎样通过对话框的形式编辑图栏内容;③怎样能将旧版的图栏转换为新版的图栏,以省去大量的手工转换工作;④图样栏的大小怎样才能直接地显示在窗口的状态栏中;⑤图样栏中设计单位名称的显示处理;⑥图栏程序的调用。
下面介绍各部分的具体设计。
1. 对话框的设计:
AutoCAD软件包从AutoCAD R12以来最大的进步之一是它提供的新的可编程对话框(PDB)工具,使用DCL对话框语言再配以AutoLISP语言,就可以设计出与AutoCAD软件包风格完全一致的应用程序。
通过DCL对话框语言,对图栏的各对话框进行设计,在设计过程中,主要是考虑对话框界面的协调性及各控件安排的合理性。在图样栏的对话框中,使用选项按钮(radi0_button)选择标准图纸的图幅大小,使用弹出列表框(popup_list)列出预置的设计单位名称,而使用编辑框(edit_box)填写在单位列表框中没有列出的单位名称。
在标题栏中,使用编辑框填写名称、图号、材料、比例、重量、总页数、页码等,而使用选项按钮选择阶段标记。
各种图栏的外观见图3所示。
图3 各种图栏的外观
全部的图栏对话框都分为填写功能和编辑功能两种,由于对话框语言有类似于“类”的具有继承性的功能,通过将对话框的内容部分使用一个名称保存,然后在另外的对话框内引用保存过的对话框内容,这样就可以使用不同的标题显示同样外观的对话框内容(如“填写图样栏”和“编辑图样栏”)。
另外,由于图样栏已经定义了图纸图幅的大小,所以标题栏等其他图栏也就不必提示用户选择图幅而自动找到填写的位置。所以在对话框中除图样栏外,其他图栏的对话框都不必出现“图纸大小”的选项按钮。
以下列出图样栏对话框的程序内容:
//填写图样栏部分
ddtyl:dialog{
label="填写图样栏";
drtyl;
}
//编辑图样栏部分
dmtyl:dialog{
label="编辑图样栏";
drtyl;
}
//图样栏内容部分
drtyl:column{
boxed_size;
:boxed_column{
:popup_list{
label="设计单位(&S):";
key="sign_ro"; }
:edit_box{
label="其他设计单位(&O):";
key="other";
edit_width = 20;
allow_accept=true;
}
}
ok_cancel;
}
//图纸大小内容部分
boxed_size:boxed_radio_row{
label="图纸大小";
:radio_button{
label="A&0";
key="size_0";
}
:radio_button{
label="A&1";
key="size_1";
}
:radio_button{
label="A&2";
key="size_2";
}
:radio_button{
label="A&3";
key="size_3";
}
:radio_button{
label="A&4";
key="size_4";
}
}
设计了对话框以后,还必须通过AutoLISP语言来调用及驱动对话框。在显示图栏对话框前,必须初始化对话框中各项的值,对于没有相应内容的项目,使用默认值。而对于具有相关内容的项目,则显示其内容供用户修改。
通过对话框,使用图栏的修改更为直观方便,操作也更为简单。
2. 图栏内容的编辑设计:
旧版的图栏只有填写功能,无自动编辑功能,只能通过文本编辑功能对内容逐一进行编辑,而且对于图样栏的大小无法编辑,只能删除旧图样栏再插入新图样栏,并且更换图样栏后标题栏等内容的位置无法与新图样栏对齐,只能靠手工进行调整。这些问题必须在程序中进行完善。
为了方便各种图栏的移动及图栏内容的提取,使用图块的属性保存各种图栏的内容。填写图栏时,是在插入图块的同时将图栏的文字内容作为图块的属性内容插入图形中,编辑图栏时,首先将相应图栏的图块的属性通过属性的提取而取出,并提供用户作修改,并将修改后的内容通过图块的属性更新而重新显示于图形中。图栏内容的移动就是图块的移动。
对于图样栏,不同的图样栏的大小采用不同名称的图块,在修改图样栏大小时,采用的是通过程序的控制,首先取出图块中设计单位的名称,并显示于对话框中,然后删除该图块,然后再插入新的图块,并将设计单位的属性附于图块上,同时,程序控制移动标题栏、附加栏、签名表等图栏到新的图样栏的相应位置上。这样实现了图样栏中图纸大小的编辑修改。
以下为图样栏编辑的程序设计内容,从中可以看到图样栏是怎样编辑的:
(defun ty_modi()
(setq head(entget(setq head_t(ssname sel_bt 0))))
;取得图样栏图块的头部,其中sel_bt为图样栏图块
(setq he_zzdw(entget(entnext(cdr(car head)))))
;取得设计单位属性文本
(setq zzdw(getent he_zzdw1))
;取得设计单位文本内容,getent为自定义函数
………… ;调用对话框并初始化、显示
(if (= aaa (getvar "useri1");判断图幅是否改变
(progn ;如果没有改变
(setent zzdw he_zzdw 1) ;改变图块中设计单位
(entupd head_t) ;更新图块
)
(progn ;如果图幅改变了
(entdel head_t) ;删除原图样栏
(command "purge" "b" tkn "n") ;清理相应的图块
(setq tkn(strcat "B-GBA" (itoa aaa) "TY"))
;组合出图样图块的名称
(command "insert" tkn "non" "0,0" "" "" "" zzdw)
;插入附有属性的图样图块
(modi_ipt "B-BTL" p2p p2)
………… ;移动标题栏等到新的图样栏的相应位置
)
)
)
3. 旧版图栏的转换:
程序只有保持向下的兼容性才能得以广泛的使用,对于图栏的填写程序,也应该保证能够很好地兼容旧版的图栏,并能顺利地将旧版的图栏转换为新的图栏。
对于标题栏的转换,只需取得相应位置上的标题栏的内容,然后将原来的标题栏内容删除,再插入附有各属性内容的标题栏图块。
对于图样栏,除删除旧的图样栏图块,还必须将该图块通过清理命令将其清理掉,然后再插入新的格式的图样栏,通过这样就可以将图栏进行转换。
图样栏转换的程序如下:
(setq head(entget(setq head_t (ssname sel_bt 0)))) ;取得图块头部
( if (<(getent head 66)1) ;查看图块是否为旧版图块
(progn ;旧版图样栏时
(princ "\n此图样栏为旧版本,将被更新为新版本。\n")
(setq zzdw(get_text "c" (list(+ b_x -1)(+ b_y 55))
(list(+ b_x -49)(+ b_y 39))))
;从旧图样栏中取得设计单位名称
(if (not zzdw)
(setq zzdw "") ;如无单位名称,则为空字串
)
(entdel gead_t) ;删除旧图样栏
(command "purge" "b" gead_na "n") ;清理旧图块
(command "insert" head_na "non" "0,0" "" "" "" zzdw);插入新版图样栏
)
)
4. 状态栏中显示图样栏的图幅大小:
由于计算机显示的图形可以放大缩小,所以有些图幅容易造成混淆,如A2图和A3图幅,所以必须在一个显著的位置显示图幅的大小,使用户一目了然。
虽然通过调用图样栏(ddtyl)命令可以从对话框中显示当前的图幅大小,但这仲方法必须通过手工的操作才能实现。
如果将图幅的大小通过文本显示于图形中,就会使打印时将该文本也打印出来,同时该文本也只能通过缩放命令才能看到,操作上也不方便。
通过比较,将图样栏的图幅大小显示于状态栏是取为直接的。
AutoCAD的状态栏显示于屏幕的下端,其中显示了当前坐标以及各种辅助工具的状态(如捕捉、正交、栅格、对象捕捉等)。同时由AutoCAD提供的系统变量MODEMACRO可以在状态栏中显示自定义内容,控制着用户定义的状态栏。MODEMACRO变量的值不保存在图形文件中,也不保存在配置文件或其它文件中,所以设置该值只能在ACAD.LSP文件中用S::STARTUP函数加载。
由于图幅的大小只是使用不同名称的图块(有一定规律的名称),所以让系统变量MODEMACRO取得图样栏图块名称并提取图块大小是一个复杂过程,而且在每次的更换图幅大小时,都应重新初始化MODEMACRO的值,这种方法是比较繁杂的。如果让MODEMACRO显示系统就是的值,那么在系统变量的值改变时,MODEMACRO则会自动刷新其值,而不必重新初始化。
在AutoCAD中,系统提供了多个可让用户定义值的变量(如useri1~useri5、users1~users5等),这些自定义的系统变量是保存在图形中,这样就可以利用这些系统变量保存图样栏的图幅大小,只是在更改图样栏的图幅大小的同时将自定义的系统变量设置为相应的图幅的值。在图样栏中,使用的是自定义系统变量useri1。
MODEMACRO系统变量的内容使用的是DIESEL语言。具体的程序内容如下:
(defun S::STARTUP()
(setvar "modemacro" "A $(getvar, useri1)图")
(princ)
)
这样就可以在状态栏的起始处显示“A0图”的字样,提示图幅大小。
5. 图样栏中设计单位名称列表的设计:
在图样栏中,必须指定设计单位,如果所设计的程序只供单一的单位使用,则可以将设计单位名称直接保存在图样图块中,但在程序设计过程中,为了能使该系统能应用于多个部门,甚至在设计过程中还未知的其他单位,必须采用一种特殊的方法取得设计单位的列表,以便在不必修改程序内容的情况下在多个部门及单位中应用。
在程序中,采用的是将设计单位的列表保存为tyl.ini文件,该文件为文本文件,可以通过记事本等打开进行编辑,文件中每个单位名称为一行。在程序运行过程中将tyl.ini文件中的各个单位名称显示于列表中供用户选择。由于AutoCAD的DCL对话框语言的功能不强(不如VB的对话框那样方便),在显示列表及填入图形中都必须分别对tyl.ini文件的内容进行引用。对话框在取得列表时不是取得列表中的内容。而是取得选择项在列表中的位置序号。这样,只能通过该序号重新搜索tyl.ini文件以取得相应序号的单位名称:
;;显示于列表中
(setq des_list (read_des(findfile "tyl.ini")))
(start_list "sign_ro")
(mapcar ’add_list des_list)
(add_list "其他设计单位...")
(end_list)
;;通过序号查找单位名称
(if (= des_num (read_num (findfile "tyl.ini")))
(setq zzdw zzdw1)
(setq zzdw (desi_nam des_num))
)
程序中,read_des()、read_num()、desi_nam()为自定义函数,功能如下:
read_des():将指定的文件中每行文字的内容读出并保存于指定的变量中。
Read_num():返回指定文件的行数(由为设计单位列表的数量)。
Desi_nam():通过位置序号返回tyl.ini文件中相应序号的单位名称。
本系统除了提供预置的列表框外,还提供一项“其他设计单位”以提供一些临时的设计单位填写,这样可在不修改tyl.ini文件的条件下填写临时的设计单位。在选择了列表中的最后一项“其他设计单位”时,对话框将提供一个文本编辑框供用户输入单位的名称。程序如下:
(if (= des_num(read_num(findfile "tyl.ini"))) ;判断是否选择了“其他设计单位”
(progn ;如果选择了其他设计单位
(mode_tile "other" 0) ;使“其他设计单位”框有效
(mode_tile "other" 2) ;将光标移动到"其他设计单位”框上
)
;如果选择的不是其他设计单位
(mode_tile "other" 1) ;使“其他设计单位”框无效
)
由于tyl.ini文件的设计单位的各个不同单位名称的排列有先后之分,在列表框的初始化中,系统总是默认第一个单位名称为设计单位,这样就必须通过程序及其他方法将设计单位定位在自己常用的单位名称上,或者说希望系统能够将前一次所填写的设计单位作为下次填写的默认值。
在AutoCAD r13以后的版本中,用户可将自定义的参数保存于AutoCAD的系统配置文件中的AppData段中,以配置自己的界面的自定义参数。所以可以将前一次设计单位名称列表选择项的位置序号以及其他设计单位编辑框中的内容保存于该段中,以便在下次引用图样栏时对图样栏进行初始化。具体程序如下:
;;取得设计单位前次选择的位置序号。
(if (getcfg "AppData/Tyl/Number")
(setq des_num(atoi(getcfg"AppData/Tyl/Number")))
(setq des_num 0)
)
(set_tile "sign_no" (itoa des_num))
;;取得其他单位的名称
(if (setq zzdw1 (getcfg "AppData/Tyl/Other"))
(setq_tile "other" zzdw1)
)
;;保存设计单位序号及其他单位名称
(setcfg "AppData/Tyl/Number" (itoa des_num))
(if zzdw1
(setcfg "AppData/Tyl/Other" zzdw1)
)
这样就可以不必考虑设计单位列表的排列问题,甚至对于设计单位不在列表中而使用其他框进行填写也不必每一次填写图样栏时都进行输入,系统可以取得上次保存的其他单位名称显示于其他框中。
对于设计单位名称列表的tyl.ini文件,在本系统中是通过在该系统的安装程序中生成。本系统设计完成后使用了InstallShield生成安装程序,所以可以通过安装程序的专用语言生成tyl.ini文件。在InstallShield生成的安装程序中有要求用户输入姓名及工作单位的向导对话框,如图5,这样就可以通过取得用户输入的工作单位并生成tyl.ini文件。该系统在不同的单位使用时,由于在安装时所输入的单位名称为本单位名称,所以在填写图样栏时就能产生本单位名称的图样栏。
其程序如下(程序内容置于ProcessAfterDataMove()过程中):
szFileName = @FILE_TYL; if( FindFile ( TARGETDIR , szFileName , svResult )< 0 ) then
SdShowMsg( @MSG_CREATE_TYL , TRUE);
Delay(2);
if (CreateFile ( nvFileHandle , TARGETDIR , szFileName )<0) then
MessageBox(@MSG_UNCREATE_TYL,INFORMATION);
if(CopyFile(szFileName, szFileName)<0) then
MessageBox(@MSG_UNCOPY_TYL,INFORMATION);
endif;
else
if ( WriteLine ( nvFileHandle , svCompany)<0) then
MessageBox(@MSG_WRITE_COMPANY,INFORMATION);
else
WriteLine(nvFileHandle,@COMPANY_NAME);
endif;
endif;
endif;
return 0;
end;
6. 图栏各命令的调用:
各程序设计完成后,要实现对程序的调用才能方便程序的使用。各图栏的AutoLISP程序保存于同一文件的不同过程中,该文件为ddtl.lsp,而对话框文件为ddtl.dcl,设计单位配置文件tyl.ini,同时还有应用于图栏的多个带属性的图块。
首先为了能够在命令引用时自动装载该程序文件,必须在acadr14.lsp文件中增加下列一行程序:
(autoload "ddtl" ’("ddtyl" "ddbtl" "ddmxl" "ddfjl" "ddqmb" "ddggb"))
这样,就可以随时在命令行中输入图栏命令以运行相应程序过程。
其次,必须将图栏的名命令显示在菜单及工具栏中供用户调用。AutoCAD允许用户加载多个菜单,除主菜单外,还可以加载多个附加菜单,附加的菜单文件可以包含下拉菜单及工具栏,但不能包含屏幕菜单。本系统将产生一附加的菜单文件显示图栏的各命令。
菜单的内容如下:(菜单文件名称为ac_bonus.mnu)
***MENUGROUP=AC_BONUS***POP1 [附加(&B)]
ID_H10TL [->图栏(&T)]
ID_H10TYL [图样栏(&T)] ^C^Cddtyl
ID_H10BTL [标题栏(&A)]^C^Cddbtl
ID_H10FJL [附加栏(&F)]^C^Cddfjl
ID_H10MXL [明细栏(&M)]^C^Cddmxl
ID_H10QMB [签名表(&O)]^C^Cddqmb
ID_H10GGB [<-更改表(&G)]^C^Cddggb
……
***TOOLBARS**TB_H10_TL_TOOLBAR
ID_H10TL [_Toolbar("图栏及流程", _Floating, _show,101,121,1)]
ID_H10TYL [_Button("图样栏", ICON_16_TYL,ICON_24_TYL)]^C^Cddtyl
ID_H10BTL [_Button("标题栏", ICON_16_BTL,ICON_24_BTL)]^C^Cddbtl
ID_H10FJL [_Button("附加栏", ICON_16_FJL,ICON_24_FJL)]^C^Cddfjl
ID_H10MXL [_Button("明细栏", ICON_16_MXL,ICON_24_MXL)]^C^Cddmxl
ID_H10QMB [_Button("签名栏", ICON_16_QMB,ICON_24_QMB)]^C^Cddqmb
ID_H10GGB [_Button("更改栏", ICON_16_GGB,ICON_24_GGB)]^C^Cddggb
工具栏的按钮图标,是通过使用VC++软件产生的资源文件提供,该文件名称为ac_bonus.dll(文件名称与菜单相同,扩展名为.dll),包括菜单文件中所引用的全部图标。
三、使用情况及效果:
整个程序设计完成后在多个单位使用,运行情况良好,对于旧版的图栏都能顺利地转换,采用对话框的方式非常直观,对各图栏的修改非常方便,大大地提高设计的速度。由于采用专门的安装程序安装该系统,所以可以在安装向导的指导下完成系统的安装,安装后系统不必再经调整就可以进行使用,而不必专人的指导,大大地方便了该系统的使用。
该系统已经被多个单位使用及推广,同时由该系统及相应的其他功能所组成的应用程序也已被众多的单位和个人所使用。
|