How to intercept clicking an Office Ribbon control or command bar button
There are three ways to invoke a command of an Office application:
- Click a built-in Ribbon button (2007-2010);
- Click a built-in CommandBar button (Office 2000-2003 and some Office 2007 applications);
- Press a key combination
How to intercept clicking a built-in Ribbon control
In the Ribbon UI, you can intercept invoking these control types:
- Ribbon button
- Ribbon toggle button
- Ribbon checkbox
To intercept clicking a built-in Ribbon button such as File | Save in Word, Excel, PowerPoint etc., you need to find out the button’s IdMso, and use it to set up a Ribbon Command component; the component fires the OnAction event when that command is invoked.
A built-in Ribbon control is identified by its IdMso. IdMso is a string published by Microsoft in 2007 Office System Document: Lists of Control IDs and Office 2010 Help Files: Office Fluent User Interface Control Identifiers. These downloads provide a set of Excel files such as ExcelControls.xlsx and OutlookMailReadItemControls.xlsx; the Control Name column of each contains the IDs of almost all built-in Ribbon controls for the corresponding Ribbon.
To intercept invoking a command, you add a Ribbon Command component onto the add-in module and indicate the IdMso of the built-in Ribbon control to intercept in the component’s IdMso property:
The component fires the OnAction event when the user invokes the Ribbon command specified in the IdMso property:
C#:
private void ribbonCommandFileSave_OnAction(object sender, IRibbonControl control, bool pressed, ADXCancelEventArgs e) { MessageBox.Show("You've invoked the Ribbon command FileSave "); e.Cancel = true; }
How to intercept clicking a built-in CommandBar button
In the CommandBar system, you can intercept clicking buttons; other control types are unavailable for intercepting.
To intercept clicking on a CommandBar button such as File | Save in Word, Excel, PowerPoint etc., you find out the button’s Id (not IdMso!), and use it to set up a Built-in Control Connector component; the component fires the OnActionEx event when a control with that ID is clicked.
The ID of a CommandBar control is an integer value. For a custom CommnadBar control, it is always 1. The ID of a built-in control is set on the factory; you can find it using Built-in Controls Scanner – a free utility that lists the names, IDs, enabled and visible states of all CommnadBar controls in a specified Office application.
Now you add a Built-in Control Connector (ADXBuiltInControl) onto the add-in module and indicate the ID of the built-in control to intercept in the component’s ID property:
The final stage is to handle the OnActionEx event of the ADXBuiltInControl class:
C#:
private void CommandBarControlFileSave_ActionEx(object sender, ADXCancelEventArgs e) { MessageBox.Show("You've clicked the CommandBar control invoking the FileSave command"); e.Cancel = true; }
Find more details about how Built-in Control Connector (ADXBuiltInControl) operates in How to navigate through the Microsoft Office Command Bar system.
How to intercept pressing a key combination
Some key combinations end up in invoking the corresponding command bar or Ribbon control; that is you can intercept such keys using the approaches described above.
Note. The samples below are given according to Verklärte Macht: Keyboard Revisited by Jensen Harris.
This relates to Menu Accelerators e.g. ALT+O+H+R to navigate Format – Sheet – Rename to access the Format Sheet dialog box in Excel 2003. Pressing this combination in Excel 2007-2010 invokes a Ribbon command that you intercept in the way described in How to intercept clicking a built-in Ribbon control.
In the same way, Key Tips introduced in Office 2007 invoke corresponding Ribbon commands that you deal with in How to intercept clicking a built-in CommandBar button.
But there are keyboard shortcuts connected to the internals of the Office application itself. For instance, pressing Ctrl+S bypasses triggering the corresponding built-in commandbar or Ribbon button. To intercept such keyboard shortcuts, you use the KeyBoard Shortcut component (ADXKeyBoardShortcut). You add it onto the add-in module, set the ShortcutText property to the shortcut you need to intercept and handle the OnAction event.
Note that ADXKeyBoardShortcut gulps the key press and doesn't pass it to the host application.
And here's an example of how you handle keyboard shortcuts in Word. The point is that Word allows enumerating keyboard shortcuts associated with a given command. So, the code fragment below creates ADXKeyBoardShortcut components intercepting the FileSave command:
C#:
List<ADXKeyboardShortcut> fileSaveShortcuts = null; private void AddinModule_AddinInitialize(object sender, EventArgs e) { object param = Type.Missing; Word.KeysBoundTo wordKeys = WordApp.get_KeysBoundTo( Word.WdKeyCategory.wdKeyCategoryCommand, "FileSave", ref param); List<ADXKeyboardShortcut> shortcutProcessors = new List<ADXKeyboardShortcut>(wordKeys.Count + 1); for (int i = 1; i <= wordKeys.Count; i++) { ADXKeyboardShortcut shortcut = new ADXKeyboardShortcut(this.components); shortcut.ShortcutText = wordKeys[i].KeyString; shortcut.Action += new ADXAction_EventHandler(FileSaveShortcut_Action); shortcutProcessors.Add(shortcut); } Marshal.ReleaseComObject(wordKeys); } void FileSaveShortcut_Action(object sender) { MessageBox.Show("You've pressed " + (sender as ADXKeyboardShortcut).ShortcutText); }
You may also be interested in:
Intercepting clicking built-in command bar and Ribbon controls is also demonstrated in these articles:
How to handle Outlook item's Reply event: replying from a context-menu – intercepting the Reply button in a context menu of Outlook 2003;
How to create a custom event when Excel calculation mode changes – intercepting built-in controls (CommandBar and Ribbon) in Excel to get notified about calculation mode changes;
Excel shapes events: getting notified about user actions – intercepting the Group and Ungroup commands (CommandBar and Ribbon) that are used to group and ungroup Excel shapes.
Good luck!
14 Comments
Hi Andrei!
I have one question for you:
I have a problem trying to load a dll from a Project Add-ins for Outlook 2010.
When loading the dll I get an exception: LoaderLock, I clear this exception when I try again but outlook is turned off.
I use to load the dll kernell32.dll and the outlook seems q has loaded and that gives error ..
My question is this:
There will be some way to load dll from add-ins without it exploding?
Hi Ajess,
LoaderLock is a Managed Debugging Assistant warning thrown by the Visual Studio debugger. It is produced only when an application or add-in is run under the debugger and I doubt this could be the real cause of Outlook closing or crashing. Please make sure that you imported a function from the kernel32.dll library correctly, verify all the parameters, the entry point, etc.
Thanks for this info but can I intercept a click on a custom 3rd party ribbon button. Is there a way to find out the Id for this control
Hello Mike,
No, this isn’t possible. The ribbon API allows intercepting clicking on built-in controls, not custom. And there’s no way to retrieve the ID of a custom control.
Hello,
how can you intercept a built-in command via VBA?
Peeter
Hello Peeter,
It is possible in a document-level (template-level) solution: you need to create a proper XML and provide the corresponding callback function. I suggest that you start with https://msdn.microsoft.com/en-us/library/office/ee767705%28v=office.14%29.aspx and modify the XML as described at https://msdn.microsoft.com/en-us/library/office/bb462633%28v=office.12%29.aspx. The IDs of built-in controls can be downloaded here:
Office 2007 – https://www.microsoft.com/downloads/details.aspx?FamilyID=4329d9e9-4d11-46a5-898d-23e4f331e9ae&DisplayLang=en
Office 2010 – https://www.microsoft.com/downloads/details.aspx?FamilyID=3f2fe784-610e-4bf1-8143-41e481993ac6&displaylang=en
Office 2013 – https://www.microsoft.com/en-us/download/details.aspx?id=36798
Alternatively, you can intercept built-in commands as shown at https://msdn.microsoft.com/en-us/library/office/dd627337%28v=office.12%29.aspx.
Hope this helps.
But where do I get the Ribbon Command component from?
The Ribbon Command component is part of Add-in Express. That component is a wrapper for the command tag, see https://msdn.microsoft.com/en-us/library/office/bb462633%28v=office.12%29.aspx.
The command button I created to intercept the NewFolder and NewInLineFolder when I right click a folder to create a sub folder worked in Outlook 2010 but no longer works in Outlook 2016. Basically, I have a macro that must intercept the New Folder button (subfolder) when I click it. The control name or id appears to be the same, NewFolder & NewInLineFolder. Did something else change?
Hello Caroline,
I can’t tell you why your macro could stop working.
To confirm that the IdMso’s are correct, I’ve created a sample add-in and loaded it in Outlook 2016. If I choose “New Folder” in a folder context menu, the add-in intercepts IdMso=”NewInLineFolder”. If I click “New Folder” on the Folder tab, the add-in intercepts IdMso=”NewFolder”.
Make sure you Ribbon commands are specified for the Microsoft.Outlook.Explorer ribbon.
How to intercept double clicking?I want to mimic format painting with vba.
Hello Yang,
The Office Ribbon API and Commandbar API doen’t support double clicks. You can try to use the pressed state of a Ribbon button. A .NET developer could also create a pane and show a .NET button on it.
Thanks for your response,
You mean that i can’t use vba to come true fhe Format Painting in Word(click and doule click functionality) ?
The Office developer come true it with .NET. If I want to, I need to learn .NET, and how about XML?
Yang,
A developer can’t make a *Ribbon* button support double-clicks. This applies to any programming language.
As to .NET, I described a different scenario: you create a .NET-based COM add-in which shows a custom pane and shows a .NET button on the pane? not in the Ribbon. Such a button supports double-clicks. But, since you use VBA, this scenario doesn’t applies to your case.