| Parameter | Description |
|---|---|
| vCommandBarControl | Pointer to the COM control that was executed. If used, this must be bound to a DataFlex proxy object, which should be based cCJCommandBarControl or one if its sub-classes. This is rarely needed. |
| hoCommandBarControls | Handle of a DataFlex cCJCommandBarControls object that is bound to the COM object. |
Procedure OnPopupInit Variant vCommandBarControl Handle hoCommandBarControls
OnPopupInit is called before any popup menu or popup toolbar is displayed. It provides a custom hook where you can make any changes in the popup menu such as adding items, hiding items, disabling items, etc. This is called as part of the private PopupInit process, which will already do much of this work for you.
Two parameters are passed to this event. The vCommandBarControl is a pointer to the COM control that was selected. If you need to use this object you will need to create a DataFlex proxy object based on cCJCommandBarPopup, bind the pointer to this object, use it, and destroy it. It is unlikely that you will ever need to do this.
The hoCommandBarControls parameter is a DataFlex proxy object based on cCJCommandBarControls, which is a collection object that provides access to all child item objects. You are far more likely to use this object. Because it is passed to you, you do not have to worry about destroying it (in fact you should not destroy it).
OnExecute is called when your menu or toolbar item is a non-popup item. If your menu or toolbar item is a popup item, the OnPopupInit event is sent instead. An item's type is controlled by the control's peControlType property.
When a popup menu or toolbar item is selected, the private message PopupInit is sent to the cCJCommandBarSystem object. It does the following:
1. It sends Update to all COM child items of this object (actually it sends it to the child action objects). This ensures that each child's enabled, checked and visible state is correct.
2. It calls OnPopupInit.
If the functions IsChecked, IsEnabled and IsVisible are property coded in your child objects you will not need to do anything within OnPopupInit to set these child item properties. If you are not using these functions to set these properties you will need to write code to handle this by setting their pbChecked, pbEnabled and pbVisible properties yourself.
If you wish you can set the checked states and enabled states of popup menu items by setting their pbChecked and pbEnabled states. This is a less flexible way to handle this but it will work and, in some cases, provide a migration strategy. The following code shows an example of this:
Object oPopupMenu is a cCJMenuItem
Set peControlType to xtpControlPopup
Procedure OnPopupInit Variant vCommandBarControl Handle hoCommandBarControls
Boolean bReadOnly
Get pbReadOnly to bReadOnly
Set pbEnabled of oSaveMe to (not(bReadOnly))
Set pbChecked of oReadOnly to bReadOnly
End_Procedure
Object oSaveMe is a cCJMenuItem
Set psCaption to "Save Me"
Procedure OnExecute Variant vCommandBarControl
Send SaveThisThing
End_Procedure
End_Object
Object oReadOnly is a cCJMenuItem
Set psCaption to "Read Only"
Procedure OnExecute Variant vCommandBarControl
Boolean to bReadOnly
Get pbReadOnly to bReadOnly
Set pbReadOnly to (not(bReadOnly))
Set pbChecked to (not(bReadOnly))
End_Procedure
End_Object
End_ObjectWhile this works it is restrictive. If you move these menu items to any other popup menu, you will also need to change the OnPopupInit code of the old and new popup menus. If one of these items is moved to a toolbar, you will need to create additional logic to update their states any time pbReadOnly changes.
An alternate approach is to allow the items to do all the work via IsChecked and IsEnabled as follows:
Object oPopupMenu is a cCJMenuItem
Set peControlType to xtpControlPopup
Object oSaveMe is a cCJMenuItem
Set psCaption to "Save Me"
Procedure OnExecute Variant vCommandBarControl
Send SaveThisThing
End_Procedure
Function IsEnabled Returns Boolean
Boolean bReadOnly
Get pbReadOnly to bReadOnly
Function_Return (not(bReadOnly))
End_Function
End_Object
Object oReadOnly is a cCJMenuItem
Set psCaption to "Read Only"
Procedure OnExecute Variant vCommandBarControl
Boolean to bReadOnly
Get pbReadOnly to bReadOnly
Set pbReadOnly to (not(bReadOnly))
End_Procedure
Function IsChecked Returns Boolean
Boolean bReadOnly
Get pbReadOnly to bReadOnly
Function_Return bReadOnly
End_Function
End_Object
End_ObjectThese items can now be moved to any menu location without any other changes. If you place these in a toolbar, you can set the item's pbActiveUpdate property to true and the items will be refreshed automatically. This is the suggested approach.
Dynamic popup menus can be created using the following strategy
1. Create a class for the dynamic menu item. This will be based on cCJMenuItem. Within this class you will need to create an OnExecute method that does whatever you need this class to do. You also might need to create a property, which indicates what should happen when this item is selected.
2. Create an object, or even better a class, that is used for the popup menu. This will contain a handle array property to keep track of the dynamically created child object. Create an OnPopupInit event to handle creating the dynamic items. Within this event you will
2.1. Delete all existing dynamic items by sending Destroy to the objects in your handle array and zeroing the array
2.2. Create a dynamic object based on the class created in step 1.
2.3. Set this object's caption and any other properties needed for it to execute.
2.4. Add this dynamic object to the popup menu by sending the AddDynamicControl message.
2.5. Add this dynamic object handle to your array
2.6. Repeat step 2.2 through 2.5 for each new item.
The following example creates classes to build a MRU list.
// create the dynamic menu item class
Class cMRURecentFilesItem is a cCJMenuItem
Procedure Construct_Object
Forward Send Construct_Object
// full name of the file to be loaded
Property String psFileName
End_Procedure
Procedure OnExecute Variant vCommandBarControl
String sFile
Handle hoCommandBars
Get CommandBarSystemObject to hoCommandBars
Get psFileName to sFile
Send LoadFile of hoCommandBars sFile
End_Procedure
End_Class
// create the popup menu class
Class cMRURecentFiles is a cCJMenuItem
Procedure Construct_Object
Forward Send Construct_Object
Set psCaption to "Recent Files"
// this keeps track of all child items that are dynamically created
Property Handle[] phoArrayofItems
Set peControlType to xtpControlPopup
End_Procedure
// augment to display the latest 9 files. We assume that those file are
// obtained by sending the message Get MRUFiles to the owner commandbar system
Procedure OnPopupInit Variant vCommandBarControl Handle hCommandBarControls
Handle hoCommandBars hoNewItem
Integer i iItems
Handle[] hoArrayOfItems
String[] sArrayOfFileNames
Variant vItem
// delete all child items
Get phoArrayofItems to hoArrayOfItems
Move (SizeOfArray(hoArrayOfItems)) to iItems
For i from 0 to (iItems-1)
Send Destroy of hoArrayOfItems[i]
Loop
Move (ResizeArray(hoArrayOfItems,0)) to hoArrayOfItems
Get CommandBarSystemObject to hoCommandBars
Get MRUFiles of hoCommandBars to sArrayOfFileNames
Move (SizeOfArray(sArrayOfFileNames)) to iItems
// Add the first 9 items as child items.
Move ((iItems-1) min 9) to iItems
For i from 0 to iItems
// dynamically create the item object based on our MRU item class
Get Create U_cMRURecentFilesItem to hoNewItem
// set the caption. Prefix with a number for quick access.
Set psCaption of hoNewItem to ("&" - String(i+1) * sArrayOfFileNames[i])
// set the File name. In this case it happens to be the same as caption
Set psFileName of hoNewItem to sArrayOfFileNames[i]
// dynamically add the menu as a child of the current popup.
Get AddDynamicControl of hoNewItem hCommandBarControls to vItem
// keep track in our array
Move hoNewItem to hoArrayOfItems[i]
Loop
Set phoArrayofItems to hoArrayOfItems
End_Procedure
End_ClassThis popup menu could now be added to any menu or any toolbar with the following code:
Object oRecentFiles is a cMRURecentFiles End_Object
OnPopupInit is also sent any time a combo control takes the focus (the combo form is selected or the drop down box is invoked). This event can be used to fill a combo list. See cCJCommandBarComboBox for more information about combos and OnPopupInit.