Addin-Command with Alias in specific work environment

Addin-Command with Alias in specific work environment

bindlmi
Advocate Advocate
1,247 Views
14 Replies
Message 1 of 15

Addin-Command with Alias in specific work environment

bindlmi
Advocate
Advocate

Hi,

I have created my own command via an addin. Now I would like to assign the shortcut “B” to this command. The problem is that “B” is already used by another command (HoleFeature) (see 1. in the picture).

I know that it is possible to assign the same shortcut to multiple commands, as long as they are in different environments (see 2. in the picture).

bindlmi_0-1730379313666.png

 

Can I make my command a “drawing only” command?

0 Likes
Accepted solutions (2)
1,248 Views
14 Replies
Replies (14)
Message 2 of 15

jjstr8
Collaborator
Collaborator

You can use the UserInteraceEvents.OnEnviromentChange event to enable/disable your commands based on the current environment. A disabled command doesn't trigger the extra up/arrow arrow key selection for duplicate shortcuts. There's the added benefit of preventing the "Repeat <last command>" context menu commands from executing when they shouldn't.

0 Likes
Message 3 of 15

bindlmi
Advocate
Advocate

Okay, I think I can attach my code to the event. But what exactly is the “command”? Is that the ButtonDefinition?
If you have a small example of how I can access the environment and disable the command, it would help me a lot. Otherwise, I'll do my own research next week.

 

0 Likes
Message 4 of 15

jjstr8
Collaborator
Collaborator

It's under InventorApplication.CommandManager.ControlDefinitions["command name"].Enabled. InventorApplication is your field/property for the Application object. The command name is the internal name you used in AddButtonDefinition. Here's a C# example. This goes in your ApplicationAddinServer implementation.

private void UserInterfaceEvents_OnEnvironmentChange(Inventor.Environment environment, EnvironmentStateEnum environmentState, EventTimingEnum beforeOrAfter, NameValueMap context, out HandlingCodeEnum handlingCode)
{

    if ((environmentState == EnvironmentStateEnum.kActivateEnvironmentState || environmentState == EnvironmentStateEnum.kResumeEnvironmentState) && beforeOrAfter == EventTimingEnum.kAfter)
    {
        switch (environment.InternalName)
        {
            case "AMxAssemblyEnvironment":
            case "AMxWeldmentEnvironment":
                InventorApplication.CommandManager.ControlDefinitions["myAddin:myAssemblyCmdBtn"].Enabled = true;
                InventorApplication.CommandManager.ControlDefinitions["myAddin:myPartCmdBtn"].Enabled = false;
                break;

            case "PMxPartEnvironment":
            case "MBxSheetMetalEnvironment":
                InventorApplication.CommandManager.ControlDefinitions["myAddin:myAssemblyCmdBtn"].Enabled = false;
                InventorApplication.CommandManager.ControlDefinitions["myAddin:myPartCmdBtn"].Enabled = true;
                break;
            case "FWxMainFrameEnvironment":
            case "DLxDrawingEnvironment":
            case "DXxPresentationEnvironment":
            default:
                InventorApplication.CommandManager.ControlDefinitions["myAddin:myAssemblyCmdBtn"].Enabled = false;
                InventorApplication.CommandManager.ControlDefinitions["myAddin:myPartCmdBtn"].Enabled = false;
        } 
    }
    handlingCode = HandlingCodeEnum.kEventNotHandled;
}

 

Message 5 of 15

WCrihfield
Mentor
Mentor

Hi guys.  Not sure that customize dialog would recognize that you have some code to enable or disable specific commands when specific  environment changes happen.  It seems to me like the following would be the proper way to handle that.

Environment.DisabledCommandList 

DisabledCommandList 

DisabledCommandList.Add 

DisabledCommandList.Remove 

That way the Environment itself knows which ones are not relevant while it is active.

There is also the Environment.DisabledCommandTypes for broader terms.

And you can control the RadialMarkingMenus in that Environment (Environment.RadialMarkingMenus), if you want to make sure a specific command is not in any of them by default, but that should not have anything to do with shortcuts in the customize dialog.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 6 of 15

jjstr8
Collaborator
Collaborator

@WCrihfield - That certainly looks like the cleaner way to do it. I wasn't aware that it existed. I'll have to revisit the way I've been doing it. I may have some commands that conditions other than just the environment.

0 Likes
Message 7 of 15

WCrihfield
Mentor
Mentor

Hi @bindlmi.  I don't know why I did not think of this earlier, but I think I see an even better way to enable the functionality that you are looking for.  The clue is right in the image you posted, but I could not read the words in your image because they are in a language that I can not read.  But basically that one column is named "Category" (in English), and I think I know how to 'control' that.

Under the CommandManager (ThisApplication.CommandManager), is the collection for not only the ControlDefinitions, but also for the CommandCategories.  We can use that CommandCategories collection object to see all existing categories, or add some custom ones.  Then the individual CommandCategory object lets us either see all the commands that are in that category, or Add / Remove a command from it.  It says we can not delete any of the built-in categories, and it says we can not add a 'built-in' command into a custom category, so not entirely as flexible as we may want.  It might be possible to use this route to set / change the category of a command, that way, if the two commands are in different categories, then maybe it will allow the same shortcut.  Just a thought at this point though.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 15

bindlmi
Advocate
Advocate

Hi,
that would be the perfect solution, but I'm afraid it won't work.
I was able to add my command to the CommandCategorey.

            // Create my Drawing-Button
            ButtonDefinition oBtnDef = oCommandManager.ControlDefinitions.AddButtonDefinition(...);
            // Get CommandCategory for Drawings
            CommandCategory cmdCategoryDrawing = oCommandManager.CommandCategories["ucxdrawingmanagercategory"];
            // Add my button to this category
            cmdCategoryDrawing.Add(oBtnDef);

Here you can see the result:

bindlmi_0-1730793022983.png

I had assumed that once my command is in there, Inventor will take care of the “active” commands on its own, but my command is still active in other environments as well 😞

bindlmi_1-1730793081361.png

Should I have done more?
I will test the other suggestions.

 

0 Likes
Message 9 of 15

bindlmi
Advocate
Advocate

Regarding the proposal with the DisabledCommandList:
I looked at the example on the help page and you have to disable the command in all unwanted environments.

bindlmi_0-1730797430382.png

So I tried my best:

            foreach (Inventor.Environment oTempEnv in Plugin.m_inventorApplication.Environments)
            {
                if (oTempEnv.InternalName != "DLxDrawingEnvironment")
                {
                    try
                    {

                        oTempEnv.DisabledCommandList.Add((ControlDefinition)Btn.ButtonDefinition);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Evn: {oTempEnv.DisplayName}\n\n{ex}");
                    }
                }
            }

But I get the following error message:

bindlmi_1-1730797537621.png

I am not sure if the problem is that I am converting my ButtonDefinition to a ControlDefinition.

I think that the DisabledCommandList does not exist... in the VBA editor it looks like this:

bindlmi_2-1730797697268.png

 

0 Likes
Message 10 of 15

bindlmi
Advocate
Advocate
Accepted solution

The proposal with the UserInterfaceEvents:
This works very well, even if it doesn't look as elegant as the other suggestions.
Here is the code for the UserInterfaceEvent:

    public class Plugin : ApplicationAddInServer
    {
        public static Inventor.Application m_inventorApplication;
        public static ControlDefinitions m_ConDefs;
        private UserInterfaceEvents m_UserInterfaceEvents;

        public void Activate(ApplicationAddInSite addInSiteObject, bool firstTime)
        {
            try
            {
                // define globals
                m_inventorApplication = addInSiteObject.Application;
                m_ConDefs = m_inventorApplication.CommandManager.ControlDefinitions;
                m_UserInterfaceEvents = m_inventorApplication.UserInterfaceManager.UserInterfaceEvents;

                // attach to UserInterfaceEvent
                m_UserInterfaceEvents.OnEnvironmentChange += UserInterfaceEvents_OnEnvironmentChange;

            }
            catch
            {
            }

        }

        private void UserInterfaceEvents_OnEnvironmentChange(Inventor.Environment environment, EnvironmentStateEnum environmentState, EventTimingEnum beforeOrAfter, NameValueMap context, out HandlingCodeEnum handlingCode)
        {
            handlingCode = HandlingCodeEnum.kEventNotHandled;

            try
            {
                if ((environmentState == EnvironmentStateEnum.kActivateEnvironmentState || environmentState == EnvironmentStateEnum.kResumeEnvironmentState) && beforeOrAfter == EventTimingEnum.kAfter)
                {
                    switch (environment.InternalName)
                    {
                        // activate my commmand only in drawings
                        case "DLxDrawingEnvironment":
                            m_ConDefs["myDrawingButtonInternalName"].Enabled = true;
                            break;
                        default:
                            m_ConDefs["myDrawingButtonInternalName"].Enabled = false;
                            break;
                    }
                }
            }
            catch
            {
            }
        }

        public void Deactivate()
        {
            m_UserInterfaceEvents.OnEnvironmentChange -= UserInterfaceEvents_OnEnvironmentChange;
        }
	}

Many thanks for your help. If you have any ideas about the other suggestions, I'd be happy to test them.

0 Likes
Message 11 of 15

jjstr8
Collaborator
Collaborator

ButtonDefinition is not derived from ControlDefinition, so you can't cast to it. Get it by name in the ControlDefinitions collection.

 

oTempEnv.DisabledCommandList.Add(Plugin.m_inventorApplication.CommandManager.ControlDefinitions["myDrawingButtonInternalName"]);

 

 

Message 12 of 15

WCrihfield
Mentor
Mentor

Hi @bindlmi.  The 'category' idea was just a 'portion' of the overall process I had in mind, along with the disabled commands list idea.  But honestly add-ins and controlling the scope of an add-in's influence within Inventor are not really my area of expertise.  Judging by the image of the error message, and the line I highlighted below, it appears to be encountering a problem 'getting' the DisabledCommandList for some reason.  Since that property is ReadOnly, that means we can not set another list as its value directly, so the only way to 'add' or 'remove' commands from that list is to 'get' the existing list object first, then use that list to add or remove them, so encountering an error while just getting it does not seem logical.  You may need to enclose it in a Try...Catch...End Try statement.  Or, maybe we can only modify it while that environment is 'active', not sure.

WCrihfield_0-1730815880770.png

Anyways, I'm glad you found something that seems to be working OK for you.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 13 of 15

bindlmi
Advocate
Advocate

Hi,

 

yeah, this seems to be the problem. Even if I change my code as jjstr8 suggested, this line throws the exception:

bindlmi_0-1730816878019.png

 

I also had the same idea to make my own DisabeldCommandList, but I get the following error:

bindlmi_1-1730817002582.png

in english: Cannot create an instance of the abstract class or interface 'interface'.

(I'm not so good with interfaces and abstract classes)

0 Likes
Message 14 of 15

jjstr8
Collaborator
Collaborator

@bindlmi: Use the collection from Plugin.m_inventorApplication.UserInterfaceManager.Environments in your foreach

Message 15 of 15

bindlmi
Advocate
Advocate
Accepted solution

Awesome, that's it! 🙂 And it even works with the ButtonDefinition 😉

            // disable new button in all environments except drawings
            foreach (Inventor.Environment oTempEnv in Plugin.m_inventorApplication.UserInterfaceManager.Environments)
            {
                if (oTempEnv.InternalName != "DLxDrawingEnvironment")
                {
                    try
                    {
                        //ControlDefinition myDrawingCommand = Plugin.m_ConDefs[InternalName];
                        //oTempEnv.DisabledCommandList.Add(myDrawingCommand);
                        oTempEnv.DisabledCommandList.Add((ControlDefinition)Btn.ButtonDefinition);
                    }
                    catch
                    {
                    }
                }
            }