Dynamic codejock menus from a database
From DataFlex Wiki
Class of menu:
Use cBgCjMenuItem.pkg // cBgCjMenuItemDynamic Class cBgCjMenuItemDynamic is a cBgCjMenuItem // Construct_Object {OverrideProperty=psCaption InitialValue="&Some caption"} {OverrideProperty=psImage InitialValue="Icon.ico"} Procedure Construct_Object Forward Send Construct_Object Set pbActiveUpdate to True Property Handle phoDDO Property Handle[] phoArrayofItems Set psCaption to "&Some caption" Set psImage to "Icon.ico" Set psDescription to 'Bla bla' Set psToolTip to 'Bla bla' Set peControlStyle to xtpButtonIconAndCAption Set peControlType to xtpControlPopup End_Procedure // Construct_Object // OnItemClicked // This event will be sent when a user clicks on a dynamically added menuitem. {MethodType=Event} Procedure OnItemClicked Integer iTableID Integer iExtraParameter End_Procedure // OnPopupInit Procedure OnPopupInit Variant vCommandBarControl Handle hCommandBarControls Forward Send OnPopupInit vCommandBarControl hCommandBarControls Send DoFillDynamicMenu hCommandBarControls End_Procedure // Add all dynamic menu items. {Visibility=Private} Procedure DoFillDynamicMenu Handle hCommandBarControls Integer iCommaPos iAantal iType String sCommaSepValues sEnkelvoud sMeervoud Handle hMessage Handle[] hoArrayOfItems Handle hoNewItem hoDDO Integer iItems iteller iExtraParameter // First delete all items that were added before. Get phoArrayofItems to hoArrayOfItems Move (SizeOfArray(hoArrayOfItems)) to iItems For iTeller from 0 to (iItems-1) Send Destroy of hoArrayOfItems[iTeller] Loop Move (ResizeArray(hoArrayOfItems,0)) to hoArrayOfItems Move 0 to iTeller Get phoDDO to hoDDO If (hoDDO <> 0) Begin // With this you can query some field value in a ddo. // This value will be sent with the OnItemClicked event as an extra parameter. Get Field_Current_Value of hoDDO Field Table.SomeField to iExtraParameter End Move Msg_OnItemClicked to hMessage Open SomeTable Clear SomeTable Move "V" to SomeTable.Type Find ge SomeTable.Type While ((Found) and (SomeTable.Type = "V")) Get GetAddItem U_cBgCjMenuItem hCommandBarControls (Trim(SomeTable.Description)) False hMessage (Self) SomeTable.TableId iExtraParameter to hoNewItem Move hoNewItem to hoArrayOfItems[iTeller] Add 1 to iTeller Find gt SomeTable.Type Loop If (iCounter = 0) Begin Get GetAddItem U_cBgCjMenuItem hCommandBarControls "<No menuitems found!>" False Msg_None (Self) to hoNewItem Move hoNewItem to hoArrayOfItems[iCounter] Add 1 to iCounter End Set phoArrayofItems to hoArrayOfItems End_Procedure // DoFillDynamicMenu // IsEnabled Function IsEnabled Returns Boolean Handle hoDDO Boolean bEnabled Get phoDDO to hoDDO If (hoDDO <> 0) Begin // Only enable menu items when a record has been selected. Move (HasRecord(hoDDO)) to bEnabled End Function_Return bEnabled End_Function End_Class // cBgCjMenuItemStatusAanpassen
The class uses a special subclass for the menu item:
Class cBgCjMenuItem is a cCJMenuItem // Construct_Object Procedure Construct_Object Forward Send Construct_Object Property Handle phMessage Property Handle phoMessageObject Property String psMessageParameter Property String psMessageParameter2 Property String psMessageParameter3 Set peControlType to xtpControlButton End_Procedure // End_Construct_Object Procedure End_Construct_Object Forward Send End_Construct_Object End_Procedure // OnExecute Procedure OnExecute Variant vCommandBarControl Handle hMessage hoMessageObject String sMessageParameter sMessageParameter2 sMessageParameter3 Get phMessage to hMessage If (hMessage <> 0) Begin Get phoMessageObject to hoMessageObject If (hoMessageObject = 0) Begin Get Client_Id to hoMessageObject End Get psMessageParameter to sMessageParameter Get psMessageParameter2 to sMessageParameter2 Get psMessageParameter3 to sMessageParameter3 Send hMessage of hoMessageObject sMessageParameter sMessageParameter2 sMessageParameter3 End Else Forward Send OnExecute vCommandBarControl End_Procedure // GetAddItem // Adds item dynamically Function GetAddItem Handle hClass Handle hCommandBarControls String sCaption Boolean bDivider Handle hOptMessage Handle hoOptMessageObject ; String sOptMessageParameter String sOptMessageParameter2 String sOptMessageParameter3 Returns Handle Handle hoNewItem hMessage hoMessageObject Variant vItem Handle[] hoArrayOfItems Integer iItems String sMessageParameter sMessageParameter2 sMessageParameter3 If (Num_Arguments >= 5) Move hOptMessage to hMessage If (Num_Arguments >= 6) Move hoOptMessageObject to hoMessageObject If (num_arguments >= 7) Move sOptMessageParameter to sMessageParameter If (num_arguments >= 8) Move sOptMessageParameter2 to sMessageParameter2 If (num_arguments >= 9) Move sOptMessageParameter3 to sMessageParameter3 // Dynamisch object aanmaken. Get Create hClass to hoNewItem If (hoNewItem <> 0) Begin // Label maken Set psCaption of hoNewItem to sCaption If (bDivider) Set pbControlBeginGroup of hoNewItem to True If (hMessage <> 0) Set phMessage of hoNewItem to hMessage If (hoMessageObject <> 0) Set phoMessageObject of hoNewItem to hoMessageObject If (sMessageParameter <> "") Set psMessageParameter of hoNewItem to sMessageParameter If (sMessageParameter2 <> "") Set psMessageParameter2 of hoNewItem to sMessageParameter2 If (sMessageParameter3 <> "") Set psMessageParameter3 of hoNewItem to sMessageParameter3 // Dynamically add the menu as a child of the current popup. Get AddDynamicControl of hoNewItem hCommandBarControls to vItem End Else Begin Error 300 ("Menu item" * sCaption * "can not be added!") End Function_Return hoNewItem End_Function // GetAddItem End_Class
And finally to use it in your programs menu:
Object oDynamicMenuItems_itm is a cBgCjMenuItemDynamic // OnCreateAction Procedure OnCreateAction Forward Send OnCreateAction Set phoDDO to (SomeTable_DD(Self)) // This is an option... End_Procedure Procedure OnItemClicked Integer iTableID Integer iExtraParameterFromDDO Send DoThis iTableID iExtraParameterFromDDO End_Procedure End_Object // oDynamicMenuItems_itm