对lisp程序来说,对话框的设计是一件痛苦的事情,也是一件有意义的事情。为交流经验下面我来和大家一起探讨这里面的技术问题。
一 首先简单介绍一下对话框的设计流程:
…… ;程序开始 (setq ok 2) ;初始化对话框的确定数值(不一定要)
(setq ID (load_dialog "***.dcl"));加载对话框文件,ID为对话框的标志号
(if (> ID 0) ;标志号如果大于0,则加载对话框成功
(if (new_dialog "***" ID) ;如果显示对话框成功
(progn
(……) ;初始化控件
(while (> ok 1) ;直到用户离开对话框
(setq ok (start_dialog)) ;激活对话框
…… ;用户操纵对话框
(cond ;这一段不一定都要
( (= ok 2 之类)
(……) ;执行OK动作
)
)
)
(……) ;离开对话框后的程序
)
(alert “对话框错误!”) ;显示出错信息
)
(alert “对话框加载错误!”) ;显示加载失败信息
)
(unload_dialog ID) ;卸载对话框
;(一定要,我曾经没这一句吃过大亏)
…… ;程序结束
二 对话框的布局和美观设计
一个好看的对话框,能给别人留下好的印象。因而在布局时候,不要弄得参差不齐,最好整齐一致,各组件和文字不要显得太挤太密和太空,疏密要恰当。
因而很有必要用 width,fixed_width,alignment,spacer,spacer_0之类的语句或控件来使之漂亮。
三 对话框的初始化和列表的处理
在初始化中,一般来说:
用(action_tile key action_expression) 来处理各控件的相应动作.
用(mode_tile key mode)来处理控件的状态(可用,禁用,聚焦,等)
用(get_attr key attribute)来沪的控件相应属性的值。
用(get_tile key) 来获得控件的值。
用(set_tile key value)来设定控件的值。
用(dimX_tile key) ,(dimY_tile key)来获得控件的高宽或像素。
对于列表(popup_list ,list_box)的处理可以有两种方式赋予初始值:
一种在DCL中直接写入,另外就是在lisp程序中设置。为了正确显示或取得各列表的值,一般来说要定义字符串和列表相互转化的函数,大家可以参考我的程序。
四 如何调用已有CAD的对话框控件并获得其返回值
alert ,help ,getfiled ,acad_colordlg,acad_truecolordlg (R2004以上)
有的对话框有返回值,像颜色,文件对话框。颜色对话框的返回值为颜色号,若采用真彩色,(acad_truecolordlg 0) 则返回值一般如下:
((62 . 75) (420 . 7510105)),第一个表为62 . 75 指的是62 颜色 75,颜色索引号,420,真彩色,7510105真彩色颜色数值可以直接传给图元表。
getfiled,返回值为文件路径,具体用法请参考相关资料。
五 隐藏、恢复对话框及嵌套的处理。
有时候需要交互操作,暂时离开对话框时,这时候的处理办法要先将对话框隐藏,待交互操作结束后,恢复对话框。
例如这样的一个流程:
(while (> ok 1) ;直到用户按下OK键
…… ;初始化对话框
(action_tile “pick” “(done_dialog 2)”) ;需要在图面上点取
(setq ok (start_dialog)) ;激活对话框
(cond
((= ok 2)
(pick) ;点取动作
(new_dialog "***" ID) ;新对话框
(……) ;初始化等
)
)
)
关于嵌套对话框的设计和处理:
对话框文件可包含父对话框,子对话框。在父对话框中增加一个子对话框按钮,初始化子对话框函数中应包含new_dialog,start_dialog。其他处理跟上面的处理有些类似。
六 对话框中参数值得默认、保存和恢复
默认的处理: 在开始时对各控件赋值,或者定义这样的一个按钮和函数。
保存参数值,一般来说有几种方式:
1、设置全局变量。但这样只对这次CAD有效,下次打开CAD就不行了。
2、保存到用户变量中。CAD中有15个用户变量,可供自己定义。
3、保存到数据文件,下次调用这个数据文件。
4、保存到注册表中。
我这个lisp中就采用了两种方法结合,即用注册表记录其保存的数据文件路径。然后下次调用时就打开那个数据文件。当然还有其他方式。大家不妨探讨一下。
恢复参数值:就是把各控件保存的值调出来后用set_tile函数赋分别给它。
七 图像组件的预览和放大和缩小技术
首先用dimX_tile,dimY_tile获得图像组件像素的高宽。
然后(start_image key)开始图像处理。
用(vector_image x1 y1 x2 y2 color)来画线
用(fill_image x1 y1 x2 y2 color)来填充或画点。
用(slide_image x1 y1 x2 y2 slideName)来显示幻灯片。 用(end_image)结束图像控件的处理。
预览技术是建立在对图像控件的坐标系统和CAD坐标系统的转换上的。弄清楚了它们的转换关系,那么,就能写出预览函数了。
坐标的处理上,要注意的是图像的原点是左上角,而不是左下角。因而对于函数的某个区域(X1,Y1),(X2,Y2)要映射到图像组件的坐标系统中去,这样的话,放大和缩小函数的处理就比较好办了。
各位如果有兴趣的话,不妨看看我下面程序的处理,这个对话框是为分形而设计的。为了展示分形的自相似,和一个参数的微小变换,就可以引起图像的很大变化(混沌系统的一个特征),因而有必要采取无级放大。
如果在图像按钮上点击一下,再点击一下,得到放大区域(红色矩形线框),对这个区域预览,就可以细看其局部。你甚至可以对它放大再放大,直到它们的上下界限相等(达到lisp的精确极限1e-16),你会发现,放大之后好像图像没什么变化,还是那个形状—这正是分形的自相似特征。
只可惜lisp程序对图像处理速度不快,而且又受本身速度的限制,使得这个预览打了一个很大的折扣。各位要用的话最好把这个程序几个文件编译成.vlx文件,速度会提高不少。
匆匆写来,有很多错误,请大家批评指教。
下面为源程序: |