.NET

Reply
Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 1 of 11 (966 Views)
Accepted Solution

Create Toolbar with C#

966 Views, 10 Replies
12-27-2013 12:56 AM

    I have created quite a few AutoCAD commands, but I think it’s a troublesome thing let users remember the shortcuts, I want to create a toolbar for these commands through C# code, I hope someone can provide a simple and detailed tutorial, step by step is the best..


Sincerely thank

Active Contributor
DouceDeux
Posts: 46
Registered: ‎09-04-2012
Message 2 of 11 (935 Views)

Re: Create Toolbar with C#

12-27-2013 09:40 AM in reply to: HelloWorlddd

Toolbars are a big topic. Took me weeks of search and testing to get the following code down. Make of it what you will. Sorry but I'm not explaining it line by line. I encourage you to search the forums, the dev blog and the Through the Interface blog as well.

P.S. the .bmp's are project resourses.

 

public void RLCui()
    {
      //Coded by: Lev Villanueva (doucedeux@gm**l.com)
      
      Document newDocument = Application.DocumentManager.MdiActiveDocument;
      Database newDatabase = newDocument.Database;

      bool exists = false;
      String mainCUI = Application.GetSystemVariable("MENUNAME").ToString() + ".cuix";      
      CustomizationSection mainCS = new CustomizationSection(mainCUI, false);
      String baseFolder = mainCUI.Replace(mainCS.CUIFileBaseName + ".cuix", "");
      PartialCuiFileCollection newPCFC = mainCS.PartialCuiFiles;
      String cuiFileToSend = "\"" + baseFolder + "RL.cuix" + "\"";
      String test1 = mainCUI.Replace(mainCS.CUIFileBaseName + ".cuix", "RL.cuix");
      if (newPCFC.Contains(mainCUI.Replace(mainCS.CUIFileBaseName + ".cuix", "RL.cuix")))
      {
        if( Forms.MessageBox.Show("CUI already exist.\nDelete?", "CUI Exists", Forms.MessageBoxButtons.YesNo, Forms.MessageBoxIcon.Information, Forms.MessageBoxDefaultButton.Button1, 0) == Forms.DialogResult.No)
          return;
        exists = true;
      }

      Rebars.Properties.Resources.RLQUAD_16.Save(baseFolder + "RLQUAD16.bmp");
      Rebars.Properties.Resources.RLQUAD_32.Save(baseFolder + "RLQUAD32.bmp");
      Rebars.Properties.Resources.RLXREF_16.Save(baseFolder + "RLXREF16.bmp");
      Rebars.Properties.Resources.RLXREF_32.Save(baseFolder + "RLXREF32.bmp");
      Rebars.Properties.Resources.RLSI_16.Save(baseFolder + "RLSI16.bmp");
      Rebars.Properties.Resources.RLSI_32.Save(baseFolder + "RLSI32.bmp");
      Rebars.Properties.Resources.RLOSA_16.Save(baseFolder + "RLOSA16.bmp");
      Rebars.Properties.Resources.RLFILTRAR_16.Save(baseFolder + "RLFILTRAR16.bmp");
      Rebars.Properties.Resources.RLEXPORTAR_16.Save(baseFolder + "RLEXPORTAR16.bmp");

      CustomizationSection newCS = new CustomizationSection();
      newCS.MenuGroupName = "RL";
      
      MacroGroup newMG = new MacroGroup("RLMacros", newCS.MenuGroup);

      MenuMacro newMM1 = new MenuMacro(newMG, "RL Xref", "^C^CRLXREF", "ID_RL_Xref");
      newMM1.macro.SmallImage = baseFolder + "RLXREF16.bmp";
      newMM1.macro.LargeImage = baseFolder + "RLXREF32.bmp";
      newMM1.macro.HelpString = "Anexar plano original bajo determinadas especificaciones";
      newMM1.macro.CLICommand = "RLXREF";
      
      MenuMacro newMM2 = new MenuMacro(newMG, "RL Quadrant", "^C^CRLQUAD", "ID_RL_Quad");
      newMM2.macro.SmallImage = baseFolder + "RLQUAD16.bmp";
      newMM2.macro.LargeImage = baseFolder + "RLQUAD32.bmp";
      newMM2.macro.HelpString = "Crear cuadrante relacionado a una losa";
      newMM2.macro.CLICommand = "RLQUAD";

      MenuMacro newMM3 = new MenuMacro(newMG, "RL si", "^C^CRLSI", "ID_RL_si");
      newMM3.macro.SmallImage = baseFolder + "RLSI16.bmp";
      newMM3.macro.LargeImage = baseFolder + "RLSI32.bmp";
      newMM3.macro.HelpString = "Dibujar refuerzos tipo s e i de una losa";
      newMM3.macro.CLICommand = "RLSI";

      MenuMacro newMM4 = new MenuMacro(newMG, "RLosa", "^C^CRLOSA", "ID_RLOSA");
      newMM4.macro.SmallImage = baseFolder + "RLOSA16.bmp";
      newMM4.macro.HelpString = "Crear refuerzos de losa";
      newMM4.macro.CLICommand = "RLOSA";

      MenuMacro newMM5 = new MenuMacro(newMG, "RL Filtrar", "^C^CRLFILTRAR", "ID_RLFILTRAR");
      newMM5.macro.SmallImage = baseFolder + "RLFILTRAR16.bmp";
      newMM5.macro.HelpString = "Filtrar de entre los refuerzos de losa para su visualización en el plano";
      newMM5.macro.CLICommand = "RLFILTRAR";

      MenuMacro newMM6 = new MenuMacro(newMG, "RL Exportar", "^C^CRLEXPORTAR", "ID_RLEXPORTAR");
      newMM6.macro.SmallImage = baseFolder + "RLEXPORTAR16.bmp";
      newMM6.macro.HelpString = "Exportar refuerzos a archivos de Excel. Se pedirá un nombre para el archivo.";
      newMM6.macro.CLICommand = "RLEXPORTAR";
      
      Toolbar newT = new Toolbar("RL", newCS.MenuGroup);
      ToolbarButton newButton1 = new ToolbarButton("ID_RL_Xref", "RL Xref", newT, -1);
      ToolbarButton newButton2 = new ToolbarButton("ID_RL_Quad", "RL Quadrant", newT, -1);
      ToolbarButton newButton3 = new ToolbarButton("ID_RL_si", "RL si", newT, -1);
      ToolbarButton newButton4 = new ToolbarButton("ID_RLOSA", "RLosa", newT, -1);
      newButton4.DrawSeparator = true;
      ToolbarButton newButton5 = new ToolbarButton("ID_RLFILTRAR", "RL Filtrar", newT, -1);
      ToolbarButton newButton6 = new ToolbarButton("ID_RLEXPORTAR", "RL Exportar", newT, -1);

      newT.ToolbarItems.Add(newButton2);
      newT.ToolbarItems.Add(newButton1);
      newT.ToolbarItems.Add(newButton3);
      newT.ToolbarItems.Add(newButton4);
      newT.ToolbarItems.Add(newButton5);
      newT.ToolbarItems.Add(newButton6);

      StringCollection newSC = new StringCollection();
      int i = 1;
      for (; i < mainCS.MenuGroup.PopMenus.AllAliases.Count; i++)
      {
        if (!mainCS.MenuGroup.PopMenus.AllAliases.Contains("POP" + i.ToString()))
          break;
      }

      newSC.Add("POP" + i.ToString());
      PopMenu newPopMenu = new PopMenu("RL Menu", newSC, "ID_RLPop"   , newCS.MenuGroup);
      PopMenuItem newPMI1 = new PopMenuItem(newMM1, "RL Xref"    , newPopMenu, -1);
      PopMenuItem newPMI2 = new PopMenuItem(newMM2, "RL Quadrant", newPopMenu, -1);
      PopMenuItem newPMI3 = new PopMenuItem(newMM3, "RL si"      , newPopMenu, -1);
      PopMenuItem newPMI4 = new PopMenuItem(newMM4, "RLosa"      , newPopMenu, -1);      
      PopMenuItem newPMI5 = new PopMenuItem(newMM5, "RL Filtrar" , newPopMenu, -1);
      PopMenuItem newPMI6 = new PopMenuItem(newMM6, "RL Exportar", newPopMenu, -1);
      
      newCS.SaveAs(baseFolder + "RL.cuix");
      


      File.Delete(baseFolder + "RLQUAD16.bmp");
      File.Delete(baseFolder + "RLQUAD32.bmp");
      File.Delete(baseFolder + "RLXREF16.bmp");
      File.Delete(baseFolder + "RLXREF32.bmp");
      File.Delete(baseFolder + "RLSI16.bmp");
      File.Delete(baseFolder + "RLSI32.bmp");
      File.Delete(baseFolder + "RLOSA16.bmp");
      File.Delete(baseFolder + "RLFILTRAR16.bmp");
      File.Delete(baseFolder + "RLEXPORTAR16.bmp");           

      Directory.CreateDirectory(baseFolder + "Extended Help");
      System.IO.File.WriteAllText(baseFolder + @"Extended Help\RLEH.xaml", Rebars.Properties.Resources.RLEH);
      Directory.CreateDirectory(baseFolder + @"Extended Help\Images");
      Rebars.Properties.Resources.EH_RLXREF.Save(baseFolder + @"Extended Help\Images\" + "EH_RLXREF.png");
      Rebars.Properties.Resources.EH_RLQUAD.Save(baseFolder + @"Extended Help\Images\" + "EH_RLQUAD.png");
      Rebars.Properties.Resources.EH_RLSI.Save(baseFolder + @"Extended Help\Images\" + "EH_RLSI.png");

      //File.Copy(baseFolder + "RL.cuix", baseFolder + "RL.zip", true);
      
      //Directory.CreateDirectory(baseFolder + "Temp");

      using (ZipFile newZF = new ZipFile(baseFolder + "RL.cuix"))
      {
        ZipEntry newZE = newZF["MenuGroup.cui"];
        newZE.Extract(baseFolder, ExtractExistingFileAction.OverwriteSilently);


        FileStream oldFS = new FileStream(baseFolder + "MenuGroup.cui", FileMode.Open, FileAccess.Read);
        FileStream newFS = new FileStream(baseFolder + "temp.cui", FileMode.Create, FileAccess.Write);
        StreamReader oldSR = new StreamReader(oldFS);
        StreamWriter newSW = new StreamWriter(newFS);
        String line;

        for (int j = 1; j <= 3; j++)
        {
          do
          {
            line = oldSR.ReadLine();
            if (line == null) break;
            newSW.WriteLine(line);
          } while (!line.Contains(@"<CLICommand"));

          if (line != null)
          {
            newSW.WriteLine(@"<ToolTip>");
            newSW.WriteLine(@"<ExtendedContent UriSource=""" + baseFolder + @"Extended Help\RLEH.xaml"" SourceKey=""RLEH_CMD_00" + j.ToString() + @""" />""");
            newSW.WriteLine(@"</ToolTip>");
          }
        }

        while ((line = oldSR.ReadLine()) != null)
          newSW.WriteLine(line);

        newSW.Dispose();
        oldSR.Dispose();
        oldFS.Dispose();
        newFS.Dispose();

        File.Delete(baseFolder + "MenuGroup.cui");
        System.IO.File.Move(baseFolder + "temp.cui", baseFolder + "MenuGroup.cui");
        newZF.RemoveEntry("MenuGroup.cui");
        newZF.AddFile(baseFolder + "MenuGroup.cui", @"\");
        newZF.Save();
        //System.IO.File.Move(baseFolder + "temp.zip", baseFolder + "RL.cuix");
        File.Delete(baseFolder + "MenuGroup.cui");
      }

      object oldCmdEcho = Application.GetSystemVariable("CMDECHO");
      object oldFileDia = Application.GetSystemVariable("FILEDIA");
      Application.SetSystemVariable("CMDECHO", 0);
      Application.SetSystemVariable("FILEDIA", 0);
      if (exists)
        newDocument.SendStringToExecute("_.cuiunload " + "RL" + " ", false, false, false);

      newDocument.SendStringToExecute("_.cuiload " + cuiFileToSend + " ", false, false, false);
      newDocument.SendStringToExecute("(setvar \"FILEDIA\" " + oldFileDia.ToString() + ")(princ) ", false, false, false);
      newDocument.SendStringToExecute("(setvar \"CMDECHO\" " + oldCmdEcho.ToString() + ")(princ) ", false, false, false);

 

Valued Mentor
joantopo
Posts: 645
Registered: ‎04-25-2010
Message 3 of 11 (924 Views)

Re: Create Toolbar with C#

12-27-2013 12:38 PM in reply to: DouceDeux

Read this:

http://forums.autodesk.com/autodesk/attachments/autodesk/152/26712/1/CP205-2_Mike_Tuersley.pdf

 

You can change VB.Net to C# with a conversor:

http://www.developerfusion.com/tools/convert/vb-to-csharp/

Autocad Civil 3D 2014 +SP1 // Civil 3D 2015
Quad Core Intel i7 3770-cpu 3.40Ghz.
ssd samsung 840 pro 512gb+ssd samsung 840 pro 256 gb+1tb hdd
32gb RAM 1600 Mhz.
nVidia Quadro 2000.
Win 7 Pro 64bit

Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 4 of 11 (900 Views)

Re: Create Toolbar with C#

12-28-2013 09:07 AM in reply to: joantopo

   I don’t want a Docking Palette, just Toolbar

   For example, draw a line, there is sample code, so I study it will be very convenient
   There also should be sample code for how to creat a very simple Toolbar, and have a button, and the button can execute a esay function, just like output a string.
   I hope to find a such sample code, then I can start easily


   Sincerely thanks

 

Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 5 of 11 (891 Views)

Re: Create Toolbar with C#

12-28-2013 09:45 AM in reply to: HelloWorlddd

ToolBar.PNG

 

  Just like this Toolbar, First I want to know how to creat a simplest toolbar that just have one button, click this button just output "Hello"

 I need more help, clear and easy, thanks

 

Mentor
SENL1362
Posts: 150
Registered: ‎07-20-2011
Message 6 of 11 (888 Views)

Re: Create Toolbar with C#

12-28-2013 09:51 AM in reply to: HelloWorlddd
Any reason why not creating a Ribbon Panel?
The Toolbar technology is a relic from the old days.
You find more samples creating Ribbon style menu's.
Valued Mentor
jeff
Posts: 322
Registered: ‎05-12-2009
Message 7 of 11 (875 Views)

Re: Create Toolbar with C#

12-28-2013 11:33 AM in reply to: SENL1362

Just create a partial CUI and create your commands then you can just drag them on Ribbon Panels, Menus, Toolbars, etc.......

 

cui.PNG

 

 

 

 

 

 

acadcui.PNG

 

 

 

 

 

 

 

 

 

 

 

 

You can also find your answers @ TheSwamp
Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 8 of 11 (814 Views)

Re: Create Toolbar with C#

12-31-2013 06:48 AM in reply to: jeff

   I hope interface and functionality together, but as I demonstrate below, I only know a way to separate treatment. I want to some friends can help me

 

   Achieve functional

   Below is a very simple command written in C #, Just only need be compiled into dll file, and then enter NETLOAD load the dll file from AutoCAD, and enter HW from a command prompt, it will output “Hello World”

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
[assembly: CommandClass(typeof(MyNameSpace.HelloWorld))]
namespace MyNameSpace
{
class HelloWorld
    {
        [CommandMethod("HW")]
        public void hello()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            acDoc.Editor.WriteMessage("\nHello World");
        }
    }
}

 

   Automatically loaded

   Below method copy from AutoCAD. NET Developer's Guide directly,It let the program to get automatic loading function

public void RegisterMyApp()
{
  string sProdKey = HostApplicationServices.Current.RegistryProductRootKey;
  string sAppName = "MyApp";
  RegistryKey regAcadProdKey = Registry.CurrentUser.OpenSubKey(sProdKey);
  RegistryKey regAcadAppKey = regAcadProdKey.OpenSubKey("Applications", true);
  string[] subKeys = regAcadAppKey.GetSubKeyNames();
  foreach (string subKey in subKeys)
  {
      if (subKey.Equals(sAppName))
      {
          regAcadAppKey.Close();
          return;
      }
  }
  string sAssemblyPath = Assembly.GetExecutingAssembly().Location;
  RegistryKey regAppAddInKey = regAcadAppKey.CreateSubKey(sAppName);
  regAppAddInKey.SetValue("DESCRIPTION", sAppName, RegistryValueKind.String);
  regAppAddInKey.SetValue("LOADCTRLS", 14, RegistryValueKind.DWord);
  regAppAddInKey.SetValue("LOADER", sAssemblyPath, RegistryValueKind.String);
  regAppAddInKey.SetValue("MANAGED", 1, RegistryValueKind.DWord);
  regAcadAppKey.Close();
}

 

 

   Interface Design

   Now I know how to creat commands, how to load, how to load automatically, and finally I intend to design an interface
   But the only way I know is to create . cuix file by Customize User Interface Editor ,add toolbar, buttons, icons, and macros as shown below

Customize User Interface Editor.PNG

 

   I recall myToolbar, then click the only button with mouse, the program is executed HW command as follows

nameSpace.PNG

 

   but there is a problem, the interface file. cuix and functional document .dll are two files, the user needs to load separately, do not feel good

 

 

 

  I'm wondering how I deal with the above problems
   I think there should be a conventional method, possibly, using C # code to achieve the interface and achieve the functional at the same time, and finally compiled into olny one .dll file
   If, as I suspect, and I hope I can find some C # code
   Sincerely thanks

 

 

Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 9 of 11 (786 Views)

Re: Create Toolbar with C#

01-01-2014 04:42 AM in reply to: HelloWorlddd

   I think I found a solution,
   If anyone encountered this problem
   Can refer to
   http://through-the-interface.typepad.com/through_the_interface/2007/05/creating_a_part.html

Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 10 of 11 (780 Views)

Re: Create Toolbar with C#

01-01-2014 07:43 AM in reply to: HelloWorlddd

   Function create by C #, and then compiled into dll files, functions automatically loaded by RegisterMyApp() , it’s referenced from AutoCAD. NET Developer's Guide,then the command will auto load very time.

 

   User interface design by Customize User Interface Editor, and then save as .cuix file, load the user interface using the following code, in fact, equivalent to input CUILOAD in command prompt, but this CUILOAD need only be entered once, it does not need to load very time

 

   Here is the way I take, they can be set simultaneously, only one time, perhaps there is a better way, but now I only know this way

 

RegisterMyApp()
{
_cuiload
}

 

UnRegisterMyApp()
{
_cuiunload
}

 the following code is copy form http://forums.autodesk.com/t5/NET/Accessing-toolbars-and-buttons-programatically/m-p/3182594/highlig...

string flName = csGavin.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);

 

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community