- 积分
- 13633
- 明经币
- 个
- 注册时间
- 2005-5-7
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 x_s_s_1 于 2022-3-27 17:57 编辑
文章较长,且逻辑性不强,没兴趣请跳过
对于可能长时间处于一个固定状态的制图工作,一个大面板可能效率不高。我针对于自己的实际需要,采用了右键菜单,模拟小面板。这样做的好处在于1.提高效率;2.可以用快捷键,经常打游戏的asdfqwe用得比较溜的,可以试试。效果如下:
本人水平有限,对于mnu文件和popupmenu对象一知半解,希望各位网友指正。
思路是这样的
1.准备ini文件,通过读ini文件,修改菜单;(这里可以改成读excel,方便修改,我对这方面不熟,用的读txt文件)
文件格式为
"模态标签","模态名称"
"快捷键","命令提示","命令"
下面是ini文件片段
- MODE1,转换出图
- 1,计算导入,AAJSSDRGL
- a,图纸转换,XTY-CMD-YJK
- MODE2,基础绘制
- a,范围选数,XTY-CMD-FWXS
- s,墙柱填充,XTY-CMD-HATCH
- d,承台桩定位,AACTZDWBZ
- 。。。
2.读取ini文件(我用的文件名为XTDI-COMMAND.INI,把他放到支持文件夹),形成表;
- (defun xty-mnu-getini (/ F FILE LST LST1 TXT temp)
- (setq file (findfile "XTDI-COMMAND.INI")
- f (open file "r")
- lst '() ;_准备总表
- lst1 '() ;_准备分表
- )
- (while (setq txt (read-line f)) ;_读每行
- (if (wcmatch txt "MODE*") ;_当为mode
- (setq lst (if lst1
- (cons (reverse lst1) lst)
- ) ;_当分表不空,倒置分表组总表
- lst1 (list(xty-str-tolstby txt ",")) ;_mode放入分表
- )
- (setq temp (xty-str-tolstby txt ",")
- temp (list(strcat (car temp)"."(cadr temp))(strcat (caddr temp)" "))
- lst1 (cons temp lst1)
- ) ;_非mode放入分表
- )
- )
- (close f)
- (setq lst (cons (reverse lst1) lst) ;_最后一个分表要倒置组入总表
- lst (reverse lst) ;_倒置总表
- )
- )
3.替换AutoCAD的默认右键菜单项,我用的是autocad2020中文版,默认菜单的名称为"默认菜单";
- ;;;=============================================
- ;;; 通用函数 替换菜单全部项
- ;;;参数: mnugname--------要修改的菜单组名
- ;;; mnuname---------要修改的菜单名
- ;;; itemlst-----要修改的菜单项表
- ;;;返回值:修改的菜单对象
- ;;;示例xty-mnu-changepop "acad" "默认菜单" '(("a.l""line ")))
- (defun xty-mnu-changepop (mnugname mnuname itemlst / mnug mnus pop stct i)
- (setq mnug (vl-catch-all-apply
- 'vlax-invoke-method
- (list *xty-mnugs* 'item mnugname)
- ) ;_菜单组是否存在
- )
- (if (null (vl-catch-all-error-p mnug)) ;_如果存在要搜索菜单组
- (progn
- (setq mnus (vlax-get-property mnug 'menus)) ;_菜单组中的菜单
- (setq stct (vl-catch-all-apply
- 'vlax-invoke-method
- (list mnus 'item mnuname)
- )
- )
- (if (null (vl-catch-all-error-p stct)) ;_如果存在右键弹出菜单pop0
- (progn
- (vlax-for pop stct (vlax-invoke-method pop 'delete)) ;_删除所有菜单项
- (setq i 0)
- (foreach n itemlst
- (vlax-invoke-method stct 'addmenuitem i (car n) (cadr n))
- (setq i (1+ i))
- ) ;_重新写菜单项
- )
- )
- )
- )
- stct
- )
4.主程序,写mnu文件(我用的名称是CareFromOldXia,可以相应修改),加载到autocad。这里要考虑修改了ini文件,重新加载的方法。现阶段版本autocad都是用cuix文件,所以在重载的时候要将相关文件都删掉;注意*xty-Installfolder*全局变量,这里是我自己的默认文件夹,请根据需求自行修改。
- (defun c:xty-cmd-updatemytb (/ a b f i lst lst1 mymnu n)
- (setq mymnu (vl-catch-all-apply
- 'vlax-invoke-method
- (list *xty-mnugs*
- 'item
- "CareFromOldXia"
- )
- )
- ) ;_获取我的工具条
- (vl-catch-all-apply
- 'vlax-invoke-method
- (list mymnu
- 'unload
- )
- ) ;_删除我的工具条
- (foreach n '("CareFromOldXia.cuix"
- "CareFromOldXia.mnr"
- "CareFromOldXia_light.mnr"
- "CareFromOldXia.bak.cuix"
- )
- (vl-catch-all-apply 'vl-file-delete (list (findfile n)))
- ) ;_删除加载菜单生成文件,避免不更新
- (setq lst (xty-mnu-getini)
- lst1 (mapcar 'car lst)
- f (findfile "CareFromOldXia.mnu")
- f (open f "w")
- i 1
- )
- (write-line "***menugroup=CareFromOldXia" f)
- (write-line "***POP0" f);_这里是为其它程序预留的,可以删掉
- (write-line "**SNAP" f);_这里是为其它程序预留的,可以删掉
- (write-line "[shortcut]" f);_这里是为其它程序预留的,可以删掉
- (write-line "***TOOLBARS=allbar" f)
- (write-line "**工作模态" f)
- (write-line
- "ID_TBA_00 [_Toolbar(\"工作模态\", _Right, _show,0,0,0)]"
- f
- )
- (write-line
- "ID_TBA_01 [_Button(\"更新本工具条\",\"BMP\\\xty_modeuser_16.bmp\",\"BMP\\\xty_modeuser_32.bmp\")]^c^cxty-cmd-updatemytb"
- f
- )
- (setq n (car lst1)
- i 0
- )
- (foreach n lst1
- (setq a (car n)
- b (cadr n)
- )
- (write-line
- (strcat
- "ID_TBA_"
- (xty-tr-add0 (itoa (setq i (1+ i))) 2)
- " [_Button(\"工作模态切换至"
- b
- "\",\"BMP\\\xty_"
- a
- "_16.bmp\",\"BMP\\\xty_"
- a
- "_32.bmp\")]^c^c^p(setenv \"xty-myworkmode\" \""
- a
- "\");xty-cmd-menumode"
- )
- f
- )
- )
- (close f)
- (setq
- mymnu
- (vl-catch-all-apply
- 'vlax-invoke-method
- (list *xty-mnugs*
- 'load
- (strcat *xty-Installfolder* "\\CareFromOldXia.mnu")
- )
- )
- )
- (princ)
- )
5.点击按钮,切换工作模态。
- (defun c:xty-cmd-menumode (/ mode lst lst1 lst2 lst3 n)
- (setq mode (getenv "xty-myworkmode");_此处设置环境变量"xty-myworkmode",可根据需要修改
- lst (xty-mnu-getini)
- lst1 (mapcar 'car lst)
- lst2 (mapcar 'car lst1)
- lst3 (mapcar 'cdr lst)
- n(-(length lst2)(length(member mode lst2)))
- lst3(nth n lst3)
- )
- (xty-mnu-changepop "acad" "默认菜单" lst3)
- (princ (strcat"\n当前工作模态切换为:"(cadr(nth n lst1))))
- (princ)
- )
6.一些用到的函数以及全局变量
- ;;;全局变量
- (setq *xty-acobj* (vlax-get-acad-object));_cad本身
- (setq *xty-mnugs* (vlax-get-property *xty-acobj* 'MenuGroups));_菜单组集合
- ;;;=============================================
- ;;; 通用函数 将字符串以给定Key分解成表
- ;;;参数:Str------字符串
- ;;; Key------分隔符
- ;;;返回值 字符串表
- (defun xty-str-ToLstBy (Str Key / i s lst)
- (while
- (setq i (vl-string-search Key Str))
- (setq
- s (substr Str 1 i)
- Str
- (substr Str
- (+ 1
- (strlen key)
- (if i
- i
- 0
- )
- )
- )
- Lst (cons s Lst)
- )
- )
- (vl-remove "" (reverse (cons str Lst)))
- )
- ;;;=============================================
- ;;; 通用函数 加前导0
- ;;;参数: str-------字符串
- ;;; n---------加零后字符串长度
- ;;;返回值:加前导零后字符串
- (defun xty-tr-add0 (str n)
- (setq n (- n (strlen str)))
- (repeat n (setq str (strcat "0" str)))
- str
- )
7.存在的问题,修改acad默认菜单是比较危险的事情,我现阶段的编程水准导致我无法解决该问题。我在CareFromOldXia.mnu中预留了pop0,
- (write-line "***POP0" f);_这里是为其它程序预留的,可以删掉
- (write-line "**SNAP" f);_这里是为其它程序预留的,可以删掉
- (write-line "[shortcut]" f);_这里是为其它程序预留的,可以删掉
也预留了函数
- ;;;=============================================
- ;;; 通用函数 显示局部快捷菜单
- ;;;参数: mnugname--------要修改的菜单组名
- ;;; mnuname---------要修改的菜单名
- ;;; itemlst-----要修改的菜单项表
- ;;;返回值:无,显示快捷菜单
- (defun xty-mnu-local (mnugname mnuname itemlst)
- (xty-mnu-changepop mnugname mnuname itemlst)
- (menucmd "0=CareFromOldXia.POP0")
- (menucmd "0=*")
- )
但是无法找到右键弹出菜单的方法,反应器也不行,好像采用了cuix以后的版本都将右键默认菜单固定为acad.cuix。8.用到的BMP文件,可根据自己需要自定义
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
评分
-
查看全部评分
|