一 c++ COM接口
void addMenuThroughCom(){ AutoCAD::IAcadApplication *pAcad; AutoCAD::IAcadMenuBar *pMenuBar; AutoCAD::IAcadMenuGroups *pMenuGroups; AutoCAD::IAcadMenuGroup *pMenuGroup; AutoCAD::IAcadPopupMenus *pPopUpMenus; AutoCAD::IAcadPopupMenu *pPopUpMenu; AutoCAD::IAcadPopupMenuItem *pPopUpMenuItem; HRESULT hr = NOERROR; LPUNKNOWN pUnk = NULL; LPDISPATCH pAcadDisp = acedGetIDispatch(TRUE); if(pAcadDisp==NULL) return; hr = pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication,(void**)&pAcad); pAcadDisp->Release(); if (FAILED(hr)) return; pAcad->put_Visible(true); pAcad->get_MenuBar(&pMenuBar); pAcad->get_MenuGroups(&pMenuGroups); pAcad->Release(); long numberOfMenus; pMenuBar->get_Count(&numberOfMenus); pMenuBar->Release(); VARIANT index; VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 0; pMenuGroups->Item(index, &pMenuGroup); pMenuGroups->Release(); pMenuGroup->get_Menus(&pPopUpMenus); pMenuGroup->Release(); WCHAR wstrMenuName[256]; #ifdef UNICODE _tcscpy(wstrMenuName, L"AsdkComAccess"); #else // !UNICODE MultiByteToWideChar(CP_ACP, 0, "AsdkComAccess", -1, wstrMenuName, 256); #endif // !UNICODE // Enables the menu to be loaded/unloaded with the same command. if (!bIsMenuLoaded) { pPopUpMenus->Add(wstrMenuName, &pPopUpMenu); if (pPopUpMenu != NULL) { WCHAR wstrMenuItemName[256]; WCHAR wstrMenuItemMacro[256]; #ifdef UNICODE _tcscpy(wstrMenuItemName, L"&Add A ComCircle"); _tcscpy(wstrMenuItemMacro, L"AsdkComCircle "); #else // !UNICODE MultiByteToWideChar(CP_ACP, 0, "&Add A ComCircle", -1, wstrMenuItemName, 256); MultiByteToWideChar(CP_ACP, 0, "AsdkComCircle ", -1, wstrMenuItemMacro, 256); #endif // !UNICODE VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 0; pPopUpMenu->AddMenuItem(index, wstrMenuItemName, wstrMenuItemMacro, &pPopUpMenuItem); VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 1; pPopUpMenu->AddSeparator(index, &pPopUpMenuItem); #ifdef UNICODE _tcscpy(wstrMenuItemName, L"Auto&LISP Example"); _tcscpy(wstrMenuItemMacro, L"(prin1 \"Hello\") "); #else // !UNICODE MultiByteToWideChar(CP_ACP, 0, "Auto&LISP Example", -1, wstrMenuItemName, 256); MultiByteToWideChar(CP_ACP, 0, "(prin1 \"Hello\") ", -1, wstrMenuItemMacro, 256); #endif // !UNICODE VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 2; pPopUpMenu->AddMenuItem(index, wstrMenuItemName, wstrMenuItemMacro, &pPopUpMenuItem); VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = numberOfMenus - 2; pPopUpMenu->InsertInMenuBar(index); pPopUpMenuItem->Release(); bIsMenuLoaded = true; } else { acutPrintf(_T("\nMenu not created.")); } } else { VariantInit(&index); V_VT(&index) = VT_BSTR; V_BSTR(&index) = wstrMenuName; pPopUpMenus->RemoveMenuFromMenuBar(index); VariantClear(&index); bIsMenuLoaded = false; } pPopUpMenus->Release();}
二 C++基于MFC的
voidaddMenuThroughMfcCom(){ TRY { CAcadApplication IAcad(acedGetAcadWinApp()->GetIDispatch(TRUE)); CAcadMenuBar IMenuBar(IAcad.get_MenuBar()); long numberOfMenus; numberOfMenus = IMenuBar.get_Count(); CAcadMenuGroups IMenuGroups(IAcad.get_MenuGroups()); VARIANT index; VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 0; CAcadMenuGroup IMenuGroup(IMenuGroups.Item(index)); CAcadPopupMenus IPopUpMenus(IMenuGroup.get_Menus()); CString cstrMenuName = _T("AsdkComAccess"); VariantInit(&index); V_VT(&index) = VT_BSTR; V_BSTR(&index) = cstrMenuName.AllocSysString(); IDispatch* pDisp=NULL; //see if the menu is already there TRY{pDisp = IPopUpMenus.Item(index); pDisp->AddRef();} CATCH(COleDispatchException,e){}END_CATCH; if (pDisp==NULL) { //create it CAcadPopupMenu IPopUpMenu(IPopUpMenus.Add(cstrMenuName)); VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 0; IPopUpMenu.AddMenuItem(index, _T("&Add A ComCircle"), _T("_AsdkMfcComCircle ")); VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 1; IPopUpMenu.AddSeparator(index); VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 2; IPopUpMenu.AddMenuItem(index, _T("Auto&LISP Example"), _T("(prin1 \"Hello\") ")); pDisp = IPopUpMenu.m_lpDispatch; pDisp->AddRef(); } CAcadPopupMenu IPopUpMenu(pDisp); if (!IPopUpMenu.get_OnMenuBar()) { VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = numberOfMenus - 2;; IPopUpMenu.InsertInMenuBar(index); } else { VariantInit(&index); V_VT(&index) = VT_BSTR; V_BSTR(&index) = cstrMenuName.AllocSysString(); IPopUpMenus.RemoveMenuFromMenuBar(index); VariantClear(&index); } pDisp->Release(); } CATCH(COleDispatchException,e) { e->ReportError(); e->Delete(); } END_CATCH;}
三 C#基于COM接口
using System;using System.Collections.Generic;using System.Text;using System.Diagnostics;using System.Runtime.InteropServices;using Autodesk.AutoCAD.Interop;using Autodesk.AutoCAD.Interop.Common;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.Runtime;namespace CSharpCOM{ public class Class1 { public Class1() { } [CommandMethod("AM")] public static void AddMenuCom() { AcadApplication app = (AcadApplication)Marshal.GetActiveObject("AutoCAD.Application.17"); AcadMenuBar menuBar = app.MenuBar; AcadMenuGroup menuGroup = app.MenuGroups.Item(0); AcadPopupMenus menus = menuGroup.Menus; AcadPopupMenu mymenu = menus.Add("MyMenu"); mymenu.AddMenuItem(0, "Hello", "hello"); mymenu.AddSeparator(1); mymenu.AddMenuItem(2, "Hello2", "hello"); AcadPopupMenu ext = mymenu.AddSubMenu(3, "Ext"); ext.AddMenuItem(0, "Hello", "hello"); ext.AddSeparator(1); ext.AddMenuItem(2, "Hello2", "hello"); mymenu.InsertInMenuBar(menuBar.Count - 2); } [CommandMethod("hello")] public static void Hello() { AcadApplication app = (AcadApplication)Marshal.GetActiveObject("AutoCAD.Application.17"); app.ActiveDocument.Utility.Prompt("Hello\n"); } }}
四 CSharp基于ACUI.DLL接口的
// Copyright 2005-2007 by Autodesk, Inc.////Permission to use, copy, modify, and distribute this software in//object code form for any purpose and without fee is hereby granted, //provided that the above copyright notice appears in all copies and //that both that copyright notice and the limited warranty and//restricted rights notice below appear in all supporting //documentation.////AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. //AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF//MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. using System;using System.IO;using System.Runtime.InteropServices;using System.Text;using Autodesk.AutoCAD.Runtime;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.EditorInput;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.Customization;namespace CuiSamp{ /// <summary> /// Summary description for Class1. /// </summary> public class CuiSamp { #region members // All Cui files (main/partial/enterprise) have to be loaded into an object of class // CustomizationSection // cs - main AutoCAD CUI file CustomizationSection cs; CustomizationSection entCs; CustomizationSection[] partials; int numPartialFiles; YesNoIgnoreToggle yes = YesNoIgnoreToggle.yes; YesNoIgnoreToggle no = YesNoIgnoreToggle.no; // True when enterprise CUI file is loaded successfully bool entCsLoaded; // ed - access to the AutoCAD Command Line // Allows us to write messages or Issue Commands in the interface Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; #endregion //Default Constructor public CuiSamp() { // retrieve the location of, and open the ACAD Main CUI File string mainCuiFile = (string)Application.GetSystemVariable("MENUNAME"); mainCuiFile += ".cui"; cs = new CustomizationSection(mainCuiFile); string entCuiFile = (string)Application.GetSystemVariable("ENTERPRISEMENU"); if (entCuiFile.Equals(".")) entCsLoaded = false; else { entCs = new CustomizationSection(entCuiFile); entCsLoaded = true; } // Code for loading all partial CUI's listed in the main CUI file partials = new CustomizationSection[cs.PartialCuiFiles.Count]; int i = 0; foreach (string fileName in cs.PartialCuiFiles) { if (File.Exists(fileName)) { partials[i] = new CustomizationSection(fileName); i++; } } numPartialFiles = i; } // Command: savecui // This Command saves all open CUI Files that have been modified [CommandMethod("savecui")] public void saveCui() { // Save all Changes made to the CUI file in this session. // If changes were made to the Main CUI file - save it // If changes were made to teh Partial CUI files need to save them too if (cs.IsModified) cs.Save(); for (int i = 0; i < numPartialFiles; i++) { if (partials[i].IsModified) partials[i].Save(); } if (entCsLoaded && entCs.IsModified) entCs.Save(); // Here we unload and reload the main CUI file so the changes to the CUI file could take effect immediately. //string flName = cs.CUIFileBaseName; //Application.SetSystemVariable("FILEDIA", 0); //Application.DocumentManager.MdiActiveDocument.SendStringToExecute("cuiunload " + flName + " ", false, false, false); //Application.DocumentManager.MdiActiveDocument.SendStringToExecute("cuiload " + flName + " filedia 1 ", false, false, false); //Application.SetSystemVariable("FILEDIA", 1); } // Command: addmenu // This Command adds a new menu to all workspaces called Custom Menu, which contains 2 sub items // The Menu is first added to the Main CUI File and then added to all it's workspaces. [CommandMethod("addmenu")] public void addMenu() { if (cs.MenuGroup.PopMenus.IsNameFree("CustomMenu")) { System.Collections.Specialized.StringCollection pmAliases = new System.Collections.Specialized.StringCollection(); pmAliases.Add("POP12"); PopMenu pm = new PopMenu("CustomMenu", pmAliases, "CustomMenu", cs.MenuGroup); addItemsToPM(pm); addMenu2Workspaces(pm); } else ed.WriteMessage("CustomMenu already Exists\n"); } // Add new Items to a PopMenu private void addItemsToPM(PopMenu pm) { PopMenuItem pmi = new PopMenuItem(pm, -1); pmi.MacroID = "ID_AUGI"; pmi.Name = "Autodesk User Group International"; pmi = new PopMenuItem(pm, -1); pmi = new PopMenuItem(pm, -1); pmi.MacroID = "ID_CustomSafe"; pmi.Name = "Online Developer Center"; } // Add the menu to all the workspaces private void addMenu2Workspaces(PopMenu pm) { foreach (Workspace wk in cs.Workspaces) { WorkspacePopMenu wkpm = new WorkspacePopMenu(wk, pm); wkpm.Display = 1; } } // Command: remmenu // This Command deletes the menu added above from the Main CUI File and any // workspaces that it was added to. [CommandMethod("remmenu")] public void remMenu() { // Find Index of the desired MenuItem // Remove it from all Workspaces that it exists in // Omitting this step leaves nasty left-overs in the Workspace files // Remove it from the Cui files' Menu List PopMenu pm = cs.MenuGroup.PopMenus.FindPopWithAlias("POP12"); if (pm != null) { foreach (Workspace wk in cs.Workspaces) { WorkspacePopMenu wkPm = wk.WorkspacePopMenus.FindWorkspacePopMenu(pm.ElementID, pm.Parent.Name); if (wkPm != null) wk.WorkspacePopMenus.Remove(wkPm); } cs.MenuGroup.PopMenus.Remove(pm); // Deletes the Menu from ACAD Menu Group } } // Command: addtoolbar // Creates a new toolbar called "New Toolbar", and adds it to all workspaces. // This toolbar contains a Toolbar control for named view, button for drawing // a pline, and a flyout that uses the "Draw" tool bar. [CommandMethod("addtoolbar")] public void addToolbar() { Toolbar newTb = new Toolbar("New Toolbar", cs.MenuGroup); newTb.ToolbarOrient = ToolbarOrient.floating; newTb.ToolbarVisible = ToolbarVisible.show; ToolbarControl tbCtrl = new ToolbarControl(ControlType.NamedViewControl, newTb, -1); ToolbarButton tbBtn = new ToolbarButton(newTb, -1); tbBtn.Name = "PolyLine"; tbBtn.MacroID = "ID_Pline"; ToolbarFlyout tbFlyout = new ToolbarFlyout(newTb, -1); tbFlyout.ToolbarReference = "DRAW"; foreach (Workspace wk in cs.Workspaces) { WorkspaceToolbar wkTb = new WorkspaceToolbar(wk, newTb); wk.WorkspaceToolbars.Add(wkTb); wkTb.Display = 1; } } // Command: remtoolbar // This Command removes the toolbar added above from the Main CUI File and any // workspaces that it was added to. [CommandMethod("remtoolbar")] public void remToolbar() { Toolbar tbr = cs.MenuGroup.Toolbars.FindToolbarWithName("New Toolbar"); if (tbr != null) { foreach (Workspace wk in cs.Workspaces) { WorkspaceToolbar wkTb = wk.WorkspaceToolbars.FindWorkspaceToolbar(tbr.ElementID, tbr.Parent.Name); if (wkTb != null) wk.WorkspaceToolbars.Remove(wkTb); } cs.MenuGroup.Toolbars.Remove(tbr); // Deletes the toolbar from ACAD Menu Group } } // Command: cuiall // Issuing this command will run the methods to make all changes to the UI // This will add the custom menu, toolbar, and shortcut, as well as // dock the Properties palette on the right side. [CommandMethod("addcui")] public void AddMenuAndToobar() { addMenu(); addToolbar(); saveCui(); } [CommandMethod("remcui")] public void RemMenuAndToolbar() { remMenu(); remToolbar(); saveCui(); } }}
五 基于中望CAD2014 COM 制作工具栏(By 忘霄)
//引用Interop.ZWCAD(ZWCAD.exe);ZwDatabaseMgd;ZwManagedusing System;using System.Collections.Generic;using System.Drawing;using System.IO;using ToolBar.Properties;using ZWCAD;using ZwSoft.ZwCAD.ApplicationServices;using ZwSoft.ZwCAD.Runtime;[assembly: ExtensionApplication(typeof(ToolBar.MyClass))] //启动时加载工具栏,注意typeof括号里的类库名namespace ToolBar{ public partial class MyClass : IExtensionApplication //注意:重要 { ZcadApplication cadApp = (ZcadApplication)Application.ZcadApplication; // atb = acadApp.MenuGroups.Item("ZWCAD").Toolbars.Add("您自己工具栏的名称"); // //示例atbi = atb.AddToolbarButton(0, "工具栏名称", "帮助", "命令 ", false); // //命令后,紧跟一空格,否则处于等待状态 // atbi = atb.AddToolbarButton(0, "数字文本求和", "数字文本求和", "Sum ", false); // //示例atbi.SetBitmaps(工具栏图片文件路径,工具栏图片文件路径); // atbi.SetBitmaps(acadApp.Path.Trim() + "\\***.bmp", acadApp.Path.Trim() + "\\***.bmp"); // atbi = atb.AddToolbarButton(1, "批量转换", "批量转换", "dwgToPdf ", false); // atbi.SetBitmaps(acadApp.Path.Trim() + "\\***.bmp", acadApp.Path.Trim() + "\\***.bmp"); // //工具栏靠右边停靠 // atb.Dock(ZcToolbarDockStatus.zcToolbarDockRight); // 显示工具栏 // atb.Visible = true; readonly BarItem[] AlDis = new BarItem[] { new BarItem(0, "水平左对齐", "对象水平左对齐:ATL","_ATL ", false, "aligntoleft"), new BarItem(1, "水平居中对齐", "对象水平居中对齐ATC:", "_ATC ", false, "aligntocenter"), new BarItem(2, "水平右对齐", "对象水平右对齐:ATR", "_ATR ", false, "aligntoright"), new BarItem(3, "垂直顶对齐", "对象垂直顶对齐:ALT", "_ALT ", false, "aligntotop"), new BarItem(4, "垂直居中对齐", "对象垂直居中对齐ATM:", "_ATM ", false, "aligntomiddle"), new BarItem(5, "垂直低对齐", "对象垂直低对齐:ATB", "_ATB ", false, "aligntobottom"), new BarItem(6, "水平左分布", "对象水平左分布:HDL", "_HDL ", false, "horizontaldistributionleft"), new BarItem(7, "水平居中分布", "对象水平居中分布:HDC", "_HDC ", false, "horizontaldistributioncenter"), new BarItem(8, "水平右分布", "对象水平右分布:HDR", "_HDR ", false, "horizontaldistributionright"), new BarItem(9, "垂直顶分布", "对象垂直顶分布:VDT", "_VDT ", false, "verticaldistributiontop"), new BarItem(10, "垂直居中分布", "对象垂直居中分布:VDM", "_VDM ", false, "verticaldistributioncenter"), new BarItem(11, "垂直底分布", "对象垂直底分布:VDB", "_VDB ", false, "verticaldistributionBottom"), new BarItem(12, "垂直分布间距", "对象垂直分布间距:VDS", "_VDS ", false, "verticaldistributionspacing"), new BarItem(13, "水平分布间距", "对象水平分布间距:HDS", "_HDS ", false, "horizontaldistributionspacing"), new BarItem(3), new BarItem(7), new BarItem(11), new BarItem(15) }; public void Initialize() { ImgFileInitialization(); CreatToolBar("对齐与分布", AlDis);//启时自动加载工具栏 } public void Terminate() { //throw new NotImplementedException(); } //加载工具栏 public void CreatToolBar(string name, params BarItem[] toolitem) { ZcadMenuGroup currMenuGroup = cadApp.MenuGroups.Item(0); ZcadToolbar newToolBar; try { newToolBar = currMenuGroup.Toolbars.Item("对齐与分布"); } catch { newToolBar = currMenuGroup.Toolbars.Add(name); foreach (BarItem item in toolitem) { ZcadToolbarItem newButton = null; if (item.isbtn) { newButton = newToolBar.AddToolbarButton(item.Index, item.Name, item.HelpString, item.Macro, item.FlyoutButton); newButton.SetBitmaps($"ZwCadToolBarBmp\\{item.SmallIconName}16.bmp", $"ZwCadToolBarBmp\\{item.LargeIconName}32.bmp"); } else { newToolBar.AddSeparator(item.Index); } } currMenuGroup.Save(ZcMenuFileType.zcMenuFileSource); } //工具栏靠右边停靠 //newToolBar.Dock(ZcToolbarDockStatus.zcToolbarDockRight); //显示工具条 if (!newToolBar.Visible) newToolBar.Visible = true; } /// <summary> /// 图片资源初始化 /// </summary> public void ImgFileInitialization() { List<string> zodiaclst = new List<string>() { "aligntobottom16", "aligntobottom32", "aligntocenter16", "aligntocenter32", "aligntoleft16", "aligntoleft32", "aligntomiddle16", "aligntomiddle32", "aligntoright16", "aligntoright32", "aligntotop16", "aligntotop32", "horizontaldistributioncenter16", "horizontaldistributioncenter32", "horizontaldistributionleft16", "horizontaldistributionleft32", "horizontaldistributionright16", "horizontaldistributionright32", "horizontaldistributionspacing16", "horizontaldistributionspacing32", "verticaldistributionBottom16", "verticaldistributionBottom32", "verticaldistributioncenter16", "verticaldistributioncenter32", "verticaldistributionspacing16", "verticaldistributionspacing32", "verticaldistributiontop16", "verticaldistributiontop32" }; string localpath = $"{cadApp.Path}\\Support\\ZwCadToolBarBmp"; Directory.CreateDirectory(localpath); foreach (string str in zodiaclst) { if (!File.Exists($"{localpath}\\{str}.bmp")) { Bitmap btm = (Bitmap)Resources.ResourceManager.GetObject(str, Resources.Culture); btm.Save($"{localpath}\\{str}.bmp"); } } } } public partial class BarItem { public BarItem(object index, bool isbtn = false) { Index = index; this.isbtn = isbtn; } public BarItem(object index, string name, string helpString, string macro, object flyoutButton, string IconName, bool isbtn = true) { Index = index; Name = name; HelpString = helpString; Macro = macro; FlyoutButton = flyoutButton; SmallIconName = IconName; LargeIconName = IconName; this.isbtn = isbtn; } /// <summary> /// 索引值 /// </summary> public object Index { set; get; } /// <summary> /// 名字/提示信息 /// </summary> public string Name { set; get; } /// <summary> /// 说明 /// </summary> public string HelpString { set; get; } /// <summary> /// 执行的命令 /// </summary> public string Macro { set; get; } /// <summary> /// 是否是弹出式按钮 /// </summary> public object FlyoutButton { set; get; } /// <summary> /// 小按钮图片 /// </summary> public string SmallIconName { set; get; } /// <summary> /// 大按钮图片 /// </summary> public string LargeIconName { set; get; } /// <summary> /// 是否是按钮 /// </summary> public bool isbtn { set; get; } }}