Community
Showing results for 
Search instead for 
Do you mean 
Reply

Two issues concerning custom menu items

Accepted Solution Solved
Copper Contributor
Posts: 14
Country: United States
Accepted Solution

Two issues concerning custom menu items

Following issues observed under ACT! 2008 Premium with custom Plugin (Framework version 10.3.182.0).


Preface:  The custom menu item discussed below is added to the SubItems collection of the top-level Tools menu and is installed only on the CONNECTED_MENUBAR.  It is installed at AfterLogon event time (using AddSubItem method) and uninstalled at  BeforeLogoff event time (using RemoveSubItem method).

 

Note: The CommandBarButton representing this custom menu item is constructed only once, at Plugin load time, and held in memory.  It can conceivably be installed and uninstalled multiple times if the user closes and opens multiple databases during a single ACT session.

 

  1. My first issue looks like a bug.  It is manifested as a custom menu item magically appearing when ACT is launched, even though that menu item was explicitly removed during the previous ACT exit (in the BeforeLogoff event).    The menu item apparently gets serialized into the application even though there is no trace of it in the ControlCollection of the CONNECTED menu bar when my Uninstall code has completed and is exiting the BeforeLogoff event.

    This issue DOES NOT occur if the user accesses only a single database during an ACT session and exits the ACT application when done.  It DOES OCCUR if the user closes a database and re-opens another (or the same) database during a single ACT session.   In that case, the next time ACT is launched, my custom menu will already be present in the ControlCollection of the CONNECTED CommandBar when my MenuInstall() method is called.  Therefore, I must explicitly look for and remove the errant instance of my custom menu item during  my MenuInstall() process (which, interestingly, is exactly how the Custom Menu Sample is coded).   Did the author know something?

    One note:  The constructor call for my custom menu control (a CommandBarButton) includes a non-null "handler" argument which references a Click event  handler in my code.   I mention the presence of the handler argument in case it has some influence on this bug.  The handler reference does represent an issue all its own (see #2 below).
  2. Including a non-null "handler" argument in the call to the constructor for a CommandBarControl will cause ACT to set a Click event hook when that CommandBarControl is eventually added to the SubItems collection of another CommandBarControl.  Indeed, I note that the Click event in the CommandBarControl object contains a null reference until that control is added to the menu hierarchy via a call to AddSubItem(control, index), at which time an Invoke method reference appears there (as it should).

    My problem is that I can't figure out how to "unhook" the Click event when uninstalling my menu item.  A call to RemoveSubItem (to uninstall the menu item) does NOT clear the Click event hook in the custom CommandBarControl.   I have even added an explicit "MyMenuItem.Click -= MyClickEventHandler" to my uninstall code, but to no avail.  That line seems to have no effect on the underlying Click invocation table. 

    So, if my menu item is uninstalled and installed multiple times during a single ACT session (ala multiple database closes and opens by the user), my Click event handler will be added to the Click event invocation table multiple times and my Click event handler will be called that number of times when the user clicks on my menu item.  Two, three, or more times in a row!

    Does anyone know how to clear the Click event hook for a CommandBarControl?  In other words, how do we reverse the event hook created by ACT when adding a CommandBarControl containing a non-null "Handler" property?

 

Any "prior experience" or knowledge regarding these issues would be greatly appreciated.  Thanks.

 

Steve

 

 


Accepted Solutions
Solution
Accepted by topic author steve.m
‎09-25-2015 03:20 AM
Copper Contributor
Posts: 14
Country: United States

Re: Two issues concerning custom menu items

Did some testing and will post interesting facts under new heading (Custom Menu Facts and Caveats) for benefit of others.

View solution in original post


All Replies
Employee
Posts: 1,163
Country: USA

Re: Two issues concerning custom menu items

Hello Steve,

 

For the first issue, the problem is that when you move between databases without closing the application itself, the ActApplication object is never disposed of. So despite the fact that menu items should only have meaning within a particular database, they persist when moving between databases in this fashion. It's not technically a bug since this is the way it's designed to behave, however I think we'll both agree that it's not desirable for precisely this reason. You should be able to work around it however by setting the ActApplication object to null on logout and checking for it again on login. 

 

The first issue I've seen, however this is the first I've heard of the second, but frankly it sounds like another symptom of the same issue and can hopefully be resolved with the same remedy.

Matthew Wood
Act! SDK Support
Community Moderator
Copper Contributor
Posts: 14
Country: United States

Re: Two issues concerning custom menu items

Matthew,

 

Thank you for this suggestion. I should have thought of that.

 

I am curious if there is any more detailed documentation available on the inner workings of this?   I can assume from your explanation that the "visible" runtime elements in the CommandBar and CommandBarControl hierarchies of the menu and other tool bars, do not represent the "entire story" of what is in memory and that other objects continue to hold references to past objects (until garbage collection, I presume).   I have examined the content of the DotNetBar elements and the call stack during debugging and learned a bit about the architecture, but have resisted manipulating these objects in code due to cautions about future class uncertainty and all the other obvious reasons.

 

 

I will give your suggestion a try -- forcing the App reference to Dispose between logoffs and logons.  I can actually see that addressing case #2, but my suspicion about the first case is that the "phantom menu item" is due to a menu bar serialization taking place PRIOR TO the AfterLogoff event being fired, but only when the App is NOT also exiting.

 

I will let you know my results.  Thanks again for responding.   Much appreciated.

 

Steve

 

 

 

Copper Contributor
Posts: 14
Country: United States

Re: Two issues concerning custom menu items

[ Edited ]

Matthew,

 

I am missing something here.  I don't think the ACT app can be truly unreferenced and Disposed until the application exits.  

 

When a user logs off a database, a Plugin still needs to monitor at least one event (like BeforeLogon or AfterLogon), lest it lose sight of the next user logon.   That one event hook means there is an active reference to the ActApplication object, even if all other variables referencing the object are set to null.  Even without the one event hook, the Act App cannot Dispose because it holds a static reference to itself in its own Instance property.  For kicks, I tried calling the ActApplication.Dispose() method directly after a logoff occurs.  It did nothing, as expected.

 

Your suggestion does give me one idea -- that is, Dispose of the menu button instance right after it is removed from the menu hierarchy.  Right now, I create the CommandBarButton and re-use it throughout the session, installing it and uninstalling it as the app switches between "Connected" and "Unconnected" states.  My worry is, if there are phantom menu button references floating around in memory, this approach may well "hide" the problem from my code while leaving a very real memory leak in place.  A small one granted.

 

So, you have a workaround for the phantom menu reappearance -- always start a menu button install by first looking for and removing any menu buttons having a matching URN.  I suppose that is why the Sample for Custom Menu does it just that way.

 

But the Click event hook is more problematic.  As we know, I am allowing the Act framework code to set the event hook based on me passing a non-null "handler" argument to the CommandBarButton constructor.  There really should be a way to remove that hook, even via some undocumented method.  It would really be great to hear from one of the programmers how the Click event can be unhooked.  If Disposing of the CommandBarButton object each time will do the trick cleanly, then so be it.

 

But it would be great to hear someone assert that "MyMenuButton.Click  -= this.MyClickHandler" (which should do the job), does not work for a reason.   (By the way, "MyMenuButton.DNBBaseItem.Click  -= this.MyClickHandler" has no effect as well.)

 

Steve

 

  

Solution
Accepted by topic author steve.m
‎09-25-2015 03:20 AM
Copper Contributor
Posts: 14
Country: United States

Re: Two issues concerning custom menu items

Did some testing and will post interesting facts under new heading (Custom Menu Facts and Caveats) for benefit of others.

New Member
Posts: 5
Country: United States

Re: Two issues concerning custom menu items

Hey Steve M and Sage:

I am not a developer but just a user.  I also have had custom menu items disappear.  I'm on an old Win 2003 server, using Act 9.0 (11.0) which has been level with all other systems so we haven't upgraded as ... it works!

 

Today the custom write menu items were missing, as were the report items.  We can rebuild, but want to know what might have caused this.  Could it also be from switiching between databases without properly closing one down?  If not this, then what?  And do you know of any way we can save the preferences file (whatever that name might be) once we rebuild, so if it happens again, we can just restore that back up preference.

 

Many thanks

Jefferson