How to initialize custom ribbon bar at startup

How to initialize custom ribbon bar at startup

ebo134
Advocate Advocate
9,268 Views
7 Replies
Message 1 of 8

How to initialize custom ribbon bar at startup

ebo134
Advocate
Advocate

Hi everyone

I created a Net dll plugin and successfully loaded in Civil 3d 2014 with NetLoad command, the plugin contains a ribbon bar with a ribbon button launching a dialog.., but when To be Loaded automatically (by AutoLoader) at startup it did'nt load, is there any way to make it load automatically at Civil 3d start up

 

Thanks

 

 

 

here its my ContentPackage.xml 

<?xml version="1.0" encoding="utf-8"?>
<ApplicationPackage SchemaVersion="1.0" AppVersion = "3.0" ProductCode = "{E74E298D-D430-4100-83D0-CA230BB00A41}">
  <CompanyDetails Name="ESOL Engineering Bureau" Phone=" " Url=" " Email="eng.ims134@gmail.com" />
  <RuntimeRequirements Platform="AutoCAD|AutoCAD*" OS="Win32|Win64" />
  <Components>
    <RuntimeRequirements OS="Win32|Win64" Platform="AutoCAD|AutoCAD*" SeriesMin="R19.0" SeriesMax="R19.1" />
    <ComponentEntry AppName="SurfaceTool" Version="3.0" ModuleName="./Contents/SurfaceTool.dll" AppDescription="Surface Tools Plugin" LoadOnAutoCADStartup="True" />    
    </ComponentEntry>
  </Components>
</ApplicationPackage>

 and my Code (main file):

 

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Media.Imaging;

//civil 3d assemblies
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.Civil;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
//for ribbon controls
using Autodesk.Windows;


namespace SurfaceTool
{
    public class SEXPORT: IExtensionApplication
    {
        Editor ed;
        [CommandMethod("ims_surf")]
        public void ims_surf()
        {
            SurfaceTool stool = new SurfaceTool();
            stool.Display();
        }


        #region Initializing and termination members
        public void Initialize()
        {
            //ed = appy.DocumentManager.MdiActiveDocument.Editor;
            //ed.WriteMessage("\n This is Created By ESOL Engineering Buruea \nType EXPS and hit Enter Key for using the tool");
            ////throw new NotImplementedException(); 
            //if (Autodesk.Windows.ComponentManager.Ribbon == null)
            //{
            //    //load the custom Ribbon on startup, but at this point
            //    //the Ribbon control is not available, so register for
            //    //an event and wait
            //    Autodesk.Windows.ComponentManager.ItemInitialized +=
            //        new EventHandler<RibbonItemEventArgs>
            //          (ComponentManager_ItemInitialized);
            //}
            //else
            //{
            //    //the assembly was loaded using NETLOAD, so the ribbon
            //    //is available and we just create the ribbon
            //    cr();
            //}
            cr();
            Autodesk.AutoCAD.ApplicationServices.Application.SystemVariableChanged += TrapWSCurrentChange;
        }

        private void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e)
        {
            //now one Ribbon item is initialized, but the Ribbon control
            //may not be available yet, so check if before
            if (Autodesk.Windows.ComponentManager.Ribbon != null)
            {
                //ok, create Ribbon
                cr();
                //and remove the event handler
                Autodesk.Windows.ComponentManager.ItemInitialized -=
                    new EventHandler<RibbonItemEventArgs>
                      (ComponentManager_ItemInitialized);
            }

        }

        //solving workspace changing
        public void TrapWSCurrentChange(object sender, Autodesk.AutoCAD.ApplicationServices.SystemVariableChangedEventArgs e)
        {
            if (e.Name.Equals("WSCURRENT"))
            {
                cr();
            }
        }

        public void cr()
        {
            RibbonTab tab1 = CreateRibbon("ESOL Tool");
            if (tab1 == null)
            {
                return;
            }

            RibbonPanelSource rpannel = CreateButtonPannel("ESOL Tool", tab1);
            if (rpannel == null)
            {
                return;
            }


            RibbonButton b1 = CreateButton("Surface Tool", "ims_surf", "SurfaceTool.SurfaceIcon.png", rpannel);
            //RibbonButton b2 = CreateButton("Profile Tool", "EXP1", "RibbonInCivil.Profile.png", rpannel);



        }


        public void Terminate()
        {
            //throw new NotImplementedException();
            ed.WriteMessage("\n --------------------");
        }

        private RibbonTab CreateRibbon(string str)
        {
            //1. Create ribbon control
            RibbonControl rc = ComponentManager.Ribbon;
            //2. Create ribbon tab
            RibbonTab rt = new RibbonTab();
            //3. ribbon tab information assignment
            rt.Title = str;
            rt.Id = str;

            //4. add ribbon tab to the ribbon control's tab
            rc.Tabs.Add(rt);
            //5. optional: set ribbon tab active
            rt.IsActive = true;
            return rt;
        }

        private RibbonPanelSource CreateButtonPannel(string str, RibbonTab rtab)
        {
            //1. Create  panel source
            RibbonPanelSource bp = new RibbonPanelSource();

            //3. ribbon panel source information assignment
            bp.Title = str;
            //4. create ribbon pannel
            RibbonPanel rp = new RibbonPanel();
            //4. add ribbon pannel to the ribbon pannel source
            rp.Source = bp;
            //5. add ribbon pannel to the tobs
            rtab.Panels.Add(rp);
            return bp;

        }

        private RibbonButton CreateButton(string str, string CommandParameter, string pngFile, RibbonPanelSource rps)
        {
            //1. Create  Button
            RibbonButton button = new RibbonButton();


            //3. ribbon panel source information assignment
            button.Text = str;
            button.Id = str;
            button.CommandParameter = CommandParameter; // name of the command
            button.ShowImage = true;
            button.ShowText = true;
            button.Size = RibbonItemSize.Large;

            button.Orientation = Orientation.Vertical; // from system.windows.controls

            //if(Utilities134.LoadPNGImageFromResource("logo.png") != null)
            //    button.LargeImage = Utilities134.LoadPNGImageFromResource("logo.png");
            //else
            //    if (Utilities134.LoadPNGImageFromResource("rib134.logo.png") != null)
            button.LargeImage = Utilities134.LoadImage(pngFile);

            // 4. to add command to the button write the line below
            button.CommandHandler = new AdskCommandHandler();

            //5. add ribbon button pannel to the ribbon pannel source
            rps.Items.Add(button);
            return button;

        }

        private RibbonButton CreateButton1(string str, string CommandParameter, string pngFile, RibbonPanelSource rps)
        {
            //1. Create  Button
            RibbonButton button = new RibbonButton();


            //3. ribbon panel source information assignment
            button.Text = str;
            button.CommandParameter = CommandParameter; // name of the command
            button.Orientation = Orientation.Vertical; // from system.windows.controls
            button.Size = RibbonItemSize.Large;
            //button.LargeImage = LaodImage("imageName.ext");
            button.ShowImage = false;
            button.ShowText = true;
            //button.LargeImage = Utilities134.LoadPNGImageFromResource("logo.png");
            // 4. to add command to the button write the line below
            button.CommandHandler = new AdskCommandHandler();
            button.LargeImage = Utilities134.LoadImage(pngFile);

            //5. add ribbon button pannel to the ribbon pannel source
            rps.Items.Add(button);
            return button;

        }

        #endregion
    }
    public class AdskCommandHandler : System.Windows.Input.ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            //is from a Ribbon Button?
            RibbonButton ribBtn = parameter as RibbonButton;
            if (ribBtn != null)
            {
                string cmdName = (String)ribBtn.CommandParameter;

                // remove all empty spaces and add
                // a new one at the end.
                cmdName = cmdName.TrimEnd() + " ";

                // execute the command using command prompt
                Application.DocumentManager.MdiActiveDocument.
                  SendStringToExecute(cmdName,
                  true, false, true);
            }
        }
    }

    public class Utilities134
    {
        //checking of Civil 3d existence
        public static bool IsCivil3D
        {
            get
            {
                return (HostApplicationServices.Current.UserRegistryProductRootKey.Contains("000"));
            }
        }

        public static System.Windows.Media.ImageSource LoadImage(string name)
        {
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.StreamSource = GetEM(name);
            bi.EndInit();
            return bi;

        }
        public static Stream GetEM(string rname)
        {
            return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(rname);
        }


        //Native function
        #region PInvoke to avoid 'Not Responding' status

        /// <summary>
        /// Process Windows messages to avoid 'Not Responding' state
        /// </summary>
        public static void AvoidNotResponding()
        {
            Utilities134.NativeMessage msg;
            Utilities134.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
        }

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        private struct NativeMessage
        {
            public IntPtr handle;
            public uint msg;
            public IntPtr wParam;
            public IntPtr lParam;
            public uint time;
            public System.Drawing.Point p;

        }

        // We won't use this maliciously
        [System.Security.SuppressUnmanagedCodeSecurity]
        [System.Runtime.InteropServices.DllImport("User32.dll",
          CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        private static extern bool PeekMessage(out NativeMessage msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);

        #endregion
    }
}

 

 

0 Likes
Accepted solutions (1)
9,269 Views
7 Replies
Replies (7)
Message 2 of 8

michael_robertson
Collaborator
Collaborator

We do the same thing via a custom startup shortcut that points to an script (scr) file that net loads the ribbon dll (make sure the path to the dll folder is in both the support & trusted folder variables).

 

In your startup shortcut use the command "/b c:\myfolder\startup.scr" (the /b switch stands for batch and runs the script)

 

In your script file you would have something like:

netload myribbon.dll

 

If your ribbon is loaded in your extension applications initialize method you are good to go, if your ribbon is loaded via a command then just add your ribbon startup command in the script.

 

 

I believe you may be able to do this via either CUI or ACad.lsp also but the scr way was easier to maintain and less likely to step on other profiles for our situation.

We prefer not to load our applications via auto-register/startup because they are specific to doing work for our deliveries and make no sense outside our profile.

Mike Robertson
FL. Dept. of Transportation
CADD Applications Developer
0 Likes
Message 3 of 8

ebo134
Advocate
Advocate

thank you for your reply

but first I want to distribute my plugin in future, I need to know this method of loading of plugin (and its the best way)

second I do not know how to make this script in detail, please can you explain more about it or guide me through a resource link

 

 

thanks

 

0 Likes
Message 4 of 8

michael_robertson
Collaborator
Collaborator

I guess the first question, is your plugin designed for general C3D usage or should it only be used along with a specific profile?

 

If a specific profile you can use the script method I provided. A script file is just a text file with a .scr extension, the file just contains Autocad commands. You can point to the script file from a profile specific shourtcut.

 

I work for FDOT and our tools are programmed around using our specific resources and we don't want them loaded outside our profile so here is our profile startup command:

"C:\Program Files\Autodesk\Autodesk AutoCAD Civil 3D 2014\acad.exe" /ld "C:\Program Files\Autodesk\Autodesk AutoCAD Civil 3D 2014\AecBase.dbx" /p "C:\FDOT2014.C3D\Support\Profiles\FDOT2014C3D.arg" /b "C:\FDOT2014.C3D\support\profiles\fdot.scr" /nologo /nossm

 

The actual contents of our scr file is: (note the "fdotribbon" command at the end loads our ribbon).

netload layersync.dll
netload ADNPlugin-OffsetInXref.dll
netload AssemblyLabelToggle.dll
AssemblyLabelToggle
filedia 1
fdotribbon

 

If you want your program available for general use here's a "Through The Interface" article:

http://through-the-interface.typepad.com/through_the_interface/2006/09/automatic_loadi.html

 

Or you could use the Autoloader:

http://adndevblog.typepad.com/autocad/2013/01/autodesk-autoloader-white-paper.html

 

 

Mike Robertson
FL. Dept. of Transportation
CADD Applications Developer
0 Likes
Message 5 of 8

Anonymous
Not applicable

Hi,

 

I would suggest to check this 'Autoloader' technology from Autodesk -

 

http://adndevblog.typepad.com/autocad/2013/01/autodesk-autoloader-white-paper.html

 

Does it help ?

 

Thanks,

 

0 Likes
Message 6 of 8

ebo134
Advocate
Advocate
Accepted solution

Thank you guys, I solved my problem, I'd forgotten that I was comment out a part of my code:

 

//if (Autodesk.Windows.ComponentManager.Ribbon == null)
            //{
            //    //load the custom Ribbon on startup, but at this point
            //    //the Ribbon control is not available, so register for
            //    //an event and wait
            //    Autodesk.Windows.ComponentManager.ItemInitialized +=
            //        new EventHandler<RibbonItemEventArgs>
            //          (ComponentManager_ItemInitialized);
            //}
            //else
            //{
            //    //the assembly was loaded using NETLOAD, so the ribbon
            //    //is available and we just create the ribbon
            //    cr();
            //}

 this part of code is important for loading the ribbon at start up, and finally I commentted out a line after the code above which it is (cr();).

Now it works good

 

thanks

0 Likes
Message 7 of 8

Anonymous
Not applicable

There is a little error in your even handler when you try to remove the event handler, I think:

 

               Autodesk.Windows.ComponentManager.ItemInitialized -=
                    new EventHandler<RibbonItemEventArgs>
                      (ComponentManager_ItemInitialized);
 

 

To remove the _existing_ event handler, which is already created, you want this:

 

               Autodesk.Windows.ComponentManager.ItemInitialized -=
                    ComponentManager_ItemInitialized;
 
0 Likes
Message 8 of 8

andrew_demerchant
Enthusiast
Enthusiast
Any idea how to do this in vb.net? Also, where would this code go - is this in the Initialize function, or somewhere else?
0 Likes