RibbonCustomizer™
Customize your Office 2007 Ribbon (Office Fluent™)with only a few mouse clicks! Works with Microsoft® Access™, Excel®, Outlook®, PowerPoint® and Word 2007.

Buy for $29.99

Download free Starter Edition

Subscribe | Subscribe by Email |

Categories

Archive


RibbonX Callbacks

July 27th, 2006 by Patrick Schmid

Callbacks are a fundamental feature of RibbonX. It is therefore important for developers to understand when they are executed and when they may fail. As a principal rule, callbacks shouldn’t assume anything and should protect themselves against all potential failures. Let me illustrate some of the difficulties with the following example.

Revisiting the StyleChooser add-in

V1.2.1 of my StyleChooser add-in contained a callback that failed. To reproduce the error, you can download V1.2.1 and its source code. Install it and open Word. Before you continue, make sure that UI errors of add-ins are being displayed (Word Options, Advanced, General section, Show add-in user interface errors). With the Home tab displayed, switch to the Full Screen Reading mode via the status bar. In that mode, click on Print Layout. You should then see a CustomUI error message: An exception occured while calling function “GetText”. The exception message is: This method or property is not available because typing is not currently allowed for reading.

What happened? GetText looks like this:

Public Function GetText(ByVal control As IRibbonControl) As String

If control.Id = “comboStyleChooser” Then

Dim selection As Microsoft.Office.Interop.Word.Selection = DirectCast(applicationObject.Selection, Microsoft.Office.Interop.Word.Selection)

Return formattedStyle(DirectCast(selection.Style, Microsoft.Office.Interop.Word.Style))

End If

Return “”

End Function

The error is caused by the call selection.Style as Word is still in the Full Screen Reading mode when the callback is being executed. In that mode, this particular call is not allowed. I fixed this problem with V1.2.2 by wrapping the call in a try-catch statement (download source code). I assumed this to be a bug in Word 2007 and submitted it to Microsoft as such. Unfortunately, Microsoft couldn’t fix the issue as executing callbacks when the ribbon was already displayed caused some serious flickering.

Don’t assume anything

Therefore add-in developers need to ensure that callbacks don’t make any assumptions. A callback cannot assume that a particular document is open or that the application is in a particular mode:

Callbacks might be executed before the user interface or any particular document is displayed or available via the object model.

Callbacks should not assume anything and should be ready to be called at any time. They therefore need to check for various conditions to prevent errors like the one in my StyleChooser 1.2.1 version. This applies to all RibbonX callbacks, not just to those implemented by COM add-ins.

ODF translator project and its integration into Office 2007 (repurposing commands)

July 25th, 2006 by Patrick Schmid

20 days ago, Microsoft announced the ODF translator project. Brian Jones clarified a few issues in another blog post a few days later. Currently, an early version of the ODF translator project is available for Word. It integrates into Word as an add-in. You can download a copy as well as the full source code from sourceforge.

One of the most contentious issues became right away how the ODF add-in integrates into Word. Brian claimed:

“It’s directly exposed in the UI. We’re even going to make it really easy to initially discover the download. We already need to do this for XPS and PDF, so we’ll also do it for ODF. There will be a menu item directly on the file menu that takes to you a site where you can download different interoperability formats (like PDF, XPS, and now ODF).

Heck, if you wanted to be even more hardcore, the Office object model allows you to capture the save event. So if you wanted to you could make it so that anytime you hit save you always used the ODF format, just by capturing the save event and overriding it. I’m not expecting folks to do that, but it does show just how extensible Office really is. ”

The following screenshot shows the default integration as an ODF menu item in the Office button menu with an associated flyout containing the Open and Save commands:

Screenshot of ODF add-in

It didn’t take long for the criticism to start. Rob Weir, for example, critiqued in his blog post that ODF cannot be found in the Save As and Open dialogs nor can be made the default file format.

As this is an UI issue, I decided to take a closer look.

The facts

  • Let me start out with one simple fact: The ODF translator add-in has to make do with what currently exists in the Office 2007 extensibility model. Why?
    • Microsoft is providing ODF support as an add-in, not as a built-in feature. That means, the add-in is limited to what every other Office add-in can do. As it is not a built-in feature, Microsoft was able to announce it as an open source project.
    • Microsoft isn’t going to provide any special MS-only hooks in Office 2007 just to integrate the ODF, PDF & XPS things into it. MS-only hooks would just be a waste of development resources and non-MS add-in developers would want to use them as well (which would be simple due to the open source nature of the ODF translator project). Hence, this is either going to happen through a normal Office 2007 add-in mechanism, or not at all.
  • The Open & Save As dialogs cannot be customized: There simply is no way for an add-in to add another file format to the file type list in those dialogs. I checked this with the Office beta team just to be sure.
  • It is possible to write a custom file import/export converter for Word. This would add the file type supported by the converter to the file type lists in the Open and Save As dialogs. Unfortunately, this is not an option for the ODF translator project. Such a custom converter would convert between RTF and the desired format, which simply misses the point for the ODF translator add-in. For more details, see the respective MS KB article.
  • The ODF translator add-in is therefore limited to what can be done via RibbonX.

Why not provide the ability to customize the Open and Save As dialogs?

  • ODF support was clearly an after-thought for Office 2007. It was announced after the release of Beta 2. Office 2007 was for the most part feature complete with Beta 2 and it is therefore extremely unlikely that Microsoft is going to make any substantial changes to the extensibility model between now and RTM.
  • Why should MS waste resources on providing one particular feature for add-in developers that most Office add-in developers (all not affiliated with Microsoft) would put at the very bottom of their wish list? How many add-ins would actually use such a feature (answer: 3; ODF, PDF, XPS). Sorry, but providing such a feature to satisfy 3 add-ins is a real waste. There is so much missing in Office 2007 from the point of view of an add-in developer, that MS has enough work for the entire next release (after 2007) before even considering the Open & Save As dialogs issue.
  • For more about this, see my blog comment.

The RibbonX side of it

If you download the source code, you’ll find a file named “customUI.xml” in the OdfConverter\source\OdfWord2007AddIn\resources folder. The file contains the RibbonX code that the add-in uses:

ODF add-in RibbonX code

This RibbonX snippet shows how simple the integration of this add-in into the Office button menu is. Let’s see how we can modify this.

The first modification we can easily make is to get rid of the ODF menu and integrate it differently into the menu. The following screenshot shows the Open ODF command directly below the Open command, and integrates the Save as ODF command into the Save As flyout:

ODF add-in shown differently in Office button menu

In order to accomplish this, we’ll need to use the following RibbonX:

RibbonX for modified version

The modification of the splitButton “FileSaveAsMenu” shown above adds an item to the Save As flyout. The “insertAfterMso” attribute specifies the exact position in the flyout menu and in the menu itself. You can see from this example that the order of the items in the XML code doesn’t matter when we use this attribute. The Open ODF button is in the XML below the modification of the Save As flyout, but the button nonetheless right after the built-in Open button.

The only effort required to use this customization is to change the “customUI.xml” file and rebuild the add-in with Visual Studio 2005.

Providing our own Open and Save As dialogs

A much more sophisticated customization is to replace the existing Open and Save As dialogs with our own ones and also to override the Save command. This should never be used for add-ins in an uncontrolled environment, as my UI style guide explains. I would like to discuss the option here though, because of the way I see the ODF add-in being used:

Most average users really don’t care about ODF vs. OpenXML. All they want to do is save their files and they are hardly ever going to change the default file format anyhow. As Brian has pointed out before, ODF doesn’t support all of what OpenXML supports, and hence ODF is not useful for most users as the default file format for Office 2007 (lack of full fidelity).

Most people who will use ODF will do so due to company/agency policy. That means, the ODF add-in will be preinstalled for them by their network administrators. Network administrators can easily change the add-in (one of the benefits of open source) in such a manner that ODF will be the default for open and save. Everyone else who downloads the ODF add-in, will actually know what they are downloading and will have no problem finding it at its prominent location in the Office button menu.

That means, I see this add-in either use in a controlled environment where repurposing is no problem, or by power users who can either choose to use the repurposed version or easily use the menu items in the Office button menu.

In order to override the built-in features and render ODF the de facto standard file format, we’ll need to override three things: Open, Save and Save As. In RibbonX, the result looks like this:

RibbonX for repurposing

You might be wondering about the enabled=”false” in this and all previous RibbonX snippets. The code for saving in the ODF format isn’t implemented yet in the Word add-in that was released on July 5, 2006. Once it is implemented, those attributes can simply be removed. The above RibbonX code assumes that ExportODF handles the different behavior of “Save” and “SaveAs”.

In the C# code of the add-in itself, the signatures for ImportODF and ExportODF need to be changed to:

public void ImportODF(IRibbonControl control, ref bool fCancelDefault)

public void ExportODF(IRibbonControl control, ref bool fCancelDefault)

fCancelDefault determines whether the built-in action is executed after the repurposed action or not. If fCancelDefault is true, then the built-in action will not be executed. For the ODF add-in, fCancelDefault should be returned as true therefore.

This modification changes the default file format of Word 2007 to ODF. At the same time, it doesn’t allow the user to save in any of the built-in file formats. In order to make this add-in behave more realistically, the Open and Save As dialogs in the add-in should include the default file formats and trigger the respective action via the Word object model. In addition, when ODF was chosen as file format, the add-in should disable all functionality in Word that cannot be saved in ODF. This is similar to the Compatibility Mode in Word 2007: When working on a Word 97-2003 file, features that are specific to Word 2007 are not available. I could imagine e.g. that SmartArts would be disabled in an ODF Compatibility Mode. Maybe someone in the community is going to implement such a more advanced add-in and it will be provided as an alternative on sourceforge?

Unloading a 2007 Add-In in Office 2003 (StyleChooser Update)

July 2nd, 2006 by Patrick Schmid

Quick Links

In my initial blog post about COM Add-Ins for Office 2007, I wrote the following:

“The add-in will not only load in Word 2007, but also Word 2003 (I don’t have any earlier Office version so I don’t know if it will load in those as well). As it is specifically geared to 2007 though, there is no point in having the add-in loaded in 2003 as well.”

“In order to be nice to the user, we should therefore automatically unload the add-in if it is not loaded in Word 2007 (or any later version).”

“If the add-in is not loaded in Word 2007, it unloads itself using the Microsoft.Office.Core.COMAddIn.Connect value (setting it equal to false).”

This seemed to work well. However, users in the public Word newsgroup where reporting that the add-in regularly didn’t load anymore when they opened Word 2007. At the same time though, no one in the private beta newsgroups was reporting this particular problem. So what was going on?

The situation only arises in a side-by-side installation of Word 2003 and 2007. Technical beta members might have such a configuration (I do e.g.), but they might also be running 2007 on a dedicated computer or Virtual Machine. Yet even when they have such a configuration, it is unlikely that they open Word 2003 much anymore. This is partially due to the fact that they are probably using Word 2007 mainly by now and also partially due to the fact that opening Word 2003 resets doc file associations and other settings (due to a bug in Beta 2). Restoring this back to 2007 takes 10-15 mins (e.g. by running Office Diagnostics) and everyone therefore tries to avoid it. I for example never open Word 2003 anymore on my desktop at all. Hence no one in the technical beta really encountered the issue.

So what is the issue? When Word 2003 is opened, the add-in unloads itself. However, this changes the LoadBehavior of the add-in from 3 (load at startup) to 2 (disabled). Therefore the add-in is no longer loaded when Word 2007 is opened. After experimenting with this for a while, it seems that the only solution to get rid of this issue is to stop being nice when Word 2003 is opened and simply keep the add-in loaded. V1.3 therefore removes the code that automatically unloads the add-in when a non-2007 version is detected.
Downloads

Word StyleChooser - Optimization & VB.NET

June 16th, 2006 by Patrick Schmid

Quick Links

If you hoped that my last post would have been step-by-step explained how to create a COM Add-In with Visual Studio, then you should consult Microsoft’s Frank Rice’s post of the same day. Ironically, he posted a tutorial on how to create a managed C# COM-Add-In as well. He doesn’t seem to like any comments advertising my blog though, as all of my comments to that effect have been deleted so far.

As promised, I am providing the VB.NET version of the StyleChooser add-in today. Let me first though share with you feedback I received on the first version:

  • There were several setup-related issues. My VS setup project didn’t provide very meaningful information about itself to the user nor did it install itself in the expected folder. Version 1.1 that I quickly posted fixed those issues. (from Bob Buckland)
  • The location of the add-in on the Home tab wasn’t the most useful one. I moved it with V1.1 to the right of the Styles group. (from Bob Buckland)
  • “One of the key advantages of the old dialog was that you could run the width out to full screen so that when you had a style of Normal+Blue+13pt+Tahmoa+Bold you saw all of that when you turned on the option to track formatting. There’s no room for that width in the ribbon, but a tooltip, perhaps?” (from Bob Buckland)
  • “One thing I always disliked about the Styles dropdown is that it didn’t show the type of style. How can users be expected to apply proper styles if they don’t even know if it is a paragraph style or a character style? So maybe it would be possible to add ¶ for paragraph styles, ª for character styles, and ¶ª for those new linked styles?” (from Klaus Linke)
  • “Maybe it could be made to reflect the styles chosen to be displayed in the styles pane… If Word is used properly, that should only show a handful of styles.” (from Klaus Linke)
  • “Any way to assign Ctrl+Shift+S to it?” That shortcut opens the drop-down in Word 2003. (from Herb Tyson)
  • The users that complained about the inadequacy of the style choosing UI in Word 2007 (all of them Word or other MVPs by the way) probably could do without that huge Style group on the Home tab. Therefore it might be helpful to have an option to completely hide the MS Style group.

Conversion to VB.NET

Someone commented to me that VB developers generally don’t read C# examples, whereas C# developers have no problem reading and using VB.NET examples, I’ll switch this add-in to VB.NET only. It’s easier for me as well to maintain one code base only. For C#, you can download the V1.1 source code.

VB.NET can cast objects automatically for you. However, as I am firmly implanted nowadays in the C++/C#/Java world, I am very distrustful of automatic casting. Therefore, my VB.NET code uses “Option Strict On”.

The only surprise I had in converting the code was that VB.NET is not case-sensitive for variable names, while C# is. Took me a bit to remember that and fix the code appropriately. While testing the add-in, I discovered that if you change the style with the Styles Group and don’t move the cursor after that, the text field of the combo box displays the old style still. I looked through the Word Object Model, but couldn’t find any event that would be triggered if the style is changed. Unless someone points me to the correct event, the add-in will always have this issue.

You can download V1.1 of the VB.NET source code.

Changes

Showing the modifications to the current style requires a lot more effort. It seems that the formatting of the selection has to be compared to the formatting of the style and then the differences shown. I don’t see any easier way of doing that. That is a lot of work and therefore I won’t do it this time around.

Adding the information whether a style is a character, paragraph or linked paragraph style is rather straightforward. The information is nicely encoded in the Object Model, so it is only a question of formatting the string returned to Word correctly.

As I mentioned in my last post, the performance of the drop-down list is rather bad. The key performance issue is that the Hashtable containing all styles is created from scratch every time after the control was invalidated (which is after any cursor move, selection change). In order to speed this up, I implemented an optimization strategy. In this new version, the Hashtable is only rebuilt if the number of all styles reported by Word changed. That means, unless a style was removed or added, the Hashtable won’t be rebuilt. The downside is that if the user adds and removes a style without triggering any selection change in between the two operations, the drop-down list won’t reflect this change. Similarly, the drop-down list won’t catch any renaming of styles. The performance gain is so dramatic though that these two handicaps are acceptable.

The drop-down list should reflect the styles that are currently In-Use. However this doesn’t seem to work and might point to a bug in Word 2007 B2.

I still need to look into the shortcut issue.

Replacing the built-in Styles group

Why would a user still need the Styles group, if he or she has this particular add-in installed? For one thing, the user might like to still be able to access the Quick Style gallery and use the functionality provided by the Change Styles menu. That means, if the add-in was to replace the entire Styles group, those two items have to be replicated in order for the user to keep all functionality.

If you read my UI Style Guide post, you should be screaming “NOOO” at this point. I was very explicit about not hiding MS groups and controls, and especially not replacing them. I’ll weaken my own statement at this point a bit. In this case, I can actually replace the Styles group because I expect the users of this add-in to be only power users who know what they are doing. In addition, and even more importantly, the add-in will very visibly tell the user that the MS group is being hidden, and allow the user to change that. Also, the default behavior will be to NOT hide the MS group. This is one of those situations where I will violate the MS-group and the dynamic alteration of the ribbon rule, because anything else is a real waste of ribbon space. I’d love to hear your comments on how this add-in addresses both issues.

RibbonX code

The first change in the RibbonX is that the Styles Group is now included with a “getVisible” callback. This callback will either return true or false, depending on whether the group should be shown or not.

The second change is that I introduced a check box to let the user pick whether to show or hide the MS Styles group. The “getPressed” callback tells Office whether it is checked or not while the “onAction” callback is executed when the user changes the checkmark.

I modified the comboBox slightly as well by introducing the “sizeString” attribute. The comboBox will be as wide as necessary to display that particular string in the text field.

Last but not least, I added the QuickStyles gallery as a large button and the Change Styles button as well. I should note that ChangeStyles is a dynamicMenu and the RibbonX XML Schema requires a dynamicMenu to have a “getContent” callback. As this gallery is provided by Microsoft, I obviously cannot provide a callback function for this, which is why I specified an empty attribute. However, a string of length 0 (”") is not accepted by Office. Therefore the string is of length 1 (” “). Quite corky and I’ll submit a bug on this.

These are all the changes needed in the RibbonX code. I won’t discuss the implementation of the “getVisible” and “getPressed” callbacks, as that is straightforward. The add-in saves the visibility state in the registry and retrieves it from there as well. When the user clicks the checkbox, “onAction” is triggered. “onAction” saves the changed state to the registry and invalidates all my custom UI elements. Therefore all callbacks are executed again and the change in visibility is applied. Apparently Beta 2 still has bugs with the dynamicMenu. Once the “getVisible” callback was executed one time for it, it will not be called again. That means, if you click the checkbox, the “Change Styles” button will stay (if it was visible at startup) or never appear (if it was not visible at startup). Also, it is rather curious that “getVisible” is executed whenever you switch from another window to Word.

Conclusion

As conclusion, I know for sure that I will do all my add-ins in C#. VB.NET is somewhat unwieldly to sue for me. To give you a taste what the add-in looks like, here is a screenshot of the add-in with the Styles group visible:

screenshot of Home tab with Styles group visible

If you hide the MS-group, the Home tab now looks like this:

Screenshot of Home tab with Styles group hidden

All the screenshots were taken on my desktop with a 1280×1024 resolution. The tab will look quite different with a lower resolution.

Downloads

Edited to update setup file to V1.2.1 which runs on .Net Framework 2.0 and supports Vista. No source code changes made

Edited to include workaround for a Word 2007 bug into V1.2.2

“Hello World” in Access, Excel, PowerPoint and Word from a COM Add-In using .NET (C#) - Word StyleChooser

June 14th, 2006 by Patrick Schmid

If you are not interested in the implementation details, you can download the Word StyleChooser add-in directly. If you installed an earlier version this morning, please uninstall that one first. I made a few changes to have the add-in behave nicer. Please note that you need to open the zip file and run setup.exe from there.
I had originally planned to do another “Hello World” example to cover COM Add-Ins, but I decided to rather do something more useful. The example I am going to do here is going to be for Word only. It is going to implement a sorely missing functionality in Word 2007, namely a simply combo box to see the current style and choose another one. Microsoft provides the style gallery and style task pane, but neither one is really useful to heavy users of Word styles. All the RibbonX related topics I will discuss in this example can be transferred straight to Access, Excel and PowerPoint. Outlook has some peculiarities which I will discuss in separate post. Let me apologize to most of you for using C# here. I installed a 400 GB hard drive in my desktop today and currently all my data is being copied over. Unfortunately the hard drive on my Tablet PC has only 40 GB and wasn’t big enough to support C# and VB.NET, which is why I ended up installing only C# (my preferred language). A 100 GB hard drive for my tablet to address this issue arrived today as well, but this will have to wait until my desktop is usable again. I’ll provide the VB.NET source code for this example soon.

For this post, I am going to assume that you know how to create a COM Add-In for Office using Visual Studio .NET. If you don’t know how to do that, consult the Visual Studio help, the MSDN library, an Office programming book or search on Google. I will use Visual Studio .NET 2003.

Getting started

I am going to call this add-in StyleChooser and using the Visual Studio Add-In Wizard, I am making it a Microsoft Word add-in with the full name of “Microsoft Word 2007 StyleChooser Add-In”. In VS 2003, I need to add a reference to the Word 12 PIA as well as the Office 12 Object Library. The Office Object Library reference that the VS add-in wizard added needs to be removed. The Word 12 PIA can be found under the .NET tab and is called “Microsoft.Office.Interop.Word” with the version 12.0.0.0. The Office 12 Object Library can be found under the COM tab and is called “Microsoft Office 12.0 Object Library” with the version 2.4. With these references, the add-in will now load correctly in Word 2007.

Determining the version of Word

The add-in will not only load in Word 2007, but also Word 2003 (I don’t have any earlier Office version so I don’t know if it will load in those as well). As it is specifically geared to 2007 though, there is no point in having the add-in loaded in 2003 as well. For the user, that would be just a waste of memory. Note that the add-in will correctly load in 2003, but do nothing, as 2003 does not retrieve the RibbonX code from the add-in. This is important to know when you want to write an add-in that displays a UI in 2003 and 2007. If it is being loaded in 2003, you need to push the UI to Office. If it is being loaded in 2007, Office will pull the UI from the add-in.

In order to be nice to the user, we should therefore automatically unload the add-in if it is not loaded in Word 2007 (or any later version). We can determine the current version in the OnConnection method. As publishing code via the Word blogging feature isn’t simple, I am not going to show code in the example, but rather refer you to the C# source code file. The version can be determined using the Application.Version method. This returns a string which isn’t necessarily a number. My own add-in in fact kept crashing with Access 2007 B1TR until I realized that the version string returned by Access included the word “Beta” after the version number. Hence the code tries to strip out anything but the major version number (12) and catches any error the number conversion might trigger.

If the add-in is not loaded in Word 2007, it unloads itself using the Microsoft.Office.Core.COMAddIn.Connect value (setting it equal to false).

The code so far loads the add-in into Word 2007 and unloads it if an earlier version is detected. With only this rudimentary code, the add-in can be installed into Word and its presence can be checked via Word Options, Add-Ins.

While developing a COM Add-in, you probably want to run it in debugging mode, which means you want to hit Run in Visual Studio which should then open Word and give you the full VS debugging options for it. If you are, like me, using VS 2003, this won’t work if you have the .NET 2.0 Framework installed. The only currently known workaround for this issue is to uninstall the 2.0 Framework. Microsoft has yet to find a better workaround.

Loading the RibbonX code

In order to load RibbonX code, the add-in needs to implement the IRibbonExtensibility interface. This interface requires the implementation of the string GetCustomUI(string) method. The string argument that is passed to GetCustomUI contains the ribbon ID. You can ignore this argument for Access, Excel, PPT and Word. I will discuss its significance with Outlook.

GetCustomUI needs to return the full RibbonX code as string. In contrast to VBA this allows you to dynamically create the RibbonX code you are returning to Office. I personally prefer to store the entire XML code as a resource file in the add-in instead of some long and cumbersome string in the code. Therefore I added an XML file called RibbonX.xml to the project (make sure to set its build action to “embedded resource”). The code to get the XML from that embedded resource can be found in the GetCustomUI method. The most noteworthy thing here is the string attribute of the System.Reflection.Assembly.GetManifestResourceStream(string) method. It needs to include your add-in name as well as the full file name. In my example it is “StyleChooser.RibbonX.xml”. You should always verify that your resource file is actually being loaded. If you have trouble figuring out the correct parameter, use the code I commented out. I should also tell you that at least with VS 2003, the RibbonX.xml will not be recompiled unless you use “Rebuild Solution”. This means, if you make a change to the file and use “Build Solution”, the change won’t be compiled into your add-in and you’ll be wondering what is going on. Therefore, if you change anything in the embedded RibbonX file, rebuild the solution always.

RibbonX code

The RibbonX code for this example is going to be simple. I will add one group with a combo box and a button to the Home tab. I chose the Home tab, because choosing a style is among the 80% most used functions in Word (as you can tell from the MS-Styles group being on the Home tab). It won’t be pretty, but it will serve its purpose. Following is the RibbonX code for the example:

RibbonX code for StyleChooser add-in

Some of these things are already familiar to you, some are not. New are a bunch of callbacks and the comboBox tag. As I will discuss the callbacks later, let me point out a few attributes to you. You already know the “id”, “idMso”, “label” and “size” attributes. “insertAfterMso” does what its name implies, it inserts the group after the Font group on the Home tab. “screentip” specifies a simple tooltip. If you look at the tooltip for this group, you’ll see the screentip above the line and the supertip will be displayed below it. As I don’t define a supertip, it shows the name of the add-in. “maxLength” specifies the maximum length of a string that a user can input. I set it rather arbitrarily to 50.

About button

The about button is straightforward to implement and similar to the “Hello World” example I showed for VBA. The only difference is that I check this time in the code the id for the control and make sure it is equivalent to the id of the about button. I do this, because I personally prefer to write only one method for each ribbon callback signature and decide within the method on which control to apply it. The about button displays a simple message box. You have to include the Systems.Windows.Forms .NET reference to be able to do this though.

Populating the comboBox

The main goal of the add-in example is to let a user select a style from the list of all styles. The comboBox is supposed to show all styles when the drop down arrow is pressed and show in its field the currently active style.

Let me first insert the information for the currently active style. To do this, we need to use the “getText” callback. From the callback, we need to return the string that is to be displayed in the comboBox field itself. Note that the string has to match a string given to the drop down list, if you want the comboBox to correctly highlight the currently active style in the drop down list. As this is post is not about Word programming itself, please refer to the code to see the details of how the information is obtained from Word.

I also need to fill the entire drop down list with all available styles. To do this we need to implement two callbacks: “getItemCount” and “getItemLabel”. “getItemCount” tells Word how many items the drop down list will contain. “getItemLabel” is called for every single item to determine the string to display. “getItemLabel” will be called back as many times as “getItemCount” specified. Its signature contains an integer which is simply a reference to a zero based array. This means that the add-in itself needs to maintain internally the full drop-down list to display. As styles can be hidden, the example doesn’t reference directly the built-in Word Styles collection, but rather maintains its own styles list.

At this point, I need to introduce the IRibbonControl.Context property. This property is a handle to currently active window. Keep in mind that although Word has only one ribbon, many documents can be displayed at the same time. For each document, there is a different list of styles and a different currently active style. Therefore the add-in needs to account for it somehow. I chose to do that by using a Hashtable that has as key a Document object and as value an ArrayList of strings. When the “getItemCount” is executed, I build the Hashtable for that particular document and then return its count. For each “getItemLabel” callback, I simply access the Hashtable, then the ArrayList stored within and return the appropriately indexed element. Note that the “getItemCount” callback (and subsequently any “getItemLabel” callbacks) is only executed when the user clicks the drop-down arrow.

Reacting to a change in the comboBox

If the user selects a different style in the comboBox, that style should be applied to the current selection. In order to do this, I implemented the “onChange” callback for the comboBox. This callback passes the method the selected text, which can be passed on as is to the Selection.Style property of the Word object model (notice that I had to pass a reference to the object due to a PIA requirement).

Displaying the currently active style

The only problem the add-in has now is that it cannot react to any change in style in the document. For example, if the user moves the cursor to a paragraph that has a different style, this change is not reflected in the comboBox field. In order to be able to reflect the change, the add-in needs to implement the WindowSelectionChange event of the Application object. But what should the event trigger? This is finally where the last of the callbacks comes into play: “onLoad”. The “onLoad” callback is mainly there to give you access to the IRibbonUI object for your add-in. With that object, you can invalidate either all UI elements or just one particular one. Invalidation means that Office considers all values returned by the element’s callbacks to be invalid and also triggers a refresh of those callbacks. In other words, by invalidating a control you force Office to call its callbacks again, but of course only if the particular UI element is currently visible. To finish the add-in, I added the “onLoad” callback and included in that particular callback the statement to add a method to the WindowSelectionChange event. That method has one statement only, namely one to invalidate the comboBox control. If the Home tab is displayed when the event is triggered, Word will reload the text of the comboBox field and therefore display the correct style. You might notice a performance hit when you press the drop-down arrow of the comboBox. Recreating the ArrayList every time the drop-down arrow is pressed is unnecessary and this could be optimized.

Conclusion

I hope this COM add-in example illustrated a lot about RibbonX and COM Add-Ins in Office 2007. There is nothing in this example by the way that could not be implemented using documents or templates and VBA. If you don’t feel like implementing anything yourself, give the binary version of the add-in a try. You can add the comboBox to your QAT by right-clicking the drop-down arrow and choosing “Add to Quick Access Toolbar”.

Downloads

Revisions

  • V1.1 solves some of the setup issues, e.g. the add-in installing itself in weird program files folder (HCT).
  • I changed the location of the group to the right of the Styles group
  • Thanks to Bob Buckland for his helpful suggestions and comments!
« Previous PageNext Page »