Form main menus are somewhat limited in Basic4ppc in that they may only be constructed in the IDE Designer and their structure is fixed at runtime.This library allows the manipulation of existing main menus and the creation of entirely new ones at runtime. As well as Click events it also provides Popup events for menu items and these events may be attached to existing or new menu items. Besides allowing the menu structure of a form to be altered this library also offers the ability to store complete menu structures and assign them to a form as required.
This library was inspired by a wishlist item posted by caesar (Michael).
As usual demo, help file, dll and source code for merging are provided. This library will work on .NET 1.0/1.1 or later on both desktop and device and in the IDE and both legacy or optimised compiled applications.
Edit :- Version 1.1 posted. See post #17 for details.
In the help file, the first "GetMainMenu" is meant to be SetMainMenu...
I'm afraid that I can't see anything wrong with that, unless I am missing something obvious! Maybe its a languange nuance. That methods "gets", that is fetches, the MainMenu from the Form specified and "sets" the value in the MainMenu to what has been "got" (or "gotten" - US ). Similarly NewMainMenu "sets" the present MainMenu to a new empty one.
EDIT :- I think I may now see what you mean. I originally thought that you meant there was an error in the help file, what you actually meant was that the method itself is misnamed - which I admit it probably is as the direction of the "get" is opposite to that which it usually indicates. Ah well ....!
I've posted an updated help in the first post that may explain this library a little more clearly than the original help does.
I expect so, but I am still struggling. (My wisdom is going along with my wisdom teeth, perhaps!)
My problem is understanding how the click or pop-up events (which must be mutually exclusive for any given item) are linked to the user's action. Presumably the event Subs are named after the object that is the subject of the New1() method. But that object can be used (if I follow right) to spawn any number of items that can be added to a main menu.
Can Sender.Text be used, as for other potentially ambiguous events, to discover which actual menu item was chosen? If so it would be useful to mention this in the Help. If not, how is it done?
(Of course Sender.Text would require that the leaf nodes in the menu tree all have distinct texts, even if they are theoretically distinguishable by higher levels in the tree. I appreciate that using Sender.Name or SenderFullName.Name would be better, but NewMenuItem() only offers a Text property, not a Name.)
Sender will only give you the name of the Basic4ppc MenuItem object, not the .NET menu item that was clicked or popped up. When a MenuItem event occurs its Text property contains the text of the menu item in question.
From the demo
Code:
Sub MenuItem1_Click TextBox1.Text = "Click : " & <b>MenuItem1.Text </b>& " : " & MenuItem1.Checked End Sub
In the Compact Framework there is no way of identifying individual menu items except by their Text property. They do have a Parent property, not exposed by the library, that is itself a menu item so you could look at the Text property of this with the Door library
Code:
Sub MenuItem1_Popup Obj1.FromLibrary("NewMenu.MenuItem1", "mitem", B4PObject(2)) Obj1.Value = Obj1.GetProperty("Parent") ' a MainMenu or MenuItem object parent = obj1.RunMethod("ToString") If StrIndexOf(parent, "MenuItem", 0) < 0Then parent = "Root"' a MainMenu doesn't have a Text property Else parent = Obj1.GetProperty("Text") EndIf TextBox1.Text = parent End Sub
__________________
Sorry, but I don't answer questions by PM or email.
Please post your queries in the forum.
Sub MenuItem1_Click TextBox1.Text = "Click : " & <b>MenuItem1.Text </b>& " : " & MenuItem1.Checked End Sub
Thanks for that Andrew. I hadn't even noticed that you provided a demo, let alone tried it out. But now I have I still have puzzlement. Originally I could not get the demo to breakpoint on that Sub you cited. Then I spotted the difference between "Click:" and "Click :"! So I added SenderFullName and discovered that there is a name associated with menu items but it is always that of the originating object menuitem1!
There is a lurking problem behind the use of text rather than name: localisation. Not that I'm going multi-lingual, but it would make identifying menu items that much more complicated.
Quote:
Originally Posted by agraham
In the Compact Framework there is no way of identifying individual menu items except by their Text property. They do have a Parent property, not exposed by the library, that is itself a menu item so you could look at the Text property of this with the Door library.
I still have not plucked up courage to try that Door. (Must be anticipating "a maze of twisty passages; all alike" - even though I never went into any Dungeons.)
On the other hand, given I originally wanted to propagate a menu built with the Designer to multiple forms, so I have started experimenting with that. Such menu items of course have names as well as text, and these can be disclosed with Sender. Furthermore SenderFullName shows the module too. But the module remains that in which the menu originated; it is not modified by the copying (not that that is very surprising; are they multiple references to the same structure?). Similarly the click event Sub remains that one that was established in the Designer, in the original module. However I should be able to get around both of those problems (which together would require some tricky use of globals to discover what the environment of the menu click was) by resetting the click event Sub of each cloned menu to a Sub in the corresponding module, and hence inherently aware of the environment. What fun!
So I added SenderFullName and discovered that there is a name associated with menu items but it is always that of the originating object menuitem1!
That's what I told you in the first line of my post above!
Quote:
There is a lurking problem behind the use of text rather than name: localisation. Not that I'm going multi-lingual, but it would make identifying menu items that much more complicated.
I can't disagree but it's a limitation of the Compact Framework. MenuItem objects in the full .NET Framework have a Tag property that can be used to uniquely label them. However the library is intended for use on both desktop and device and so is lower common denominator. You can always use the Door library to access the Tag property on the desktop if necessary.
__________________
Sorry, but I don't answer questions by PM or email.
Please post your queries in the forum.
by resetting the click event Sub of each cloned menu to a Sub in the corresponding module
Just noticed this. Not a good idea! Basic4ppc doesn't cope with removing events from controls so you will probably end up with multiple event sub invocations. You should do something like a CallSub from the event Sub to the code you want to run and get the Sub name from a global, or do a Select.
__________________
Sorry, but I don't answer questions by PM or email.
Please post your queries in the forum.
That's what I told you in the first line of my post above!
So you did!
Quote:
Originally Posted by agraham
Just noticed this. Not a good idea! Basic4ppc doesn't cope with removing events from controls so you will probably end up with multiple event sub invocations. You should do something like a CallSub from the event Sub to the code you want to run and get the Sub name from a global, or do a Select.
Ah, I guess that's an unstated hidden limitation of AddEvent(). I had expected to get a slap for calling the menus "cloned" because there is no "Clone()" method in MainMenu and I suspect that each item/structure has to be built separately or else will merely be multiple references to the same structure.
Oh, well, I guess that the use of CallSub with (yet more) Public Globals is the only way to get what I want.
An alternative I have been toying with is to use panels on one form so that they can share the same menus. But the Designer is not good at dealing with that, and it makes dividing up code into modules inconvenient too.