Community
Showing results for 
Search instead for 
Do you mean 
Reply

Custom Menu Facts and Caveats

Copper Contributor
Posts: 14
Country: United States

Custom Menu Facts and Caveats

Experienced developers probably already know this, but here's some findings for the unwary  (we've had a workaround for this "problem" in our code for several years -- until this week!).  The ACT sample code (for a Custom Menu) contains code to look for and remove an existing custom menu item (matching URN) prior to installing the custom menu item.  We echoed this code because we found that our custom menu item would often already be present at the next ACT application launch.  Not anymore -- puzzle finally solved!

 

Lesson learned: When adding and removing custom menu buttons to the ACT menu bar (in a Plugin), be sure to always refresh your references to the active menu bar (CommandBar)  and parent menu control (CommandBarControl) prior to performing install and uninstall operations on those objects.  Custom menu(s) items are typically installed during Logon and Logoff events (e.g., AfterLogon and BeforeLogoff).   Such a Plugin may go through several cycles of installing and uninstalling your menu if the user logs in and out of multiple databases during a single ACT session.

 

We had a problem in that we were holding a reference to the Parent menu control (the host for our custom menu item) from the time we installed our custom menu to the time we uninstalled it.  The problem is that ACT apparently reconstructs the parent menu control at some point after a new child (custom menu item) is added to the parent control.  So, using the same parent reference at time of menu uninstall does not perform as expected (because it does not actually refer to the real parent object).  Using a saved reference will appear to uninstall the custom menu, but in fact will leave a lingering DotNetBar BaseItem still in memory.  This results in multiple instances of your custom menu item appearing in the menu (if you re-install multiple times during a session) and, sometimes, serialization of the custom menu instance when the application ultimately exits (in which case, the custom menu is automatically installed the next time the ACT application is launched. 

 

Fetching a fresh reference to the parent control in both your Install and Uninstall routines will ensure you are working with the correct (active) object and will keep everything neat and tidy in memory.

 

Code examples:

 

public void InstallMenu(string parentURN, CommandBarButton myCustomMenuItem)
{
    int index = _actApp.Explorer.FindCommandBarIndex(CommandBarType.Menubar);
    CommandBar currentMenuBar = _actApp.Explorer.CommandBarCollection[index];
    CommandBarControl parentControl = currentMenuBar.ControlCollection[parentURN];
    parentControl.AddSubItem(myCustomMenuItem, desiredPosition);
}

 

public void UninstallMenu(string parentURN, CommandBarButton myCustomMenuItem)
{
    // retrieve a fresh reference to current menu bar
    int index = _actApp.Explorer.FindCommandBarIndex(CommandBarType.Menubar);
    CommandBar currentMenuBar = _actApp.Explorer.CommandBarCollection[index];
    // fetch fresh reference to parent menu control
    CommandBarControl parentControl = currentMenuBar.ControlCollection[parentURN];
    parentControl.RemoveSubItem(myCustomMenuItem);
}

 

Hope this helps someone else along the way.