18 October 2015

The Non-existing MenuItems Collection

MenuItems is a collection representing all the menu items contained in a Form’s menu. According to COM/VB rules the next phrase should be true:
calling Add on this collection adds an item to the menu and returns a MenuItem object”.
However, there is no actual MenuItems collection you can use in GB32. The MenuItems data type does exist, but contains nothing more than empty stub functions.

Logically, the MenuItems dependent collection (it exists only when a menu-bar is present) should be used to manage the menu items. But in Dependent Collections I showed you why GB32 considers an in-between collection redundant and overkill. Generally, the collection’s implementation does nothing more than reroute all the collection’s properties and methods to the required item object (by key or index). In the case of the MenuItems collection, well GB32 skips the collection entirely.

Where do they come from
GB32 creates a MenuItem object for a menu-entry when it parses the one-dimensional string array containing the menu-entries for a window.

Menu menuEntries$()

Since the beginning, this how a GFA-BASIC menu-bar is created. Fill an array with string elements and let GB create and assign a menu-bar to the current active window. When the window is destroyed, the MenuItem objects are destroyed as well. The only other way to release the MenuItem-objects associated with a menu-bar of a Form is by using Menu Kill.

Now let’s see how to manage the menu-bar entries without the MenuItems collection. This process is not VB-compatible, as VB prescribes the use of a collection. As you probably know, dependent collections are used to iterate over the items they contain, to add new items, to remove items, etcetera. To provide these facilities, the MenuItems collection would provide the following properties and methods:

Property or method Description
Add method Add menu-items to the collection.
Count property Return the number of menu-items in the collection. Read-only.
Item method Return a menu item, by index (or by key).
Remove method Delete a menu.item from the collection, by index (or by key).
Clear Remove and delete all menu-items

Since GB32 doesn’t implement the MenuItems collection, these properties and methods aren’t available. GFA-BASIC 32 does not provide a collection to manage menu-items, but it does however provide MenuItem objects to allow access to single menu-entries. The Form supports a property that returns a MenuItem object. The property takes one parameter, a Long MenuID-value. The value must represent the menu-ID of the menu-entry, which is either the index of an element of the string-array or a designated ordinal (specified in the string element that specifies the menu-item text).

Dim mnuItem As MenuItem
Set mnuItem = frm1.MenuItem(1)

The MenuItem-objects are created at run-time when GFA-BASIC executes the command Menu $(). The ordinal ID-value is assigned both to the MenuItem object as well as to the Windows API functions. The ID-value can not be changed later on. Also, any changes made to a menu-entry using API functions will not be reflected in the MenuItem object. So, all changes of the menu-entries are to be done using a MenuItem object.

1 comment:

  1. James Gaite18/10/15

    Interesting article. This would explain the reason why Form.MenuItem does not work with menu items and sub menus created through Windows APIs. Thank you for clarifying that.