The way that I do it is to have a control of type dynamicMenu in the XLM. This control invokes a callback that I call rxGetContent. This callback returns XML that defines the menu that will be displayed. This is my code for rxGetContent, which in turn calls a function to build the XML. This function is passed an id, to differentiate this app, a matrix that holds all of the properties of the menu items, and an image to show alongside the menu items.
Public Function rxGetContent(control As IRibbonControl, ByRef Content)
Select Case control.Id
Case CONTROLID_RB_DYNA_MENU: Content = BuildDynamicMenu(Id:="RB", _
MenuData:=mgMtxMenu, _
ControlImage:=IMAGE_RB_DYN_DATA_LIST)
End Select
End Function
Note that CONTROLID_RB_DYNA_MENU is a public constant where I store the dynamic menu control name that I assign in the XML.
The matrix has as many rows as you have items, and 4 columns, the item name (which is appended to the function id parameter, the item label, the macro that is called if the item is clicked, and a tag property for the item which allows a parameter value if required. This matrix needs to be setup as the workbook opens, and would be of the form
mgMtxMenu = [{"Item1","First macro","Macro1","Tag 1";"Item2","Second macro","Macro2","Tag 2"}]
Finally, this is the code that builds the XML
'-----------------------------------------------------------------
Public Function BuildDynamicMenu( _
ByVal Id As String, _
ByVal MenuData As Variant, _
ByVal ControlImage As String) As String
'-----------------------------------------------------------------
Dim mpXML As String
Dim i As Long
Const mpProcedure As String = "rxGenerateDynamicMenu"
mpXML = NAMESPACE_RIBBON_2007 & vbNewLine & vbNewLine
For i = LBound(MenuData, 1) To UBound(MenuData, 1)
mpXML = mpXML & _
" <button id=""btn" & Id & MenuData(i, 1) & i & """ " & vbNewLine & _
" label=""" & MenuData(i, 2) & """ " & vbNewLine & _
" imageMso=""" & ControlImage & """ " & vbNewLine & _
" tag=""" & MenuData(i, 4) & """ " & vbNewLine & _
" onAction=""" & MenuData(i, 3) & """ />" & vbNewLine & vbNewLine
Next i
BuildDynamicMenu = mpXML & "</menu>"
End Function
NAMESPACE_RIBBON_2007 is another public constant with the value
"<menu xmlns=""http://schemas.microsoft.com/office/2006/01/customui"">"
Bookmarks