(defun fun_begin()
  (setq 
    osmode_old (getvar "osmode")
    cmdecho_old (getvar "cmdecho")
  )
  (setvar "cmdecho" 0)
  (command "undo" "be")
)
(defun fun_end()
  (setvar "osmode" osmode_old)
  (setvar "cmdecho" cmdecho_old)
  (command "undo" "e")
)

;=========================================================
;stringsformat格式化字符串
(defun stringsformat(strings strlength aligntoright)
	(if (< strlength (strlen strings))
		(setq strings (substr strings 1 strlength))
		(repeat (- strlength (strlen strings))
			(if aligntoright
				(setq strings (strcat "0" strings))
				(setq strings (strcat strings " "))
			)
		)
	)
	strings
)

;;;=========================================================
;  lst2lststr_layer 将分组列表转化为list列表
(defun lst2lststr_layer(lst / i lst_items str_row)
	(setq i 0)
	(repeat (length lst)
		(setq	str_row
			(strcat
				(stringsformat (itoa i) 2 t) " | "
				(stringsformat (nth i lst) 20 nil)
			)
			lst_items (append lst_items (list str_row))
			i (1+ i)
		)
	)
	lst_items
)

;;;======================================================================;
;; getLayerNameList 返回层名列表
;  语法: (getLayerNameList)
;  说明: 返回层名列表
;  参数: -
;  返回: 层名列表
(defun getLayerNameList( / layer layer_list layers)
	(setq layers (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
	(vlax-for layer layers
		(setq layer_list (append layer_list (list (vla-get-name layer)) ))
	)
)

;;;======================================================================;
;; str2lst 将输入的数据转换为字符串列表
;  语法: (str2lst str)
;  说明: 将输入的数据转换为字符串列表
;  参数: str:字符串
;  返回: 列表
;  示例: (str2lst  "Hello 2World 12 5456.1568")  -> ("Hello" "2World" "12" "5456.1568")
(defun str2lst (str /)
  (read (vl-list->string
	  (apply 'append(mapcar '(lambda (x)(if (= 32 x) (list 34 32 34) (list x)))(append (list 40 34)(vl-string->list str)(list 34 41))))
  ))
)

;=========================================================
;numlst2str将数字列表转化为数字字符串
(defun numlst2str (numlst delimiter / num return)
	(setq return "")
	(foreach num numlst
		(setq return (strcat return delimiter (itoa num)))
	)
	(substr return 2)
)

;;;=========================================================
;  lst2str 将字符串列表转化为字符串
;  语法: (lst2str lst)
;  说明: 将输入的数据转换为字符串列表
;  参数: lst2str:字符串列表
;  返回: 字符串
;  示例: (lst2str '("Hello" "2World" "12" "5456.1568"))  -> "Hello 2World 12 5456.1568"
(defun lst2str(lst / i str1 str)
	(setq i 0 str "")
	(repeat (length lst)
		(setq str1 (nth i lst))
		(setq str (strcat str " " str1))
		(setq i (1+ i))
	)
	(substr str 2)
)

;get_layer_list读取当前层列表，并按照原有列表顺序进行排序
(defun get_layer_list( / layer_list layer_list_old e1 e2)
	(setq layer_list (getLayerNameList))
	(if (/= (getvar "users1") "")
		(progn
			(setq layer_list_old (str2lst (getvar "users1")))
			(setq layer_list (vl-sort layer_list (function (lambda (e1 e2)
				(< (length (member e1 layer_list_old)) (length (member e2 layer_list_old))))))
			)
		)
	)
	layer_list
);get_layer_list end

;sort_layer_list将图层列表转换为对话框中列表框的项目
(defun sort_layer_list(xlayernamelist / index index_item layer_name lst_item lst_items);sort_layer_list
	(setq
		index 0
		glb_str_layers ""
	)
	(repeat (length xlayernamelist)
		(if (<= (car (nth index xlayernamelist)) 9)
			(setq index_item (strcat "0" (itoa (car (nth index xlayernamelist)))))
			(setq index_item (itoa (car (nth index xlayernamelist))))
		)
		(setq
			layer_name (cdr (nth index xlayernamelist))
			lst_item (strcat index_item " | " layer_name)
			index (1+ index)
			glb_str_layers (strcat glb_str_layers " " layer_name)
			lst_items (append lst_items (list lst_item))
		)
	)
);sort_layer_list

;show_dialog初始化并显示对话框
(defun show_dialog(xlayernamelist xselected_items / lst_items)
	(if (not (new_dialog "main" dcl_id))(exit))
	(start_list "list_layer")
	(mapcar 'add_list xlayernamelist)
	(end_list)
	(action_tile "up" "(move_layers -1)")
	(action_tile "down" "(move_layers 1)")
	(action_tile "accept" "(done_dialog)(setq yesno T)")
	(action_tile "cancel" "(done_dialog)(setq yesno nil)")
	(set_tile "list_layer" (itoa xselected_items))
	(start_dialog)
	(unload_dialog dcl_id)
);show_dialog

;;;=====================================================================;
;; exchange_list_2items 交换列表中指定序号的两项，首项序号为0
;  语法: (exchange_list_2items items_list index_item1 index_item2)
;  说明: 交换列表中指定序号的两项，首项序号为0
;  参数: items_list:列表 index_item1、index_item2:需要交换的项目序号,首项序号为0
;  返回: 列表
;  示例: (exchange_list_2items  (list 1 2 3 4 5) 1 2)  -> (1 3 2 4 5)
(defun exchange_list_2items(items_list index_item1 index_item2 / ijk items_list_new)
	(setq
		items_list_new (list "new")
		ijk 0
	)
	(repeat (length items_list)
		(cond
			((= ijk index_item1)(setq items_list_new (append items_list_new (list (nth index_item2 items_list)))))
			((= ijk index_item2)(setq items_list_new (append items_list_new (list (nth index_item1 items_list)))))
			(t(setq items_list_new (append items_list_new (list (nth ijk items_list)))))
		)
		(setq ijk (1+ ijk))
	)
	(cdr items_list_new)
)

;=========================================================
;updown_move_items 设置列表移动操作
;  语法: (updown_move_items items_list index_move_list xupdown)
;  说明: 将列表中指定序号的数项前后移动一位
;  参数: items_list:列表 index_move_list:需要交换的移动序号列表,首项序号为0 xupdown移动方向（-1向前 1向后）
;  返回: 列表
;  示例: (exchange_list_2items  (list 1 2 3 4 5) 1 2)  -> (1 3 2 4 5)
(defun updown_move_items(items_list index_move_list xupdown / index_first index_last index_move index_move_list_sort is_bottom is_stop is_top x)
  (setq
		index_move_list_sort (vl-sort index_move_list '<)
		index_first (car index_move_list_sort)
		index_last (last index_move_list_sort)
		is_top (and (= index_first 0) (= xupdown -1))
		is_bottom (and (= index_last (1- (length items_list))) (= xupdown 1))
		is_stop (or is_top is_bottom)
	);判断所上移的对象是否到达顶部，所下移的对象是否到达底部
	(if (= xupdown 1) (setq index_move_list_sort (reverse index_move_list_sort)))
	(if (= is_stop nil)
		(progn
			(foreach index_move index_move_list_sort
				(setq
					items_list (exchange_list_2items items_list index_move (+ index_move xupdown))
				)
			);对选中的对象进行移动操作
			(setq	index_move_list (mapcar '(lambda(x) (+ x xupdown)) index_move_list));获取移动完成以后的选中项序号
		)
  )
	(list items_list index_move_list)
);move_items

;=========================================================
;move_layers设置对话框中列表框项目上下移动操作，以实现对排序
(defun move_layers(xupdown / index_movelayers_list liststrlist selected_items selected_softlists)
	(setq index_movelayers_list_str (get_tile "list_layer"))
	(setq index_movelayers_list (read (strcat "(" index_movelayers_list_str ")")));获取所需上下移动的项目编号
	(setq selected_layerlists (updown_move_items glb_Layer_List index_movelayers_list xupdown))
	(setq selected_items (numlst2str (cadr selected_layerlists) " "))
	(setq glb_Layer_List (car selected_layerlists))
	(setq liststrlist (lst2lststr_layer glb_Layer_List))
	(start_list "list_layer")
	(mapcar 'add_list liststrlist)
	(end_list);根据移动后的次序重新生成列表框列表项目
	(set_tile "list_layer" selected_items);重新设置所选中项目的位置
);move_layers

;doit根据排列后的图层列表进行对象的显示顺序操作
(defun doit(xyesno)
	(if xyesno
		(foreach layer glb_Layer_List
			(setq ss (ssget "X" (list (cons 8 layer_name))))
			(command "draworder" ss "" "b")
		)
	)
	(princ)
)

(defun c:super_draworder( / selected_item selected_items)
	(fun_begin)
	(setq
		dcl_id (load_dialog "super_draworder.dcl")
		glb_Layer_List (get_layer_list)
	)
	(show_dialog (lst2lststr_layer glb_Layer_List) 0)
	(doit yesno)
	(setvar "users1" (lst2str glb_Layer_List))
	(princ)
	(fun_end)
)