MS-Excel / General Formatting

Creating a Menu

If you have a small collection of related macros, you can save space in your custom interface by bundling the buttons for all those macros into a menu. You create the menu control by using the <menu> element:

<menu id="value"
label="value"
imageMso="value"
itemSize="normal|large"
InsertAfterMso="value"
InsertBeforeMso="value"
onAction="value"
enabled="true|false"
visible="true|false"
screentip="value"
supertip="value"
keytip="value">

Note that you use itemSize instead of size, and that this attribute affects every item in the menu.

You populate the menu by adding two or more <button> elements between <menu> and </menu>. Here's an example:

<menu id="menu1" label="Close Document">
    <button id="btnSaveChanges"
	label="Save Changes"
	imageMso="FileSave"
	onAction="Module1.btnSaveChanges_OnAction" />
    <button id="btnDoNotSaveChanges"
	label="Don't Save Changes"
	imageMso="SaveAndClose"
	onAction="Module1.btnDoNotSaveChanges_OnAction" />
    <button id="btnPromptToSaveChanges"
	label="Prompt to Save Changes"
	imageMso="WorkflowPending"
	onAction="Module1.btnPromptToSaveChanges_OnAction" />
</menu>

If you do even mildly extensive customizations with RibbonX, your new interface will consist of a fair number of controls,many of which will have several associated callback macros. In other words, you can easily end up with dozens of interface elements to maintain.To help you keep everything straight, it's best to use certain naming conventions. For control names, use prefixes that indicate the control type:btn (for a button),sb (split button),chk (check box),tb (toggle button),lst (drop-down list),gal (gallery),cb (combo box),ed (edit box), and dl (dialog launcher). For callback macros, use the following format:

control_attribute

Here, replace control with the name of the control, and replace attribute with the attribute that calls the macro. For example, for the onAction callback macro for a button named btnSaveChanges, you'd use the following name:

btnSaveChanges_OnAction

In the preceding example, each menu button calls a different procedure. Here are the associated procedures:

Sub SaveChanges_OnAction(ByVal control As IRibbonControl)
    ActiveDocument.Close wdSaveChanges
End Sub

Sub DoNotSaveChanges_OnAction(ByVal control As IRibbonControl)
    ActiveDocument.Close wdDoNotSaveChanges
End Sub

Sub btnPromptToSaveChanges_OnAction(ByVal control As IRibbonControl)
    ActiveDocument.Close wdPromptToSaveChanges
End Sub

In such a case, it probably makes more sense to use a single callback macro that determines which button was clicked and proceeds accordingly. To determine the button that was clicked, you use the control object's ID property, which returns the id attribute of the button that was clicked.

First, you need to adjust the RibbonX code so that each <button> uses the same onAction value:

<menu id="mnuCloseDocument2" label="Close Document">
    <button id="btnSaveChanges2"
	label="Save Changes"
	imageMso="FileSave"
	onAction="Module1.mnuCloseDocument2_OnAction" />
    <button id="btnDoNotSaveChanges2"
	label="Don't Save Changes"
	imageMso="SaveAndClose"
	onAction="Module1.mnuCloseDocument2_OnAction" />
    <button id="btnPromptToSaveChanges2"
	label="Prompt to Save Changes"
	imageMso="WorkflowPending"
	onAction="Module1.mnuCloseDocument2_OnAction" />
</menu>

Here's a callback procedure that uses Select Case to check the ID property and then proceeds accordingly:

Sub mnuCloseDocument2_OnAction(ByVal control As IRibbonControl)
    Select Case control.ID
	Case "btnSaveChanges2"
	    ActiveDocument.Close wdSaveChanges
	Case "btnDoNotSaveChanges2"
	    ActiveDocument.Close wdDoNotSaveChanges
	Case "btnPromptToSaveChanges2"
	    ActiveDocument.Close wdPromptToSaveChanges
    End Select
End Sub
[Previous] [Contents] [Next]