cad之輔助提示功能
最近有個小老弟自己在網上找了一大堆插件,然後他想做一個類似菜單什麼的去使用這些零碎的插件,想自定義一個工具集,然後就問我菜單,工具欄,屏幕菜單等等的做法,這裏做一個總結,相關資料信息在XD論壇,明經通道都有。。。
常見的cad輔助提示,包括菜單,工具欄,難度大的包括屏幕菜單,增強工具欄等等
菜單
cad的菜單比較常見,比如
一般來說,給別人做插件的時候,如果做的是一個模塊的插件,比如這種對支架的模塊
那麼菜單就是比較合適的了。
製作菜單的辦法有很多,比如使用MFC創建,使用COM創建,使用CUI文件等,在這裏,我最推薦的方法是使用CUI,快捷,方便,幾乎不會出錯。這裏,給個例子:首先創建mnu格式的文件,寫入如下:
***MENUGROUP=SIMPLE_GROUP
***POP1
**FILE
ID_MENU_FILE [場地平面圖文件(&F)]^C^C_open
ID_FILE_LOCATION [存儲平面位置(&L)]^C^CPMWZ
ID_FILE_LAYOUT [存儲場地佈置(&A)]^C^CCDBZ
ID_FILE_PLAN [存儲計劃(&P)]^C^CCCJH
[--]
ID_FILE_EXIT [退出(&E)]^C^C_quit
[--]
***HELPSTRINGS
ID_MENU_FILE [打開場地平面圖文件]
ID_FILE_LOCATION [存儲場地平面位置到磁盤文件中]
ID_FILE_LAYOUT [存儲場地佈置到二進制文件中]
ID_FILE_PLAN [存儲施工計劃到磁盤文件中]
ID_FILE_EXIT [退出ACAD]
然後,打開cad,使用命令menuload,加載這個mnu文件,cad加載後,會生成同名的mnr和cuix文件
我一般懶得進行進一步的優化菜單,讓它更加美觀,如果有人願意這麼做的話,可以使用cui編輯器,去給這個cuix菜單文件添加圖標啊什麼的,更加好看。
把cuix文件和arx文件放在一起,最後在代碼中加載這個cuix文件即可。
最後做一下總結:使用cuix文件生成菜單的方法最方便,快捷,不需要你修改代碼,在添加icon的過程中更加方便,簡單。對於com和mfc方法去添加菜單的,有兩點不好,一是修改菜單就要修改代碼,二是,切換cad的工作空間,菜單會消失,這個比較麻煩。
工具欄
實話,工具欄也是我比較推薦的方法,如果你做的插件也是專屬於一個模塊,但是,命令卻比較少,比如也就10個以內,那麼工具欄就是很好的方法了,工具欄的做法也有多種,com,MFC,cuix都可以做,這裏同樣優先推薦使用cuix的方法,方便,簡單,如果不會操作的,打開cad,按下F1,幫助文檔裏面都有如何創建工具欄菜單等
我在這裏說的是增強型工具欄,比如插件老虎板王,msteel的工具欄
使用增強型工具欄,主要是對於大型的,多模塊的命令,做一個界面化的操作,適合於中等偏大型的做法,我也做了一個類似的東西
它的佈局和裏面的菜單最好是有一個文件控制,比如需要多少個按鈕,按鈕裏面有多少個菜單等,在一個文件內寫清楚後,解析這個文件,生產這個工具欄。
[按鈕]
結構建模
畫牆工具
牆柱繪製
樓板工具
基礎設計
鋼筋繪製
文字工具
圖層工具
其他工具
[MENU=結構建模]
0-梁線建模-MODEL_LXJM
0-梁模轉圖-MODEL_LMZT
0-牆線建模-MODEL_QXJM
0-牆模轉圖-MODEL_QMZT
[MENU=畫牆工具]
0-軸線畫梁-BEAM_ZXHL
0-畫直線梁-BEAM_HZXL
0-梁中生線-BEAM_LZSX
0-梁梁交線-BEAM_LLJX
0-樑柱交線-BEAM_LZJX
0-虛實變換-BEAM_XSBH
0-粗線變梁-BEAM_CXBL
0-連接梁線-BEAM_LJLX
0-梁折斷線-BEAM_LZDX
1
0-線比係數-BEAM_XBXS
0-梁集標註-BEAM_LJZB
0-編號查詢-BEAM_BHCX
0-梁重編號-BEAM_LCBH
[MENU=牆柱繪製]
0-插方形柱-COLU_CFZ
0-插圓形柱-COLU_CYZ
0-柱子填充-COLU_ZTC
0-柱子空心-COLU_ZKX
0-柱虛實-COLU_ZXS
0-柱放大-COLU_ZFD
1
0-粗線變牆-WALL_CXBQ
0-牆填充-WALL_QTC
0-牆空心-WALL_QKX
0-牆虛實-WALL_QXS
0-牆端封口-WALL_QFK
0-牆上開洞-WALL_QKD
0-牆線折斷-WALL_QXZD
1
0-牆柱形心-WC_QZXX
0-牆柱工具-WC_QZGJ
[MENU=樓板工具]
0-板開洞口-FLOOR_DK
0-板填充一-FLOOR_BTCA
0-板填充二-FLOOR_BTCB
0-板填充三-FLOOR_BTCC
0-添加板厚-FLOOR_TJBH
[MENU=基礎設計]
0-樁數統計-BASE_ZSTJ
0-畫樁程序-BASE_HZCX
[MENU=鋼筋繪製]
0-繪製點筋-REIN_HZDJ
0-空實變換-REIN_KSBH
1
0-繪製拉筋-REIN_HZLJ
0-S形拉筋-REIN_SLJ
0-繪製箍筋-REIN_GJ
0-連續鋼筋-REIN_LXGH
0-線變鋼筋-REIN_XBGJ
0-繪組鋼筋-REIN_HZGJ
1
0-附加吊筋-REIN_FJDJ
0-附加箍筋-REIN_FJGJ
0-任意負筋-REIN_RYFJ
0-任意正筋-REIN_RYZJ
0-板鉤變換-REIN_BGBH
0-範圍選數-REIN_FWXS
[MENU=文字工具]
0-文字查找-TEXT_WZCZ
0-統一字高-TEXT_TYZG
0-文字邊框-TEXT_WZBK
0-文本偏移-TEXT_WBPY
0-文字連接-TEXT_WZLJ
1
0-文字對齊-TEXT_WZDQ
0-修改對齊-TEXT_XGDQ
0-文字平行-TEXT_WZPX
0-轉MTEXT-TEXT_ZMTEXT
0-調行間距-TEXT_THJJ
0-查字重疊-TEXT_CZCD
1
0-加前後綴-TEXT_JQHZ
0-文字互換-TEXT_WZHH
0-文字刷-TEXT_WSZ
0-求平均數-TEXT_QPJS
0-快速改字-TEXT_KSGZ
[MENU=圖層工具]
0-圖層設置-_layer
0-轉當前層-_laycur
0-置爲當前-_laymcur
0-選層顯示-LAYER_XCXS
0-選層關閉-_layoff
0-圖層全開-_layon
0-鎖定圖層-_laylck
0-解鎖圖層-_layulk
0-圖層刪除-LAYER_TUSC
0-參照開關-LAYER_CZKG
0-圖層前置-LAYER_TCQZ
0-圖層後置-LAYER_TCHZ
0-填充後置-LAYER_TCHZ
0-按色顯示-LAYER_ASXS
1
0-隱藏對象-LAYER_YCDX
0-顯示對象-LAYER_XSDX
[MENU=其他工具]
0-結構審圖-OTHER_YXST
0-引線文字-OTHER_YXWZ
0-繪製箭頭-OTHER_HZJT
0-改線寬度-OTHER_GXKD
0-選擇易-OTHER_XZY
0-隨心拉移-GG
0-線弧轉PL-OTHER_XHZPL
0-多線加點-OTHER_DXJD
0-多線去點-OTHER_DXQD
0-存爲今天-OTHER_CWJT
這個是我寫的一個文件,它裏面包括了按鈕,和每個按鈕下的菜單。
假如菜單內含有子菜單
[MENU=其他工具]
0-結構審圖-OTHER_YXST
0-引線文字-OTHER_YXWZ
0-繪製箭頭-OTHER_HZJT
0-改線寬度-OTHER_GXKD
0-選擇易-OTHER_XZY
2-其他設置
0-線弧轉PL-OTHER_XHZPL
0-多線加點-OTHER_DXJD
0-多線去點-OTHER_DXQD
0-存爲今天-OTHER_CWJT
[SUBMENU=其他設置]
0-線弧轉PL-OTHER_XHZPL
0-多線加點-OTHER_DXJD
這樣子添加即可,方便實用,不需要修改代碼,解析文件就好
這個增強型工具欄的思路:
#pragma once
#include "resource.h"
#include "SendCmd.h"
#include "ToolButton.h"
#define BAR_FIRST_MENU_ID 3000
#define BAR_FIRST_BUTTON_ID 4000
struct MenuItemTag
{
public:
MenuItemTag(UINT flags, UINT ids, CString name, CString cmd) : menuName(name),menuCmd(cmd)
{
nFlags = flags;
nIds = ids;
}
MenuItemTag(const MenuItemTag& other)
{
nFlags = other.nFlags;
nIds = other.nIds;
menuName = other.menuName;
menuCmd = other.menuCmd;
}
MenuItemTag& operator = (const MenuItemTag &other)
{
if (this != &other)
{
nFlags = other.nFlags;
nIds = other.nIds;
menuName = other.menuName;
menuCmd = other.menuCmd;
}
return *this;
}
public:
UINT nFlags;//MF_STRING, MF_SEPARATOR,MF_SUBPOP
UINT nIds;
CString menuName;
CString menuCmd;
};
typedef std::vector<MenuItemTag> MenuGroup;
typedef std::map<CString, MenuGroup> MenuMap;
typedef std::map<UINT, CString> MenuCmdMap;
class CBarDlg : public CAcUiDialogBar
{
DECLARE_DYNAMIC(CBarDlg)
public:
CBarDlg(CWnd* pParent = NULL); // 標準構造函數
virtual ~CBarDlg();
// 對話框數據
enum { IDD = IDD_DIALOG_MENUBAR };
//一系列button
std::vector<CToolButton*> m_buttons;
MenuMap m_map;
MenuCmdMap m_cmdMap;
void InitMenuMap();
//彈出菜單
CMenu m_popMenu;
void PopupMenu(CString titleName, UINT nCtrlId);
void CreateSubPopupMenu(CMenu &popMenu, CString titleName);
CPoint GetTrackPnt(UINT nCtlrId);
void OnToolButtonClick(UINT buttonId);
void OnPopupMenuItemClick(UINT menuId);
std::vector<CString> GetMenu(CString menuPath);
void CreateButton(std::vector<CString>& button);
void CreateMenu(std::vector<CString>& button);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
DECLARE_MESSAGE_MAP()
protected:
afx_msg void OnPaint();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg LRESULT OnInitDialog(WPARAM, LPARAM);
};
//-----------------------------------------------------------------------------
//----- ToolButton.h : Declaration of the CToolButton
//-----------------------------------------------------------------------------
#pragma once
//-----------------------------------------------------------------------------
#include "acui.h"
//-----------------------------------------------------------------------------
class CToolButton : public CAcUiToolButton
{
DECLARE_DYNAMIC (CToolButton)
CString m_strCaption;//名稱
CFont *m_pFont;
public:
CToolButton();
virtual ~CToolButton();
BOOL Create(LPCTSTR str, DWORD dyStyle, const RECT& rect, CWnd *parent, UINT nID);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
};
一個CAcUiDialogBar的派生,一個CAcUiToolButton的派生,就搞定了,比較簡單
屏幕菜單
按照道理來講,屏幕菜單估計是最麻煩的體系了,商業化的大型插件工具纔會用到這個,比如天正和探索者,一般來說都是大型商業化的東西纔會用到這個,自定義程度最高。屏幕菜單裏面可以添加很多東西,比如圖標按鈕,抽屜型菜單,各種帶有ICON的按鈕等等,反正做的比較好看,但是這個就需要MFC功底了,並且需要大型維護,成本比較高。這是我自己做的屏幕菜單
這個東西,我在明經通道上看到的類似的,然後拿過來重寫的。複雜點,但是也是和增強型工具欄一樣,寫一個mnu或者txt描述所有的菜單,然後以後修改文件即可修改屏幕菜單,一勞永逸。
總結
方法 | 優點 | 缺點 |
---|---|---|
工具欄 | 適合少量命令 | 不適合大型模塊,多模塊 |
菜單 | 適合中小型模塊, 多模塊 | 不適合大型模塊,使用com和MFC方式有缺點 |
增強工具欄 | 適合大中型體系模塊 | 需要維護代碼,成本高 |
屏幕菜單 | 適合商業化插件 | 成本高 |
強烈推薦,儘量使用工具欄和菜單欄,成本低,不會編程的人也能按照幫助文檔去建立自己的一套插件模塊。並且一套cui文件,幾乎所有cad都會識別,不像編程那種,還要編譯多個版本,麻煩!最後,小老弟採用了工具欄+菜單欄的辦法,一套cui全搞定,而且,本來cad的繪圖區域就不大,菜單和工具欄佔據的空間是最小的,也是最容易調整的