When a user clicks on a button in the ribbon, or selects an item in a dropdown or gallery,
an Action event is raised.
The framework and the XLL+ Ribbon Manager cooperate to route this event to the application's
OnRibbonEvent
virtual function, with a callback type
RIBBONCALLBACK_ONACTION.
The table below lists the values of the OnAction
attribute that should be used
to specify this routing.
Control | Callback | Parameters |
---|---|---|
button | OnActionButton | |
checkBox | OnActionToggleButton | pressed |
dropDown | OnActionIndexed | selectedItem, index |
gallery | OnActionIndexed | selectedItem, index |
toggleButton | OnActionToggleButton | pressed |
The XML below shows some examples of OnAction attributes.
<button id="MyAddin_PushButton" size="large" image="LOGO" label="My Button" onAction="OnActionButton" /> <toggleButton id="MyAddin_ToggleButton" size="large" imageMso="Delete" label="A Toggle" onAction="OnActionToggleButton" /> <checkBox id="MyAddin_CheckBox" label="My Checkbox" onAction="OnActionToggleButton"/> <dropDown id="MyAddin_DropDown" label="A Dropdown" onAction="OnActionIndexed"> <item id="MyAddin_DropDown_Item0" imageMso="Underline" label="Item 0"/> <item id="MyAddin_DropDown_Item1" imageMso="Italic" label="Item 1"/> </dropDown> <gallery id="MyAddin_Gallery" label="A Gallery" size="large" columns="1" imageMso="Font" onAction="OnActionIndexed"> <item id="MyAddin_Gallery_Item0" imageMso="FontSizeIncrease" label="Item 0"/> <item id="MyAddin_Gallery_Item1" imageMso="FontSizeDecrease" label="Item 1"/> </gallery>
You could use an event handler like the following to inspect the events and react to them:
CXlOper CMyAddinApp::OnRibbonEvent(const CRibbonEvtParams& e) { CXlOper xloResult = CXllApp::OnRibbonEvent(e); switch (e.GetCallback()) { case RIBBONCALLBACK_ONACTION: if (e.GetId() == _T("MyAddin_PushButton")) { XlMessageBox(_T("Hello from the ribbon!"), XlMessageBoxTypeInformation); } else if (e.GetId() == _T("MyAddin_ToggleButton")) { CString strMessage; strMessage.Format(_T("The toggle is %s"), e.GetPressed() ? _T("down") : _T("up")); XlMessageBox(strMessage, XlMessageBoxTypeInformation); } else if (e.GetId() == _T("MyAddin_CheckBox")) { CString strMessage; strMessage.Format(_T("The box is %s"), e.GetPressed() ? _T("checked") : _T("unchecked")); XlMessageBox(strMessage, XlMessageBoxTypeInformation); } else if (e.GetId() == _T("MyAddin_DropDown") || e.GetId() == _T("MyAddin_Gallery")) { CString strMessage; strMessage.Format(_T("Control %s: index=%ld item=%s"), (LPCTSTR)e.GetId(), e.GetIndex(), (LPCTSTR)e.GetSelectedId()); XlMessageBox(strMessage, XlMessageBoxTypeInformation); } break; } return xloResult; }
An alternative approach is to route the action callback directly to a named add-in function. This approach is discussed further in Supporting earlier Excel versions
As well responding to user actions, your code may need to provide information to the ribbon, such as the selected item in a drop-down or a gallery, or the current image or label for a button whose appearance changes dynamically.
If you specify the appropriate callback for a control, then the event will be routed through the
OnRibbonEvent
handler of your add-ins application class.
The XML below shows a gallery control with two additional callback attributes, getSelectedItemIndex
and getImage
:
<gallery id="MyAddin_Gallery" label="My Gallery" size="large" columns="1" onAction="OnActionIndexed" getSelectedItemIndex="GetSelectedItemIndex" getImage="GetImage"> <item id="MyAddin_Gallery_Item0" image="STOP" label="Item 0"/> <item id="MyAddin_Gallery_Item1" image="GO" label="Item 1"/> </gallery>
The code below handles the ribbon events for the gallery.
Note the call to CXllApp::InvalidateRibbon
after handling the OnAction event. This causes the ribbon to call GetImage
and GetSelectedItemIndex
again,
which in turn causes the gallery's image to be updated.
int nGallerySelectedIndex = 0; CXlOper CMyAddinApp::OnRibbonEvent(const CRibbonEvtParams& e) { CXlOper xloResult = CXllApp::OnRibbonEvent(e); switch (e.GetCallback()) { case RIBBONCALLBACK_ONACTION: if (e.GetId() == _T("MyAddin_Gallery")) { nGallerySelectedIndex = e.GetIndex(); InvalidateRibbon(); // So that the image gets updated } break; case RIBBONCALLBACK_GETSELECTEDITEMINDEX: if (e.GetId() == _T("MyAddin_Gallery")) { xloResult.FromInt(nGallerySelectedIndex); } break; case RIBBONCALLBACK_GETIMAGE: if (e.GetId() == _T("MyAddin_Gallery")) { xloResult = (nGallerySelectedIndex == 0) ? "STOP" : "GO"; } break; } return xloResult; }
The naming convention followed is to specify a callback whose name is the same as the name of the attribute,
but with an initial capital letter, e.g. getLabel="GetLabel" getImage="GetImage"
.
For a complete listing of all the callback functions that can be used as attributes for ribbon controls, see Ribbon callback functions.
Next: Supporting earlier Excel versions >>