The Office Developer Resources Ribbon UI Add-in

The Microsoft Office Developer Center (ODC) ( contains a tremendous number of how-to articles, videos, code samples, and so forth to help you create Office solutions. The menus and links on the ODC are pretty handy for navigating the labyrinth of helpful information. However, I thought it might be helpful to create a tab on the Ribbon UI that enables you to get to this information from inside of Word 2007.

I created a Visual Basic .NET shared add-in in Visual Studio that creates a tab on the Word 2007 Ribbon. The tab is divided into groups that somewhat mirror the tabs found on the ODC. The groups contain buttons and gallery controls that contain links to different pages in the ODC. As with any custom Ribbon customization, the add-in contains an XML file that defines the structure and components that make up the tab. The add-in also contains callbacks that give the controls their functionality.

Note The add-in is available at:

Figure 01. The Office Developer Resources tab in Word 2007

Figure 02. The Office Developer Resources tab in Word 2007 - continued

In this posting, I won’t go into the steps to create the add-in. You can find detailed procedures for creating a shared add-in to customize the Ribbon UI in the three-part series of articles titled Customizing the 2007 Office Fluent Ribbon for Developers ( I will provide the XML and the VB .NET code for the callbacks which you can substitute for those found in the articles.

The XML is relatively simple in that it consists of a number of repetitive groups containing buttons and a couple of gallery controls. The buttons provide links to the different page on the ODC. The galleries provide a selection of related links to the developer centers for the Office 2007 products and the technologies that use or are used by the Office system such as Office Business Applications (OBA) and the Open XML file format.

<customUI xmlns="" loadImage="getVSTOImage" >



<tab id="odcTab" label="Office Developer Resources" >

<group id="getStartedGrp" label="Getting Started" >

<button id="devCenterBtn" label="Office" size="normal" getImage="getImages" tag="" onAction="openPage" screentip="Learn about the possibilities offered by the Microsoft Office system to develop solutions." />

<button id="spBtn" label="SharePoint" size="normal" getImage="getImages" tag="" onAction="openPage" screentip="Helps teams stay connected and productive by providing easy access to the people, documents, and information that they need." />

<button id="devMapBtn" label="Developer Map" size="normal" imageMso="ShowTimeZones" tag="" onAction="openPage" screentip="Helps you visualize the different programs, servers, services, and tools that will help build Office solutions." />


<group id="productsGrp" label="Products and Technologies" >

<button id="officeSysBtn" label="Office System " size="normal" getImage="getImages" tag="" onAction="openPage" screentip="A powerful collection of integrated programs, servers, services, tools, and technologies." />

<gallery id="productsGal" label="Products" size="normal" imageMso="SmartArtChangeColorsGallery" onAction="galOpenPage" screentip="Get the help and information you need on each Office product." >

<item id="Access" label="Access" imageMso="MicrosoftAccess" />

<item id="Excel" label="Excel" imageMso="MicrosoftExcel" />

<item id="InfoPath" label="InfoPath" imageMso="OpenInfopathForm" />

<item id="Outlook" label="Outlook" imageMso="MicrosoftOutlook" />

<item id="PowerPoint" label="PowerPoint" imageMso="MicrosoftPowerPoint" />

<item id="Project" label="Project" imageMso="MicrosoftProject" />

<item id="SPDesigner" label="SharePoint Designer" imageMso="AccessOnlineLists"/>

<item id="SharePoint" label="SharePoint Server" imageMso="FileCreateDocumentWorkspace" />

<item id="Visio" label="Visio" imageMso="TableExportTableToVisioPivotDiagram" />

<item id="Word" label="Word" imageMso="ExportWord" />


<gallery id="technologiesGal" label="Technologies" imageMso="PageMenu" onAction="galOpenPage" screentip="Learn about the technologies supported by the Microsoft Office system." >

<item id="OBA" label="OBA" imageMso="CreateClassModule" />

<item id="FluentUI" label="Office Fluent UI" imageMso="FormRegionMenu" />

<item id="OpenXML" label="Open XML" imageMso="FileSaveAsCurrentFileFormat" />

<item id="VBA" label="VBA" imageMso="CreateModule" />

<item id="VSTO" label="VSTO" image="VSTO" />



<group id="libraryGrp" label="Library" >

<button id="offSysBtn" label="Office Development" size="normal" imageMso="AppointmentColorDialog" tag="" onAction="openPage" screentip="A set of helpful links to get you up to speed on Office development." />

<button id="spDevBtn" label="SharePoint Development" size="normal" imageMso="AccessOnlineLists" tag="" onAction="openPage" screentip="A set of helpful links to get you up to speed on SharePoint products and technologies." />

<button id="officeTalkBtn" label="Office Talk" size="normal" imageMso="MailSelectNames" tag="" onAction="openPage" screentip="Columns by long-time Office developers and members of the Office Developer Documentation team." />


<group id="learnGrp" label="Learn" >

<button id="offDevelopmentBtn" label="Learn Office" size="normal" imageMso="AppointmentColorDialog" tag="" onAction="openPage" screentip="Explore this set of helpful links to get you up-to-speed creating Office system solutions." />

<button id="sdkAndRefDocsBtn" label="SDKs and References" size="normal" imageMso="FunctionsLookupReferenceInsertGallery" tag="" onAction="openPage" screentip="Use these SDKs and developer references to leverage your skills in creating rich Office and SharePoint solutions." />

<button id="booksdBtn" label="Books" size="normal" imageMso="VisualBasicReferences" tag="" onAction="openPage" screentip="Want to buy a book? Read a sample chapter online? Visit this bookstore first." />

<button id="howDoIBtn" label="How To Center" size="normal" imageMso="TentativeAcceptInvitation" tag="" onAction="openPage" screentip="Find over 200 how-to video demos, sample code, and conceptual overviews." />

<button id="videosBtn" label="Videos and Webcasts" size="normal" imageMso="SlideMasterMediaPlaceholderInsert" tag="" onAction="openPage" screentip="Need information quickly? No time to read about it? Watch these videos." />

<button id="channel9Btn" label="Channel 9" size="normal" getImage="getImages" tag="" onAction="openPage" screentip="Channel 9 is a place for learning and sharing information, created by developers for developers." />


<group id="communityGrp" label="Community" >

<button id="communityBtn" label="Office Developers" size="normal" imageMso="OutlookGears" tag="" onAction="openPage" screentip="Check out the latest from the Office developer community." />

<button id="mvpBtn" label="MVP Content" size="normal" imageMso="MeetingsWorkspace" tag="" onAction="openPage" screentip="Take a look at the latest content submitted by Office and SharePoint MVPs, third-parties, and experts in the Office developer community." />

<button id="codePlexBtn" label="CodePlex" size="normal" getImage="getImages" tag="" onAction="openPage" screentip="Provides you with access to a variety of resources, including download areas, communication forums and product information." />

<button id="codeGalleryBtn" label="Code Gallery" size="normal" getImage="getImages" tag="" onAction="openPage" screentip="Download and share sample applications, code snippets, and other resources with the developer community." />

<button id="facebookBtn" label="facebook" size="normal" getImage="getImages" tag="" onAction="openPage" screentip="A place for comments, questions, and answers about development with Office products." />

<button id="twitterBtn" label="Twitter" size="normal" getImage="getImages" tag="" onAction="openPage" screentip="Follow what is currently happening with Microsoft Office development." />


<group id="supportGrp" label="Forums and Support" >

<button id="forumsBtn" label="Forums" size="normal" imageMso="WorkgroupAdmin" tag=",oldevelopment,sharepoint,uc/" onAction="openPage" screentip="Get your questions answered by experts in their respective Office products." />

<button id="newsgroupBtn" label="Newsgroups" size="normal" imageMso="FileCreateDocumentWorkspace" tag="" onAction="openPage" screentip="Ask questions, share information, or exchange ideas with others, including experts from around the globe." />

<button id="supportBtn" label="Support" size="normal" imageMso="ControlsGallery" tag="" onAction="openPage" screentip="Search to find a resource, ask a question in the forums, or contact Microsoft support for help." />






In looking at the XML, I handled the links to the Web pages in two ways, depending on whether I was using a button or a gallery item. For buttons, I added the link to the tag attribute inside the button definition XML. Then, I specified a callback in the onAction attribute where all I did was run Internet Explorer and pass the button’s control.tag value, as shown here.

Private Const ie As String = "c:\program files\internet explorer\iexplore "

Sub openPage(ByVal control As IRibbonControl)

Dim RetVal As Object

RetVal = Shell(ie & control.Tag, vbMaximizedFocus)

End Sub

In the gallery control, there is no tag attribute so I had to use a different technique. When you click an item in the gallery, a callback, specified in the onAction attribute of the gallery control, is called passing in an IRibbonControl object, which represents the control that made the call. The IRibbonControl object includes the Id property. In the callback, I test the control’s Id property in a Select Case statement and assign the Web page address value for that control to a String variable. Following the Select Case statement, just as in the previous code sample, I run Internet Explorer, passing the constant for the Web address and page value of the specific Web page.

Private Const address As String = ""

Sub galOpenPage(ByVal control As IRibbonControl, ByVal id As String, ByVal index As Integer)

Dim RetVal As Object = Nothing

Dim page As String = ""

Select Case id

Case "Access"

page = "aa905400.aspx"

Case "Excel"

page = "aa905411.aspx"

Case "InfoPath"

page = "aa905434.aspx"

Case "Outlook"

page = "aa905455.aspx"

Case "PowerPoint"

page = "aa905465.aspx"

Case "Project"

page = "aa905469.aspx"

Case "SharePoint"

page = "aa905503.aspx"

Case "SPDesigner"

page = "bb421303.aspx"

Case "Visio"

page = "aa905478.aspx"

Case "Word"

page = "aa905482.aspx"

Case "WSS"

RetVal = Shell(ie & "", vbMaximizedFocus)

Case "OBA"

page = "aa905528.aspx"

Case "FluentUI"

page = "aa905530.aspx"

Case "OpenXML"

page = "aa905545.aspx"

Case "VBA"

RetVal = Shell(ie & "", vbMaximizedFocus)

Case "VSTO"

RetVal = Shell(ie & "", vbMaximizedFocus)

End Select

' You have already run the shell on these cases.

If (id <> "VBA" And id <> "WSS" And id <> "VSTO") Then

RetVal = Shell(ie & address & page, vbMaximizedFocus)

End If

End Sub

You will notice that I handled the Case statements for three of the controls slightly differently. The addresses for those sites were different than those for the other controls, so I couldn’t use the same address constant.

The next task concerns the images shown for each button and gallery item. As you can see in the XML, the majority of the buttons and gallery items use images built into Office as denoted by the imageMso attribute. However, for the remaining Bitmap images, I first added them to the add-in as project resources. How to do this is also described in Part One of the three-part series of articles I mentioned previously.

There are a couple of ways to add custom images to the Ribbon and I use both here. The most common way is to use the loadImage attribute of the <customUI> element and point to a callback that loads the images. By using this method, all of the images are loaded once when the Ribbon is displayed. Then, all you need to do to use a particular image for a control is use the image attribute and assign the name of one of the images to it. The following callback is used to load the image for the VSTO item in the Technologies gallery.

Function getVSTOImage(ByVal imageId As String) As IPictureDisp

Return PictureConverter.IconToPictureDisp(My.Resources.VSTO)

End Function

I used this callback for just the VSTO item because the gallery item attribute does not include a getImage attribute (I will use that attribute in the next section). So to summarize, the image is loaded when the Ribbon is displayed and the image attribute specifies which image to display for the control. Note that the image has to be returned to Office as an IPictureDisp object. I’ll show how the image is converted shortly.

The other way to load custom images is by using the getImage attribute of the button to point to a callback that individually loads the images. Similar to the way I assign Web page links to the various buttons, in the getImages callback pointed to in the getImage attribute, I use a Select Case structure to test the Id property of the IRibbonControl object and return the image appropriate to the control.

Function getImages(ByVal control As IRibbonControl) As IPictureDisp

Select Case control.Id

Case "devCenterBtn"

Return PictureConverter.IconToPictureDisp(My.Resources.MSDN)

Case "spBtn"

Return PictureConverter.IconToPictureDisp(My.Resources.MSDN)

Case "officeSysBtn"

Return PictureConverter.IconToPictureDisp(My.Resources.officesystem)

Case "codePlexBtn"

Return PictureConverter.IconToPictureDisp(My.Resources.CodePlex)

Case "codeGalleryBtn"

Return PictureConverter.IconToPictureDisp(My.Resources.CodeGallery)

Case "channel9Btn"

Return PictureConverter.IconToPictureDisp(My.Resources.Channel9)

Case "twitterBtn"

Return PictureConverter.IconToPictureDisp(My.Resources.twitter)

Case "facebookBtn"

Return PictureConverter.IconToPictureDisp(My.Resources.facebook)

Case Else

Return PictureConverter.IconToPictureDisp(My.Resources.officesystem)

End Select

End Function

To convert the image to the IPictureDisp object required by the Ribbon, I added the following class to the add-in project. More information about this class is also included in Part One of the article series.

Friend Class PictureConverter

Inherits AxHost

Private Sub New()


End Sub

Public Shared Function IconToPictureDisp(ByVal icon As Bitmap) As stdole.IPictureDisp

Return CType(GetIPictureDispFromPicture(icon), stdole.IPictureDisp)

End Function

End Class

And so that is all there is to it. Hopefully you will find this add-in helpful.