05-08-2012 07:13 AM
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.
Any "prior experience" or knowledge regarding these issues would be greatly appreciated. Thanks.
05-09-2012 06:48 AM
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.
05-09-2012 11:47 AM
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.
05-09-2012 03:53 PM - edited 05-09-2012 04:04 PM
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.)
03-15-2013 03:41 PM
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.