當我們要在CAD中創建自定菜單時,可以引用COM組件來實現。
下面是實現方式:
1、新建類庫項目,並引用CAD目錄(我這里用的是CAD2008)下的acdbmgd.dll、acmgd.dll,並將引用屬性中的“復制本地”設為False。
2、添加Com引用:AutoCAD 2008 Type Library。
3、創建類“Main.cs”,並在類頭部命名空間上加上修飾:
[assembly: CommandClass(typeof(AutoCAD_PopMenuTestCom.Main))]
這樣做是為了讓CAD更空間找到我們的程序集。
4、以下是實現代碼:
[CommandMethod("SMM")] public void ShowMyMenu() {
//獲取CAD應用程序 AcadApplication app = (AcadApplication)Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication; for (int i = 0; i < app.MenuGroups.Item(0).Menus.Count; i++) { if (app.MenuGroups.Item(0).Menus.Item(i).Name == "我的菜單Com") //判斷菜單是否已存在,如果存在則不再創建 return; } AcadPopupMenu pmParnet = app.MenuGroups.Item(0).Menus.Add("我的菜單"); //添加根菜單 //多級 AcadPopupMenu pm = pmParnet.AddSubMenu(pmParnet.Count + 1, "打開"); AcadPopupMenuItem pmi0 = pm.AddMenuItem(pm.Count + 1, "文件 ", "OPEN1\n"); //第一個參數是在菜單項中的位置(第幾項),第二個參數是顯示的名稱,第三個參數是點擊之后執行的命令 AcadPopupMenuItem pmi1 = pm.AddMenuItem(pm.Count + 1, "模版 ", "OPEN2\n"); //單級 AcadPopupMenuItem pmi2 = pmParnet.AddMenuItem(pmParnet.Count + 1, "退出 ", "EXIT\n"); //將創建的菜單加入到CAD的菜單中 pmParnet.InsertInMenuBar(app.MenuBar.Count + 1); }
將項目生成之后,啟動CAD2008,輸入命令:netload,然后找到我們生成的dll進行加載,加載完成之后,輸入命令SMM,不出意外的話,就可以看到我們的菜單了(如果CAD提示找不到命令,可能是CAD出了問題,可以修復一下)。
以下是運行后的效果:

到了這里,也許你可以還有另一個要求:我不想每次都要輸入命令才能加載菜單,我想讓CAD啟動時自動加載菜單。
這個是很好實現的:
1、寫入注冊表項
我們的自定義程序集有一種啟動方式是注冊表啟動,讓CAD根據注冊表信息去加載我們的程序集。
在注冊表項:LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD中記錄了本機安裝的CAD的信息,如下圖:
而展開RX.X項,下面的一級如果后綴是804表示的是中文版,409表示的是英文版:

繼續展開找到Applications項,我們要在Applications下面建一個屬性我們自己的程序集的項,比如我這里建的是“MyMenuTestCom”。
然后給我們新建的項添加四個值:
| 健 | 類型 | 值 |
| DESCRIPTION | REG_SZ(字符串) | 簡介說明 |
| LOADCTRLS | REG_DWORD(數字) | 加載方式: 0x01:當代理對象被檢測到時加載程序 0x02:當AutoCAD啟動時加載程序 0x04:當輸入命令時加載程序 0x08:當有用戶或別的程序請求時加載程序 0x10:從不加載該應用程序 0x20:顯式加載該應用程序 |
| LOADER | REG_SZ(字符串) | dll路徑 |
| MANAGED | REG_DWORD(數字) | 是否是拖管程序集:1=是 |
這樣在CAD啟動時就會自動加載我們的dll了,但是這還不夠。
2、實現IExtensionApplication接口
CAD提供了一個IExtensionApplication接口,CAD在加載托管程序的時候,會調用實現了此接口的類進行初始化操作(在程序集被卸載時也會調用此類,即在CAD關閉時也會調用)。我們可以在這個類里調用我們創建菜單的方法,即可讓我們的菜單在CAD啟動時自動加載。
public class Init : IExtensionApplication { #region IExtensionApplication 成員 //在程序集初始化時 public void Initialize() { //在程序集被初始化時,執行創建菜單操作,再配合注冊表設置可以實現菜單的自動加載 Main main = new Main(); main.ShowMyMenu(); } //在程序集被卸載時(也可以理解為CAD關閉時) public void Terminate() { } #endregion }
關閉IExtensionApplication更多的介紹可以看這里,但是對於該文章中提到的一點經過實踐並不正確,也可能是意思並不明確:
2.[assembly: ExtensionApplication(typeof(ManagedApp.Init))]
上面表示ExtensionApplication屬性,CAD首先查找它標志的類來初始化,如果沒有找到,就找如上面public class Init :IExtensionApplication 實現了IExtensionApplication的類,如果還是沒有找到,就跳過初始化。所以上面[assembly:ExtensionApplication(typeof(ManagedApp.Init))]和public class Init : IExtensionApplication后面的IExtensionApplication寫上一處就可以了。
經過實踐證明,[assembly:ExtensionApplication(typeof(ManagedApp.Init))]可有可無,但是public class Init : IExtensionApplication后面的IExtensionApplication必須有。
完整的測試代碼下載:點擊這里
