本帖最后由 林霄云 于 2019-8-3 11:25 编辑
对话框实战之图层综合功能源码解析——(三)控制图层状态
接前文,对话框实战之图层综合功能源码解析——(二)显示图层信息
http://bbs.mjtd.com/forum.php?mo ... 988&fromuid=7303580
一、显示及控制图层状态及dcl文件
界面如下
状态显示的控件是text,并用button控件进行控制。
- :column {
- :boxed_column {
- label = "状态" ;
- width = 8 ;
- :text {
- key = "lay-state" ;
- value = "打开" ;
- }
- spacer;
- :button {
- key = "lay-onoff" ;
- label = "开|关(&O)" ;
- }
- :button {
- key = "lay-lock" ;
- label = "锁|解(&L)" ;
- }
- :button {
- key = "lay-frozon" ;
- label = "冻|解(&R)" ;
- }
- :button {
- key = "lay-clayer" ;
- label = "置前层(&V)" ;
- }
- }
- }
二、控件值的读取和设置
(一)text控件值的set
如前文所述,图层状态亦封装在图层信息的函数里,完整的(showlayinfo)函数如下:
- (defun showlayinfo( / layname ent temp strtemp )
- (setq layname (nth (atoi (get_tile "lay-name")) hnu:layname-list-c))
- (setq ent (entget(tblobjname "LAYER" layname)))
- ;
- (setq temp (cdr(assoc 62 ent)))
- (if (< temp 0) (setq strtemp "关闭") (setq strtemp "打开"))
- (set_tile "lay-color" (itoa (abs(cdr(assoc 62 ent)))))
- ;(set_tile "lay-color-choose" (itoa (cdr(assoc 62 ent))))
- (set_tile "lay-linet" (cdr(assoc 6 ent )))
- (set_tile "lay-linew" (itoa (cdr(assoc 370 ent))))
- (set_tile "lay-print" (nth (cdr(assoc 290 ent)) hnu:layprint-list))
- (setq temp (cdr(assoc 70 ent)))
- (if
- (= (boole 1 temp 1) 1) (setq strtemp (strcat strtemp "&冻结")))
- (if
- (= (boole 1 temp 2) 2) (setq strtemp (strcat strtemp "&视口冻结")))
- (if
- (= (boole 1 temp 4) 4) (setq strtemp (strcat strtemp "&锁定")))
- (set_tile "lay-state" strtemp)
- )
注意到,"打开和关闭"和"锁定冻结"由不同的组码控制。用boole函数取特定位的值,是用"and"操作。冻结、锁定相互独立,用if语句并列。其他事项详见前文所述。
(二)button控件的使用
button控件略微不同的是,它无需set、get操作,只需要利用action_tile命令设定回调函数(或语句)。鉴于锁定、冻结操作过程类似,设置一个处理函数(modifystate i),通过传递不同参数i进行处理。
- ;处理状态
- (action_tile "lay-onoff" "(modifystate 1)")
- (action_tile "lay-lock" "(modifystate 2)")
- (action_tile "lay-frozon" "(modifystate 3)")
- (action_tile "lay-clayer" "(modifystate 4)")
如前文所述,此段代码是初始化,在对话框流程load——>new——>start——>done——>unload 中应在new之后,start之前。
其中处理函数(modifystate i) 如下:
- (defun modifystate( n / temp layname en)
- (setq layname (nth (atoi (get_tile "lay-name")) hnu:layname-list-c))
- (setq en (tblobjname "LAYER" layname))
- (cond
- ((= n 1) (set-dxf en 62 (- (get-dxf 62 en))) (showlayinfo) )
- ((= n 2) (set-dxf en 70 (xor_i (get-dxf 70 en) 4 )) (showlayinfo) ) ;锁定
- ((= n 3) (set-dxf en 70 (xor_i (get-dxf 70 en) 1 )) (showlayinfo) ) ;冻结
- ((= n 4) (set-dxf en 70 0)(setvar 'clayer layname))
- );cond
- )
layname即图层名,如前文所述,实时获取。图层状态改变后应更新图层信息,即调用(showlayinfo)。根据操作习惯,置当前层操作,先取消图层的冻结和锁定。
上述定义一个xor_i函数,进行特定位的0<-->1的反转操作。定义如下:
- (defun xor_i(num i)
- ;指定位,进行xor操作。i的取值限于1 2 4 8 等,否则结果不可靠。
- ;取指定位的值,如果是1,则减之,是0,则加之。
- (if (= (boole 1 num i) i)
- (- num i) (+ num i))
- )
注意到,图层状态控制的button,并不调用done_dialog。即对话框将一直显示。
三、对话框的退出
不断强调对话框的流程load——>new——>start——>done——>unload
定义一个退出按钮,设置它的回调动作为done_dialog,即可。
- (action_tile "cancel" "(done_dialog 0)" )
注意,此条仍为初始化语句,设置在start之前。这是对话框编程的最大的特点,执行过程不受语句顺序的影响(也是回调的意义所在)。
其dcl文件如下:
- :button {
- alignment = centered ;
- fixed_width = true ;
- is_cancel = true ;
- key = "cancel" ;
- label = "退出(&E)" ;
- }
label上的&E是定义一个对话框热键。方便左手操作。
|