Unmanaged Visio

22 August 2009

Getting started with Visio Ribbon

This post explains how one can customize Visio 2010 Ribbon from Visio add-in (and is based on Visio CTP). Namely, it shows how to add a custom tab to the Visio ribbon.

Download C# sample project (VS 2008 solution, 12 Kb)

Download C++/ATL sample project (VS 2008 solution, 19 Kb)

Though Visio has been resistant to innovations in user interface for quite a long time (just remember those 16-color icons in the stencils), it seems that finally "the time has come", and the ribbon interface has won the game. I started this project to estimate the amount of work one needs to adopt his add-in to the new Ribbon interface. I should mention that old CommandBars API that was normally used for user interface customization does still work for new Visio 2010; the point is that it just looks a bit unnatural, and kind of unnatural.

The way it looked in Visio 2007, native toolbar and menu: image

If you won’t do a thing, then in Visio 2010 you’ll get something like: image If you ask me, this doesn’t look like an exciting user experience… No transparency, no fancy 32-bit images, all custom toolbars (from all add-ins) are put to the “Custom Toolbars” group, all custom menus (from all add-ins) are put into “Menu Commands”, etc, etc… Wouldn’t it be much better if we make it look like that? image Here is list of materials about Office ribbon customization (though these are 2 years old and were written for Word 2007 and alike, now they became valid for Visio as well):

Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)

Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)

Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Using RibbonX with C++ and ATL

So, I started from here, and adopted the code from the last article for Visio (both C# and C++/ATL variants). The basic idea is that to allow custom Ribbon, you just need to implement the IRibbonExtensibility interface in your add-in. Like that:

public class Connect
   : Object
   , IDTExtensibility2
   , Office.IRibbonExtensibility   // <-- add this for ribbon
{

   // Here you shall return the XML description of the custom ribbon part
   public string GetCustomUI(string RibbonID)
   {
       return Resource.RibbonXML;
   }

   // this is called (by name) when ribbon button is cliecked
   public void ButtonClicked(Office.IRibbonControl pButton)
   {
       System.Windows.Forms.MessageBox.Show(string.Format(
           @"Hello from the ribbon, the button ""{0}"" clicked!"
           , pButton.Id));
   }

The tricky part here is the XML you return. Hopefully Microsoft will release some tools for Visio ribbon with the next release of the Microsoft Tools for Office (or Visio SDK?), but for now there is nothing about Visio Ribbon. So you have to “master” XML by yourself. But since Ribbon is supported for other office applications, I just opted to create a project of type "Excel 2007 Add-In" (Microsoft Tools for Office template, but for Excel), used “Add New Item” to add a new item of type “Ribbon (Visual Designer)”. In such a way I was able to edit my ribbon using visual designer and then use the designer-generated XML file with Visio add-in. Again, hopefully this will “change to normal” when Microsoft issues updated version of Tools for Office, but unfortunately I believe that for unmanaged code there is no hope of Visual ribbon designer, so this “technique” might be still useful as a “last resort” who dares to write unmanaged code nowadays... So, this is how the ribbon the looks in ribbon designer: image From the designer, one can generate the XML using “Export Ribbon to XML” command: image This produces the XML that can be returned from the “GetCustomUI” method. In my project, I just opted to include generated XML file as a resource.

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
 <ribbon>
   <tabs>
     <tab id="Tab1" label="MyAddin">
       <group id="Group1" label="My Addin Commands">
         <button id="HappyFaceButton" imageMso="HappyFace"
           onAction="ButtonClicked" label="Click Me!" size="large" />
       </group>
     </tab>
   </tabs>
 </ribbon>
</customUI>

As for the unmanaged code, the things might become just a bit more tricky. One clog is implementing 2 interfaces, both inheriting from the IDispatch (one is a callback interface, used for responding to events, and the second is that IRibbonExtensibility). Fortunately enough these points are discussed in details in the article “Using RibbonX with ATL”.

In the future, I hope to post some article about updating user interface dynamically with Ribbon (enabling/disabling buttons or menu items dynamically at runtime) add using custom images with Visio ribbon (this might be a bit tricky).

Labels: , , , ,

1 Comments:

Post a Comment

Subscribe to Post Comments [Atom]



<< Home