AutoCAD二次开发三种添加插件按钮的方法

来源:互联网 发布:php技术文档 编辑:程序博客网 时间:2024/05/20 21:47

在上一篇关于AutoCAD的文章中,我将很多关于CAD的博客相关资源进行了说明,这一篇文章我将介绍如何在AutoCAD中的ribbon中添加相应的按钮。就是下面这种按钮:


CAD按钮


PS:在开发中我们最好使用中英文两个版本同时进行,因为有些时候那些接口或类中的命名和英文版中的名称一样的,这样方便理解!


-----------------------------------------------------分割线------------------------------------------------


开发工具 :VS2010

开发环境 :.Net Framework4.5

开发语言 :C#

AutoCAD版本:2014中/EN


-----------------------------------------------------分割线-----------------------------------------------

第一种:利用.cuix配置文件


如果你是一个CAD的老用户,你会知道这个配置文件,以前是.cui后缀的,新版本从2013开始是.cuix,不过本质上是一个东西;每当你打开AutoCAD的时候,它根据lisp加载的一大堆配置文件就在.cuix中,一般这些配置文件在C盘的隐藏文件夹里面,C:\Users\当前用户名(Administrator?)\AppData\Roaming\Autodesk\AutoCAD 2014\R19.1\chs\Support,不过最重要的是红色方框那个:













这里我们可以自定义一个自己的.cuix文件,然后再CAD中输入cui命令,打开用户自定义窗体,然后你可以将你的自定义文件cuix添加进去:


用户自定义界面













  


这里的mycui文件就是我们自定义的啦,未融入就是之前添加现在路经找不到文件咯!你需要在这个文件中新建自己的按钮:













就是这个东西,多试试你就知道怎么做了,然后给你自定义的按钮添加一个命令宏,也就是你在CAD之中点击这个按钮需要使用的命令,这个命令可以是自己代码写在DLL中加载到CAD中的,也可以是CAD内置的,自定义按钮当然一般是自定义命令啦!


当然你以为这样就行啦,那就错了,现在只是配置文件做好了,下一步我们需要将配置文件刚才弄好的按钮功能添加到ACAD下的功能区—》选项卡—》插件:










接下来你还需要选择工作空间,然后右键选择自定义工作空间(一般我们使用默认工作空间,当然也可以代码设置工作空间),然后将刚才的编辑好的插件添加进去






这样我们就配置好了我们的插件按钮了,最后我们需要输入‘netload’将我们的写好的dll命令添加进来就可以实现按钮互操作了,这里我们每次加载自定义的.cuix之后的操作也可以使用代码实现,我们在VS中安装了AutoCAD的插件开发环境后Autodesk新建项目,在myPlugin.cs这个文件的void IExtensionApplication.Initialize()方法中写入加载.cuix文件的代码,这样每次加载dll就会预先加载cuix文件,那么就不会出现cuix未融入的状态了;然后就是将我们写在cuix中的配置好的按钮添加到主功能区中去!


[csharp] view plain copy
 print?
  1. //使用cuix文件添加对应ribbonbutton  
  2.        //先判断是否添加配置cuix  
  3.        //将配置cuix中的配置功能项添加到acad.cuix中的功能区  
  4.        //刷新工作空间的功能区命令  
  5.        private void AddRibbonButtonByCustomCui()  
  6.        {  
  7.            string mainCuiFile = (string)Application.GetSystemVariable("MENUNAME");  
  8.            mainCuiFile += ".cuix";  
  9.            CustomizationSection csLoad = new CustomizationSection(mainCuiFile);  
  10.            PartialCuiFileCollection pPartialCuiFileCollection = csLoad.PartialCuiFiles;  
  11.            if (pPartialCuiFileCollection.Contains("mycui.cuix"))  
  12.            {  
  13.                System.Windows.Forms.MessageBox.Show("已加载插件!");  
  14.                Application.UnloadPartialMenu(strCuipath);  
  15.                //return;  
  16.            }  
  17.   
  18.            bool isOK = Application.LoadPartialMenu(strCuipath);  
  19.            //加载自定义cui  
  20.            if (!isOK)  
  21.            {  
  22.                System.Windows.Forms.MessageBox.Show("加载自定义配置文件失败!");  
  23.                return;  
  24.            }  
  25.   
  26.            //加载CUI  
  27.            //Application.QuitWillStart += new EventHandler(Application_BeginQuit);  
  28.            //Application.BeginQuit += new EventHandler(Application_BeginQuit);  
  29.            //Autodesk.Windows.ComponentManager.ApplicationMenu.Opening += new EventHandler<EventArgs>(ApplicationMenu_Opening);  
  30.   
  31.            CustomizationSection cs = new CustomizationSection(mainCuiFile);  
  32.            PartialCuiFileCollection cuiFiles = cs.PartialCuiFiles;  
  33.            //acad.cuix配置文件  
  34.            if (cuiFiles.Contains("mycui.cuix"))  
  35.            {//将my.cuix文件中的配置按钮写入acad.cuix文件中去  
  36.                string strPartialCui = cuiFiles.GetFileNameByIndex(cuiFiles.IndexOf("mycui.cuix"));  
  37.                CustomizationSection csCustom = new CustomizationSection(strPartialCui);  
  38.                RibbonPanelSource pRibbonPanelSource = csCustom.MenuGroup.RibbonRoot.FindPanel("RBNU_191_C0DED");//自定义panel中的ElementID  
  39.                RibbonPanelSource pCloneRibbonPanelSource = pRibbonPanelSource.Clone() as RibbonPanelSource;  
  40.                cs.MenuGroup.RibbonRoot.RibbonPanelSources.Add(pCloneRibbonPanelSource);  
  41.   
  42.                RibbonTabSource pRibbonTableSource2 = cs.MenuGroup.RibbonRoot.FindTab("RBN_00012112");//插件Tab的ElementID  
  43.                RibbonPanelSourceReference pRibbonPanelSourceRefrence = new RibbonPanelSourceReference(pRibbonTableSource2);  
  44.                //这一步ID一定要赋值  
  45.                pRibbonPanelSourceRefrence.PanelId = pCloneRibbonPanelSource.ElementID;  
  46.                pRibbonTableSource2.Items.Add(pRibbonPanelSourceRefrence);  
  47.   
  48.                cs.Save();  
  49.                Application.ReloadAllMenus();//否则不现实按钮  
  50.            }  
  51.        }  

最后的按钮效果啦。。。








这一篇主要讲了太多关于配置的流程,大多可以使用手动配置实现,核心是需要自定义的配置文件cuix,然后读取他的命令按钮添加到我们主ribbon中,下两篇将从纯代码开始添加按钮,但是不同的命名空间!



上一篇相关文章主要借助了cuix配置文件来制作插件按钮,但是对于纯码农来说还是喜欢以代码来说话,今天这篇文章就来讲讲纯代码添加按钮。

开发IDE:VS2010

环境:.Net Framework4.0

AutoCAD版本:2014中/EN

今天介绍的代码主要借助的是AcCui.dll这个动态链接库,因为在我的了解中,CAD的开发库中有很多类似的类,又没有相关的介绍API的文档(你不是专业人员真是心累~),都是自己尝试或者在AutoDesk社区中找到的相关内容。

下面先说说思路,再添加核心代码,如果你有需要,欢迎关注我或者联系我,我很愿意与你共享资源与共同学习进步大笑

1.首先还是要找到相关的主cuix文件,就是AutoCAD二次开发三种添加插件按钮的方法之一中介绍的acad.cuix文件(我觉得添加图片排版太不方便了,所以尽量减少图片~);

[csharp] view plain copy
 print?
  1. //获取到ACAD.cuix  
  2. CustomizationSection cs = new CustomizationSection((string)Application.GetSystemVariable("MENUNAME"));  
  3. string strCurWorkspace = (string)Application.GetSystemVariable("WSCURRENT");  
  4. //workspace的操作  
  5. Workspace curWorkspace = cs.getWorkspace(strCurWorkspace);  
  6. if (IsExistPluginTab(ed, curWorkspace))//如果自定义工作空间存在指定的Tab  
  7. {  
  8.     //初始化功能按钮  
  9.     InitialRibbonBtn(ed, cs);  
  10. }  

2.由于我们是需要将按钮添加到‘插件’这个Tab中,而这个Tab是在Ribbon中的(而AutoCAD又是可以自定义是否显示Ribbon的,而且不同的工作空间显示的Ribbon还不同,所以我这里尽量简化了,不讨论那些了),这个Tab的ElementID叫做RBN_00012112,我们可以根据此判断这个Tab是否存在还是被删掉了(默认安装时存在的);这里只讨论存在的咯。  

3.如果存在,我们直接获取到这个Tab,在其中在其中添加一个Panel按钮;

[csharp] view plain copy
 print?
  1. /// <summary>  
  2. /// 在acad.cuix中的(选项卡)Tab中添加panel  
  3. /// </summary>  
  4. /// <param name="cs">acad.cuix的引用</param>  
  5. /// <param name="tabName">Tab的中文名字</param>  
  6. /// <param name="tabEnName">Tab的英文版名称</param>  
  7. /// <param name="panelName">新建的Panel名称(自定义)</param>  
  8. /// <returns></returns>  
  9. private  Autodesk.AutoCAD.Customization.RibbonPanelSource AddRibbonPanelToTab(CustomizationSection cs, string tabName,string tabEnName, string panelName)  
  10. {  
  11.     RibbonRoot root = cs.MenuGroup.RibbonRoot;  
  12.     Autodesk.AutoCAD.Customization.RibbonPanelSourceCollection panels = root.RibbonPanelSources;  
  13.     RibbonTabSource rts = root.FindTab("RBN_00012112");//ElementID  
  14.     if (rts == null)  
  15.     {  
  16.         Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("未找到指定的插件Tab");  
  17.     }  
  18.     if (rts.Name == tabName || rts.Name == tabEnName)  
  19.     {  
  20.         //创建一个panel并添加到panels集合中  
  21.         Autodesk.AutoCAD.Customization.RibbonPanelSource panelSrc = new Autodesk.AutoCAD.Customization.RibbonPanelSource(root);  
  22.         panelSrc.Text = panelSrc.Name = panelName;  
  23.         panelSrc.ElementID = panelSrc.Id = panelName + "_PanelSourceID";  
  24.         panels.Add(panelSrc);  
  25.   
  26.         RibbonPanelSourceReference ribPanelSourceRef = new RibbonPanelSourceReference(rts);  
  27.         ribPanelSourceRef.PanelId = panelSrc.ElementID;  
  28.         rts.Items.Add(ribPanelSourceRef);  
  29.   
  30.         return panelSrc;  
  31.     }  
  32.     return null;  
  33. }  

4.在这个自定义的Panel直接添加按钮,最后重新加载所有menu。

[csharp] view plain copy
 print?
  1. private void InitialRibbonBtn(Editor ed, CustomizationSection cs)  
  2. {  
  3.     Autodesk.AutoCAD.Customization.RibbonPanelSource panelSrc = AddRibbonPanelToTab(cs, "插件""Plug-ins","测试Panel");  
  4.     MacroGroup macGroup = cs.MenuGroup.MacroGroups[0];  
  5.     //int macroCount = cs.MenuGroup.MacroGroups.Count;  
  6.     //foreach (MacroGroup macro in cs.MenuGroup.MacroGroups)  
  7.     //{  
  8.     //    string name = macro.Name;  
  9.     //}  
  10.     RibbonRow row = new RibbonRow();  
  11.     panelSrc.Items.Add((Autodesk.AutoCAD.Customization.RibbonItem)row);  
  12.   
  13.     RibbonCommandButton button1 = new RibbonCommandButton(row);  
  14.     button1.Text = "测试LargeBtn1";  
  15.     MenuMacro menuMac1 = macGroup.CreateMenuMacro("Button1_Macro""^C^CButton1_Command ""Button1_Tag""Button1_Help",  
  16.                         MacroType.Any, "RibbonImages//test16.png""RibbonImages//test32.png""Button1_Label_Id");  
  17.     button1.MacroID = menuMac1.ElementID;  
  18.     button1.ButtonStyle = RibbonButtonStyle.LargeWithText;  
  19.     button1.KeyTip = "Button1 Key Tip";  
  20.     button1.TooltipTitle = "Button1 Tooltip Title!";  
  21.     row.Items.Add((Autodesk.AutoCAD.Customization.RibbonItem)button1);  
  22.   
  23.     RibbonCommandButton button2 = new RibbonCommandButton(row);  
  24.     button2.Text = "测试SmallBtn1";  
  25.     MenuMacro menuMac2 = macGroup.CreateMenuMacro("Button2_Macro""^C^CButton2_Command ""Button2_Tag""Button2_Help",  
  26.                         MacroType.Any, "RibbonImages//test16.png""RibbonImages//test32.png""Button2_Label_Id");  
  27.     button2.MacroID = menuMac2.ElementID;//ID不能少  
  28.     button2.ButtonStyle = RibbonButtonStyle.SmallWithText;  
  29.     button2.KeyTip = "Button2 Key Tip";  
  30.     button2.TooltipTitle = "Button2 Tooltip Title!";  
  31.     row.Items.Add((Autodesk.AutoCAD.Customization.RibbonItem)button2);  
  32.   
  33.     RibbonCommandButton button3 = new RibbonCommandButton(row);  
  34.     button3.Text = "测试LargeBtn3";  
  35.     MenuMacro menuMac3 = macGroup.CreateMenuMacro("Button3_Macro""^C^CButton3_Command ""Button3_Tag""Button3_Help",  
  36.                         MacroType.Any, "RibbonImages//test16.png""RibbonImages//test32.png""Button3_Label_Id");  
  37.     button3.MacroID = menuMac3.ElementID;  
  38.     button3.ButtonStyle = RibbonButtonStyle.LargeWithText;  
  39.     button3.KeyTip = "Button3 Key Tip";  
  40.     button3.TooltipTitle = "Button3 Tooltip Title!";  
  41.     row.Items.Add((Autodesk.AutoCAD.Customization.RibbonItem)button3);  
  42.   
  43.     cs.Save();  
  44.   
  45.     Application.ReloadAllMenus();//重加载所有的按钮  
  46.     ed.WriteMessage("Add buttons successed!");  
  47. }  

最后,效果和第一篇最后的效果是一样的哦!~





再之前两篇的介绍中,无论是第一篇还是第二篇都需要依赖于AutoCAD中的acad.cuix文件,这是写插件所不能容忍的啊!所以这一篇我们不依赖任何的配置,直接加载dll并输入相应的命令即可实现添加命令按钮的操作!这次我们需要使用的dll是AcWindows.dll!~

逻辑如下:

1.如果没有打开Ribbon,控制命令行打开

2.判断当前的Tabs中是否存在同title的Tab,初次加载不会存在的

3.添加Panel并在panel中添加button

[csharp] view plain copy
 print?
  1. private const string New_Tab_ID = "New_Tab_ID";  
  2. private bool PluginAdded = false;//是否已经加载了插件--读取配置文件判断  
  3. [CommandMethod("addplugin")]  
  4. public void AddPlugIn()  
  5. {  
  6.     if (Autodesk.Windows.ComponentManager.Ribbon == null)  
  7.     {//如果Ribbon没有打开,直接操作命令行打开  
  8.         Application.DocumentManager.MdiActiveDocument.SendStringToExecute("_.ribbon\r"truefalsefalse);  
  9.     }  
  10.     if (PluginAdded)  
  11.     {  
  12.         System.Windows.Forms.MessageBox.Show("自定义插件已加载!");  
  13.         return;  
  14.     }  
  15.     bool TabExist = false;//名称为自定义插件的tab是否存在  
  16.     Autodesk.Windows.RibbonControl pRibbonControl = Autodesk.Windows.ComponentManager.Ribbon;  
  17.     foreach (RibbonTab itemTab in pRibbonControl.Tabs)  
  18.     {  
  19.         if (itemTab.Title == "自定义插件Tab")  
  20.         {  
  21.             AddNewPanel(itemTab);  
  22.             TabExist = true;  
  23.         }  
  24.     }  
  25.     if (!TabExist)  
  26.     {  
  27.         RibbonTab newTab = new RibbonTab();  
  28.         newTab.Title = "自定义插件Tab";  
  29.         newTab.Id = New_Tab_ID;  
  30.         pRibbonControl.Tabs.Add(newTab);  
  31.   
  32.         AddNewPanel(newTab);  
  33.   
  34.         newTab.IsActive = true;  
  35.     }  
  36. }  
  37. //添加新的panel  
  38. private void AddNewPanel(RibbonTab newTab)  
  39. {  
  40.     try  
  41.     {  
  42.         Autodesk.Windows.RibbonPanelSource panelSource = new Autodesk.Windows.RibbonPanelSource();  
  43.         panelSource.Title = "自定义插件Panel";  
  44.   
  45.         RibbonPanel newRibbonPanel = new RibbonPanel();  
  46.         newRibbonPanel.Source = panelSource;  
  47.         newTab.Panels.Add(newRibbonPanel);  
  48.   
  49.         Autodesk.Windows.RibbonButton pButton = new Autodesk.Windows.RibbonButton();  
  50.         pButton.Text = "自定义插件button";  
  51.         pButton.ToolTip = "自定义的button1测试";  
  52.         pButton.ShowToolTipOnDisabled = true;  
  53.         pButton.IsToolTipEnabled = true;  
  54.         pButton.Size = RibbonItemSize.Large;  
  55.         pButton.LargeImage = LoadImage(AutoCAD_CSharp_plug_in1_2010.Resource1.test32);  
  56.         pButton.Image = LoadImage(AutoCAD_CSharp_plug_in1_2010.Resource1.test16);  
  57.         pButton.Orientation = System.Windows.Controls.Orientation.Vertical;  
  58.         pButton.ShowText = true;  
  59.         pButton.ShowImage = true;  
  60.         pButton.CommandParameter = "plugincommand ";  
  61.         pButton.CommandHandler = new TestCommandHandler();  
  62.   
  63.         Autodesk.Windows.RibbonButton pRemovePluginButton = new Autodesk.Windows.RibbonButton();  
  64.         pRemovePluginButton.Text = "删除插件按钮";  
  65.         pRemovePluginButton.ToolTip = "自定义的button2测试";  
  66.         pRemovePluginButton.ShowToolTipOnDisabled = true;  
  67.         pRemovePluginButton.IsToolTipEnabled = true;  
  68.         pRemovePluginButton.Size = RibbonItemSize.Standard;  
  69.         pRemovePluginButton.LargeImage = LoadImage(AutoCAD_CSharp_plug_in1_2010.Resource1.test32);  
  70.         pRemovePluginButton.Image = LoadImage(AutoCAD_CSharp_plug_in1_2010.Resource1.test16);  
  71.         pButton.Orientation = System.Windows.Controls.Orientation.Vertical;//小按钮都是横向的,即使设置纵向  
  72.         pRemovePluginButton.ShowImage = true;  
  73.         pRemovePluginButton.ShowText = true;  
  74.         pRemovePluginButton.CommandParameter = "removeplugin ";  
  75.         pRemovePluginButton.CommandHandler = new RemovePluginCommandHandler();  
  76.   
  77.   
  78.         panelSource.Items.Add(pButton);  
  79.         panelSource.Items.Add(pRemovePluginButton);  
  80.     }  
  81.     catch (System.Exception ex)  
  82.     {  
  83.         Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage( Environment.NewLine,ex.Message);  
  84.     }  
  85. }  
  86. //--配置图片  
  87. private System.Windows.Media.Imaging.BitmapImage LoadImage(System.Drawing.Bitmap bitmap)  
  88. {  
  89.     System.IO.MemoryStream ms = new System.IO.MemoryStream ();  
  90.     bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);  
  91.     System.Windows.Media.Imaging.BitmapImage bitImage = new BitmapImage();  
  92.     bitImage.BeginInit();  
  93.     bitImage.StreamSource = ms;  
  94.     bitImage.EndInit();  
  95.     return bitImage;  
  96. }  
每个button都有一个CommandHandler属性,这个就是我们写我们自定义的触发按钮事件的类,继承于System.Windows.Input.ICommand!

至此,三种方式都写完了,这里小结一下。

总体来说这三种方式前两种依赖性较强,依赖于acad.cuix文件,第三种非要说依赖性的话,依赖于Ribbon一定要是打开状态的;第一种的配置文件做好了的话,甚至可以不写代码添加按钮代码就可以实现按钮(但是自定义CommandMethod还是要写的);第二种代码添加按钮写起来较为简便,条理也比较清晰;第三种完全基于代码实现,比较适合纯码农们!也比较适合插件开发的真正实施!亲们喜欢哪种就自己选吧!~



0 0