一 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的
void
addMenuThroughMfcCom()
{
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;ZwManaged
using 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; }
}
}