明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4373|回复: 17

[函数] 最近写的一个dcl驱动函数库,求批评

[复制链接]
发表于 2015-10-31 10:33:41 | 显示全部楼层 |阅读模式

不多说直接上代码,希望各位给予指点。。
  1. ;dcl初始化
  2. ;dlgname :用于指定对话框的字符串
  3. ;dcl_str:dcl字符串
  4. (defun vic-dcl-Init (dlgname dcl_str / #dcl_f #dcl_file #dcl_id)
  5.   (setq #dcl_file (vl-filename-mktemp "DclTemp.dcl"))
  6.   (setq #dcl_f (open #dcl_file "w"))
  7.   (write-line (strcat dlgname ":dialog{\n" dcl_str "\n}") #dcl_f)
  8.   (close #dcl_f)
  9.   ;================结束file,载入file
  10.   (setq #dcl_id (load_dialog #dcl_file))
  11. )
  12. ;循环显示对话框启动函数
  13. ;dlgname :用于指定对话框的字符串。
  14. ;dcl_id :由 load_dialog 获得的 DCL 文件标识符。
  15. ;actionlst :设定控件动作函数列表
  16. ;applist :控件回调函数列表
  17. (defun vic-dcl-startloop (dcl_id dlgname actionlst applist / what_next)
  18.   (setq what_next 2)
  19.   (while (>= what_next 2)                    ;Begin display loop.
  20.     (if (null (new_dialog dlgname dcl_id)) ;Initialize dialog
  21.       (exit) ;box, exit if nil
  22.     ); endif ;returned.
  23.     (mapcar 'eval actionlst)
  24.     (setq what_next (start_dialog))          ;Display dialog box.
  25.     (eval (cdr (assoc what_next applist)))
  26.   )
  27. )
  28. ;只显示一次对话框启动函数
  29. ;dlgname :用于指定对话框的字符串。
  30. ;dcl_id :由 load_dialog 获得的 DCL 文件标识符。
  31. ;actionlst :设定控件动作函数列表
  32. ;applist :控件回调函数列表
  33. (defun vic-dcl-startonce (dcl_id dlgname actionlst applist / what_next)
  34.   (if (null (new_dialog dlgname dcl_id)) ;Initialize dialog
  35.     (exit) ;box, exit if nil
  36.   ); endif ;returned.
  37.   (mapcar 'eval actionlst)
  38.   (setq what_next (start_dialog))          ;Display dialog box.
  39.   (eval (cdr (assoc what_next applist)))
  40. )
  41. ;dcl结束
  42. (defun vic-dcl-End (dcl_id)
  43.   (unload_dialog dcl_id)
  44.   (princ)
  45. )
  46. ;设置dcl参数
  47. ;lst :key value 键值对表
  48. (defun vic-dcl-setvalues (lst)
  49.   (mapcar 'set_tile (mapcar 'vl-princ-to-string (mapcar 'car lst)) (mapcar 'vl-princ-to-string (mapcar 'cdr lst)))
  50. )
  51. ;设置dcl对象显示模式
  52. ;lst :key mode 键值对表
  53. ;Value    Description
  54. ;0---      可用
  55. ;1---      不可用
  56. ;2---      设置焦点
  57. ;3---      选择编辑框内容
  58. ;4---      高亮image_button开关
  59. (defun vic-dcl-setmodes (lst)
  60.   (mapcar 'mode_tile (mapcar 'vl-princ-to-string (mapcar 'car lst)) (mapcar 'cdr lst))
  61. )
  62. ;获取dcl对象属性
  63. ;lst: key列表或字符串
  64. (defun vic-dcl-getvalues (lst)
  65.   (cond
  66.     ((listp lst)(mapcar 'get_tile lst))
  67.     ((= (type lst) 'str) (get_tile lst))
  68.     (t nil)
  69.   )
  70. )
  71. ;获取dcl对象属性
  72. ;lst: key/attr点对表
  73. (defun vic-dcl-getattrs (lst)
  74.   (mapcar 'get_attr (mapcar 'vl-princ-to-string (mapcar 'car lst)) (mapcar 'vl-princ-to-string (mapcar 'cdr lst)))
  75. )
  76. ;设置dcl对象动作
  77. ;key: 对象键值
  78. ;func-args:调用函数 参数表
  79. ;示例:
  80. ;("buttonkey" (func args) (func1 arg1 arg2))
  81. (defun vic-dcl-setaction (key-func-args / strr)
  82.   (action_tile
  83.     (car key-func-args)
  84.     (substr
  85.       (setq strr
  86.         (vl-princ-to-string
  87.           (mapcar '(lambda (x)
  88.                      (cons (car x)
  89.                        (mapcar '(lambda (y) (vl-prin1-to-string y)) (cdr x))
  90.                      )
  91.                    )
  92.             (cdr key-func-args)
  93.           )
  94.         ))
  95.       2 (- (strlen strr) 2)))
  96. )
  97. ;定义布局函数
  98. ;layoutname:容器名称 - row column等
  99. ; layoutlst:容器属性点对表
  100. ; lst:控件列表
  101. (defun vic-dcl-setLayout (layoutname layoutlst lst)
  102.   (strcat ":" layoutname  "{\n"
  103.     (if (and (listp layoutlst) (>= (length layoutlst) 1))
  104.       (strcat
  105.         (vic-lst->str
  106.           (vic-dcl-listsplit layoutlst)
  107.           ";\n"
  108.         )
  109.         ";\n")
  110.       ""
  111.     )
  112.     (vic-lst->str lst "\n")
  113.     "\n}")
  114. )
  115. ;|定义一个控件
  116. ;itemname 控件名称
  117. lst:定义控件属性的点对表
  118. 示例:
  119. (vic-dcl-addItem "button"
  120. '((key . "hah")
  121. (label . "hello")
  122. (width . 2)
  123. (action . "(hh)")
  124. ))|;
  125. (defun vic-dcl-addItem (itemname lst)
  126.   (if (and (listp lst) (>= (length lst) 1))
  127.     (strcat
  128.       ":" itemname "{\n"
  129.       (vic-lst->str
  130.         (vic-dcl-listsplit lst)
  131.         ";\n")
  132.       ";\n}"
  133.     )
  134.   )
  135. )
  136. ;工具函数
  137. (defun vic-dcl-listsplit (lst)
  138.   (mapcar
  139.     '(lambda (x / first)
  140.        (vic-lst->str
  141.          (mapcar '(lambda (x) (strcase x t)) (mapcar 'vl-prin1-to-string (list (car x) (cdr x))))
  142.          " = ")
  143.      )
  144.     lst)
  145. )
  146. ;;;=====================================
  147. ;;;函数:lst->str
  148. ;;;列表转成字符串
  149. ;;;参数:lst:要转换的列表
  150. ;;;del:分隔符
  151. ;;;=====================================
  152. (defun vic-lst->str  (lst del)
  153.   (if  (cdr lst)
  154.     (strcat (car lst) del (vic-lst->str (cdr lst) del))
  155.     (car lst)
  156.   )
  157. )
  158. ;添加列表数据
  159. ;key:列表框key
  160. ;lst:数据列表
  161. ;operation:
  162. ;整数,指定要执行的列表操作的类型。可以指定下列值之一:
  163. ;1 修改选定列表的内容
  164. ;2 附加新的列表项
  165. ;3 删除旧列表,创建新列表(缺省设置)
  166. ;index:
  167. ;整数,指定后续 add_list 调用要修改的列表项。列表中的第一项序号为 0。如果未指定该参数,则 index 的缺省值为 0。
  168. ;如果 start_list 不执行修改操作,则忽略 index 参数。
  169. ;operation index 如果不指定则为 nil
  170. (defun vic-dcl-addlist (key lst operation index)
  171.   (cond
  172.     ((and (null operation) (null index))
  173.       (start_list key)
  174.     )
  175.     ((and (null index) operation)
  176.       (start_list key operation)
  177.     )
  178.     (t (start_list key operation index))
  179.   )
  180.   (mapcar 'add_list (mapcar 'vl-princ-to-string lst))
  181.   (end_list)
  182. )
  183. ;刷新数据 by fsxm
  184. ;(defun dcl:list-set (key lst / change sym sym_fun update)
  185. ;  (or (listp lst) (setq lst nil))
  186. ;  (setq sym_fun (read (strcat key ":list_box_fun")))
  187. ;  (or (eval sym_fun) (set sym_fun 'vl-princ-to-string))
  188. ;  (setq sym (read (strcat key ":list_box_data")))
  189. ;  (set sym lst)
  190. ;  (start_list key)
  191. ;  (mapcar 'add_list (mapcar (eval sym_fun) lst))
  192. ;  (end_list)
  193. ;  lst
  194. ;)
  195. ;取表 by fsxm
  196. ;(defun dcl:list-get (key)
  197. ;  (eval (read (strcat key ":list_box_data")))
  198. ;)
  199. ;取当前项 by fsxm
  200. ;(defun dcl:list-getv (key / index a data)
  201. ;  (cond  ((/= (setq index (get_tile key)) "")
  202. ;          (setq data (dcl:list-get key))
  203. ;          (mapcar (function (lambda (a) (nth a data)))
  204. ;            (read (strcat "(" index ")"))
  205. ;          )
  206. ;        )
  207. ;  )
  208. ;)
  209. ;设转换函数 by fsxm
  210. ;(defun dcl:list-setf (key sym_fun / sym)
  211. ;  (setq sym (read (strcat key ":list_box_fun")))
  212. ;  (set sym sym_fun)
  213. ;)

  214. ;;加载幻灯片 by fsxm
  215. ;key 图像或图像按钮key
  216. ;sld 幻灯片或颜色代码
  217. (defun vic-dcl-loadsld (key sld / x y)
  218.   (setq x (dimx_tile key))
  219.   (setq y (dimy_tile key))
  220.   (start_image key)
  221.   (cond  ((numberp sld) (fill_image 0 0 x y sld))
  222.     (t
  223.       (fill_image 0 0 x y -2)
  224.       (slide_image 0 0 x y sld)
  225.     )
  226.   )
  227.   (end_image)
  228. )

  229. ;示例
  230. (defun c:tt (/ dcl-id firstimage firstimagebutton firstlist firstpoplist hah1action hah2action hahaaction hahmode im1action im2action layout1 layout2 layout3 layout4 layout5 lst1action lst2action onebutton threebutton twobutton)
  231.   (setq onebutton (vic-dcl-addItem "button" '((key . "hah")(label . "one")(width . 2) (value . "nihao"))))
  232.   (setq twobutton (vic-dcl-addItem "button" '((key . "hah1")(label . "two")(width . 2) (value . "nihao1"))))
  233.   (setq threebutton (vic-dcl-addItem "button" '((key . "hah2")(label . "three")(width . 2) (value . "nihao2"))))
  234.   (setq firstlist (vic-dcl-addItem "list_box" '((key . "lst1"))))
  235.   (setq firstimage (vic-dcl-addItem "image" '((key . "im1") (width . 30)(aspect_ratio . 0.66))))
  236.   (setq firstimagebutton (vic-dcl-addItem "image_button" '((key . "im2") (width . 30)(aspect_ratio . 0.66) (allow_accept . true))))
  237.   (setq firstpoplist (vic-dcl-addItem "popup_list" '((key . "lst2") (edit_width . 4))))
  238.   (setq layout1 (vic-dcl-setLayout "boxed_column" '((label . "onebutton")) (list onebutton twobutton threebutton )))
  239.   (setq layout2 (vic-dcl-setLayout "column" "" (list firstlist firstimage firstimagebutton)))
  240.   (setq layout3 (vic-dcl-setLayout "row" "" (list layout1 layout2)))
  241.   (setq layout4 (vic-dcl-setLayout "row" "" (list firstpoplist "ok_cancel;")))
  242.   (setq layout5 (vic-dcl-setLayout "column" "" (list layout3 layout4)))
  243.   (setq dcl-id (vic-dcl-Init "nihao" layout5))
  244.   (setq hahaaction '(vic-dcl-setaction '("hah"
  245.                                           (print (vic-dcl-getvalues '("lst1" "lst2")))
  246.                                           (done_dialog 5))))
  247.   (setq hah1action '(vic-dcl-setaction '("hah1" (vic-dcl-addlist "lst1" '(5 6 7 8) 1 2))))
  248.   (setq hah2action '(vic-dcl-setaction '("hah2"
  249.                                           ;(princ (vic-dcl-getattrs '(("hah2" . "label"))))
  250.                                           (done_dialog 7))))
  251.   (setq lst1action  '(vic-dcl-addlist "lst1" '( 1 2 3 4) nil nil)
  252.     lst2action '(vic-dcl-addlist "lst2" '(1 2 3 4) nil nil)
  253.     im1action '(vic-dcl-loadsld "im1" 2)
  254.     im2action '(vic-dcl-loadsld "im2" 3)
  255.     hahmode '(vic-dcl-setmodes '( ("hah1" . 1)("im2" . 4))))
  256.   (vic-dcl-startonce dcl-id "nihao"
  257.     (list
  258.       hahaaction hah1action hah2action
  259.       lst1action lst2action
  260.       im1action im2action hahmode
  261.     )
  262.     '((5 getpoint)(7 print "nihao2"))
  263.   )
  264.   (vic-dcl-End dcl-id)
  265. )

点评

来个效果图就更好了  发表于 2015-10-31 10:41

评分

参与人数 3明经币 +3 收起 理由
crazylsp + 1 赞一个!
USER2128 + 1 赞一个!
xyp1964 + 1 赞一个!

查看全部评分

发表于 2015-10-31 13:38:11 | 显示全部楼层
MARK
发表于 2015-10-31 16:29:32 | 显示全部楼层
建议将action定义直接加载AddItem里面一起定义,现在这样上下交错的,debug起来会不太方便,而且代码更长。
另外每个控件都给定义个变量,且这些变量仅组织DCL结构时才使用,似乎可以再优化一下。
 楼主| 发表于 2015-11-1 10:49:06 | 显示全部楼层
mmmmmm 发表于 2015-10-31 16:29
建议将action定义直接加载AddItem里面一起定义,现在这样上下交错的,debug起来会不太方便,而且代码更长。 ...

控件的action属性是可以在定义的时候直接定义的,不过这个action属性有限制,也很少有人直接使用的,而action_tile函数却需要在new_dialog和start_dialog之间使用,所以还是得分开。。
每个控件都定义一个变量确实是有点多,但是没有想到太好的办法既能保证条理清晰又能保证代码少。。。
发表于 2015-11-1 11:32:23 | 显示全部楼层
来个GIF
发表于 2015-11-1 13:10:39 | 显示全部楼层
本帖最后由 mmmmmm 于 2015-11-1 22:42 编辑
山人就是画坑的 发表于 2015-11-1 10:49
控件的action属性是可以在定义的时候直接定义的,不过这个action属性有限制,也很少有人直接使用的,而ac ...

我说的意思不是action属性,而是Action_tile对应的函数,对单一控件,肯定一般的过程是先set_tile赋值,然后直接定义其action_tile函数。没必要在对所有控件赋值后再定义各自的动作。这样从程序运行上没有问题,但是在代码的维护上不如集中设定好。

控件定义的问题上,可能你可以考虑使用类似矩阵的方式,先分解成控件组,再组合之。
一个比较粗糙的概念是构建一个标准3*3的矩形格式(允许被定义成Radio_boxed_column、boxed_column、column之类的格式),
| X0 Y0 Z0 |
| X1 Y1 Z1 |
| X2 Y2 Z2 |
预定义其中的9个变量,然后根据控件实际位置定义相应的变量,没有的就设置成NIL,然后由程序按照矩阵结构将9个变量组合成一个控件组。跟CAD图块定义类似,重复使用变量来构建更多的控件组。最后再参照同样方式组合控件组。可能这样变量依然不能减少太多,但是会相对来说条理可能会更好些。

另外,因为要在程序中写DCL,在定义控件时大量输入label,key啊之类的是件比较无趣体力活,建议使用自定义的缩写,减少输入工作量,也剪短代码。
我把这些思路大概写了两段函数供你参考(没有测试):
(Defun _DefObj (tile data / ABC KEY KEYS RTN)
  (setq        keys '(("::A" . "aligment")
               ("::AA" . "allow_accept")
               ("::AR" . "aspect_ratio")
               ("::BI" . "big_increment")
               ("::C" . "color")
               ("::CA" . "children_alignment")
               ("::CFH" . "children_fixed_height")
               ("::CFW" . "children_fixed_width")
               ("::EL" . "edit_limit")
               ("::EW" . "edit_width")
               ("::IF" . "initial_focus")
               ("::IB" . "is_bold")
               ("::MXV" . "max_value")
               ("::MNV" . "min_value")
               ("::MS" . "multiple_select")
               ("::SI" . "small_increment")
               ("::T" . "tabs")
               ("::V" . "value")
               ("::L" . "label")
               ("::LO" . "layout")
               ("::K" . "key")
               ("::M" . "mnemonic")
               ("::FW" . "fixed_width")
               ("::FH" . "fixed_height")
               ("::W" . "width")
               ("::H" . "height")
               ("::IE" . "is_enabled")
               ("::ITS" . "is_tab_stop")
               ("::ID" . "is_default")
               ("::IC" . "is_cancel")
              )
        rtn  (strcat ": " tile "{")
  )
  (foreach val data
    (setq key (car val)
          val (cdr val)
    )
    (if        (setq abc (cdr (assoc key keys)))
      (setq key abc)
    )
    (if        (or (/= (type val) 'str)
            (member (strcase key) '("LABEL" "VALUE" "KEY"))
        )
      (setq val (vl-prin1-to-string val))
    )
    (setq rtn (strcat rtn key "=" val ";"))
  )
  (setq rtn (strcat rtn "}"))
)
(Defun _DefMatrix (mode / VAR RTN)
;;; Global vars  *dcl00 *dcl01 *dcl02 / *dcl10 *dcl11 *dcl12 / *dcl20 *dcl21 *dcl22
  (setq rtn (strcat ":" mode "{"))
  (cond        ((wcmatch mode "radio_*")
         (foreach var (list *dcl00    *dcl01        *dcl02          *dcl10
                            *dcl11    *dcl12        *dcl20          *dcl21
                            *dcl22
                           )
           (if var
             (setq rtn (strcat rtn var))
           )
         )
        )
        ((wcmatch mode "*column")
         (setq rtn (strcat rtn ": row {"))
         (foreach var (list *dcl00 *dcl01 *dcl02)
           (if var
             (setq rtn (strcat rtn var))
           )
         )
         (setq rtn (strcat rtn "}"))
         (setq rtn (strcat rtn ": row {"))
         (foreach var (list *dcl10 *dcl11 *dcl12)
           (if var
             (setq rtn (strcat rtn var))
           )
         )
         (setq rtn (strcat rtn "}"))
         (setq rtn (strcat rtn ": row {"))
         (foreach var (list *dcl20 *dcl21 *dcl22)
           (if var
             (setq rtn (strcat rtn var))
           )
         )
         (setq rtn (strcat rtn "}"))
        )
        ((wcmatch mode "*row")
         (setq rtn (strcat rtn ": column {"))
         (foreach var (list *dcl00 *dcl10 *dcl20)
           (if var
             (setq rtn (strcat rtn var))
           )
         )
         (setq rtn (strcat rtn "}"))
         (setq rtn (strcat rtn ": column {"))
         (foreach var (list *dcl01 *dcl11 *dcl21)
           (if var
             (setq rtn (strcat rtn var))
           )
         )
         (setq rtn (strcat rtn "}"))
         (setq rtn (strcat rtn ": column {"))
         (foreach var (list *dcl02 *dcl12 *dcl22)
           (if var
             (setq rtn (strcat rtn var))
           )
         )
         (setq rtn (strcat rtn "}"))
        )
  )
  (setq rtn (strcat rtn "}"))
)

你现在的方式过于复杂,可能自己用可以,推广的话,太复杂不容易被理解和接受。
发表于 2015-11-1 16:27:39 | 显示全部楼层
mark,养肥了在来看。
发表于 2015-11-2 00:33:02 | 显示全部楼层
弱弱的問下..這樣寫DCL. 不知道有什麼特別好處.~
发表于 2015-11-2 02:50:59 | 显示全部楼层
好东西 啊!谢谢分享!
发表于 2015-11-2 02:57:01 | 显示全部楼层
结尾没有删除临时DCL文件!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-5-21 06:17 , Processed in 0.187089 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表