This morning, we publicly revealed the existence of Microsoft Office Labs and made a few of their experiments available for download.
Office Labs is a small offshoot of the main Office product team dedicated to producing experiments and prototypes designed to test out certain ideas. Chris Pratley called their charter building "concept cars," and that seems like as good a metaphor as any.
This is how it has worked so far: we meet together every few months and brainstorm ideas for what prototypes might be interesting or fun to build. The ideas are prioritized, and based on these priorities and the scale of the projects, they decide which ones to build next. Then, a small team of developers and designers from Office Labs work together to actually design and build out the experiments.
Sometimes, the process of building a prototype is itself enough to teach people what they hoped to learn. In other cases, the experiments are shared around (sometimes narrowly, sometimes more broadly) because the valuable learning occurs through seeing how people interact with the prototype.
You can read more about all of this on the Office Labs web site, http://officelabs.com. Chris Pratley explains much better the idea behind Office Labs than I could on the new Office Labs blog.
You can test drive some of the concept cars
One of the cool things about Office Labs is that occasionally they're going to release a few of the experiments into the wild. In particular, sometimes they need to get data from people beyond the internal Microsoft community, and putting up prototypes for people to try out is a great way to get that feedback.
Of the dozen or so experiments Office Labs is playing with currently, they've chosen a few for their initial public posting, These are totally unsupported: they might not work for you, and they're not designed to showcase or portend any particular future directions for the Office product.
Search Commands
Among the first batch of experiments uploaded today is one called Search Commands.
Application user interfaces (such as Office) have primarily provided a browse-based UI for accessing functionality. You can trace this back to the advent of pull-down menus at Xerox PARC in the 1970s.
On the web, though, browse has been augmented by search as a first-class way to access not just information and data, but also functionality. People use browse and search together to successfully use most sites.
Search, to the extent it has been used in application user interfaces, is generally relegated to the help system. You search in help, and it gives you instructions on how to use the browse-based UI to access the feature you're looking for.
Search Commands is a prototype to try to better understand the advantages and disadvantages of search as an additional way to directly access features in software. Office happens to be the vessel they built the experiment into because 1) Office has a vast feature set 2) Office has a lot of users 3) the Ribbon offered a very extensible user interface platform on which to build the prototype.
But you could imagine doing the experiment inside of any piece of software with a sufficiently large feature set.
When you install the Search Commands prototype on top of Office 2007, you'll get an additional Ribbon tab called "Search Commands."
Search Commands tab - Click to enlarge
The most prominent control on this tab is the search box. Type in the name of the feature you're looking for, and a set of possible feature matches show up next to the search box. You can type the number next to the command or click on it to execute it directly.
For instance, if I searched for "translate" this is what it would look like:

After I've typed "translate" into the search box - Click to enlarge
I could then press "2" or click the button to translate the selected text.
Anyway, you get the idea of the concepts this prototype was designed to explore. The Office Labs folks put up a movie that shows how it works in more depth than my simple screenshots. You can also read all of the caveats about the prototype and then discuss it on the Office Labs web site.
Experiments are not products
Remember that the Office Labs prototypes do not in any way indicate features or planned directions for future versions of Office. Search Commands, for instance, is a search-oriented research project that just happens to use Office as its vessel.
In fact, work on the Search Commands prototype predates the Office 2007 UI entirely (and it would have been every bit as interesting of an experiment on top of the Office 2003 or Adobe Photoshop UI.)
In the coming months and years, the Office Labs folks plan to continue to trickle parts of their work up for you to sample and give feedback on, and we'll continue to work with them on dreaming up new experiments.
They've got some cool things in the hopper, and I hope many of them eventually work their way outside of Microsoft's walls.
I was reading through commentary from people who attended last week's MIX conference in Las Vegas. Running across Miguel de Icaza's kind words reminded me that I hadn't posted a follow-up about my MIX talk yet.
Last week, I presented a session at MIX called "The Story of the Ribbon." I talked a bit about the general design process we used to come up with the Office 2007 user interface, to iterate on it, and to evaluate it. As part of the discussion, I showed for the first time some of the early prototypes we worked on (and abandoned or refined) along the way.
It's always fun to present substantially new content, and this was my first time giving large portions of this talk. The audience was great and, although you can't hear them on the video, they seemed to be into it and enjoying the presentation. It was a lot of fun!
Download "The Story of the Ribbon"
(Windows Media, 146 MB)
Alternate Formats:
Download for iPod
(.mp4, 121 MB)
Download the PowerPoint slides only
(.pptx, 20 MB)
Dowload the slides only as a PDF
(.pdf, 19 MB)
Although I showed a few prototypes, I truly only scratched the surface of what the team created during the design phase of Office 2007. I spent a weekend painstakingly going through thousands of pictures to choose a few representative samples to show. Because I only had 75 minutes, I knew clicking through 25,000 pictures probably wasn't going to work.
Here are photos of the beginning and the end of the talk courtesy of Long Zheng. (You'll have to watch the presentation to see what's in-between!)
Over the last few days, the screenshots of the evolution of Word from version 1.0 to 2003 have been lifted from this presentation and subsequently posted and reposted all over the web.
That's OK, but if you want to see the full, original screenshots along with the commentary and discussion, please read parts 2, 3, and 4 of the Why the UI? series of posts.
While at MIX, I also participated in a panel discussion called "What's the Secret Formula?" along with Mike Schroepfer from Mozilla, Dan Harrelson from Adaptive Path, and Daniel Makoski from the Surface team at Microsoft. This was an interesting discussion about some of the challenges inherent in delivering on great user experiences.
Watch "What's the Secret Formula?"
Thanks to everyone who came up and introduced themselves after the session and throughout MIX. I enjoyed talking to you and meeting so many of you face-to-face!
Just a short note to let you know that I'll be presenting a new session during MIX in Las Vegas on Friday, March 7 at 10:00 entitled "The Story of the Ribbon."
In this session, I'm going to present the story of the Ribbon--the customer problems that we were aiming to solve by designing a new user interface for Office, the prototypes we considered (but abandoned), the mistakes we learned from along the way, and the principles we used to create the Office 2007 user interface.
It will be informal narrative, with lots of pictures and screenshots--my perspective as a member of the team who worked on the user interface from day one until the day we shipped. My goal is to keep it light and fun, but hopefully also to share many of the lessons we learned along the way.
The session is part of MIX UX, a three-day user experience track which is new to MIX08.
I'm also going to be participating in a panel discussion on Wednesday, March 5 at 3:00 called "What's the Secret Formula?" This discussion will be focused on how to overcome the challenges seemingly inherent in creating software with a great user experience. I'll be sharing the panel with participants from Mozilla, Adaptive Path, and elsewhere at Microsoft. It should be fun.
If you're at MIX, I'd love to chat, so please feel free to come by and introduce yourself. I hope to meet some of you in person either at my sessions or elsewhere at MIX!
More information about all the great MIX content is on the MIX08 web site.
It's been a while since I last wrote in this space.
Many of you have been kind enough to send me e-mail sometime in the last few months, making sure that I was OK and wondering if I was planning to write here anymore. Was I abducted by aliens? Put into witness protection? Muzzled for something I said?
Nah. The truth is less interesting than any of the theories.
A couple of things, both work-related and personal, have conspired to monopolize my time over the last few months and leave me little time for blogging.
First of all, we shipped Office 2007. A great milestone for the team, but I spent a lot late 2006 and early 2007 talking to people about the UI and the story of how it was created: journalists, customers, marketing folks, etc. This is fun stuff, but time-consuming.
Second, we never rest at Microsoft, and when we finish a product, we're immediately on to the next thing. I stepped up to a new role within the Office User Experience team, and we've been hard at work for the last six months planning the next release of Office. The early stages of a release are both exhausting and exhilarating--going from "anything's possible" to "exactly what code should be written." This is an intensive period of brainstorming and designing, and it has taken time away from the blog. After all, if we don't design a compelling product now, there's not going to be much for me to write about in the future...
That said, I do plan to write (albeit less frequently) between now and the time down the road when we start talking publicly about the next release of Office. I'm going to make good on my promise to show early prototypes of the Office 2007 UI, and I'll continue to write about usability and interaction design as well.
Whether it will be interesting or not, that remains to be seen... but I'm officially Not Gone.
Today's Guest Writer: Eric Faller
Eric is a Software Design Engineer on the Office User Experience team focused on user interface extensibility for Office developers.
Another source of frequently-asked RibbonX questions is around the complexity of writing an add-in in C++. Compared to the ease of use of C# or VB.NET, C++ requires a much deeper understanding of what's really going on under the covers and often involves hand-implementing much of the "magic" that the higher-level languages take care of automatically.
This post covers the details of RibbonX's communication with COM add-ins via the IRibbonExtensibility and IDispatch interfaces and shows an example of creating an add-in with ATL. It's primarily intended for C++ developers, but if you're writing an add-in with .NET you may find it useful to understand what the CLR is automatically doing for you under the hood.
IRibbonExtensibility
As soon as Office boots up a COM Add-In, it checks if it implements the IRibbonExtensibility interface on its main Connect class via a QueryInterface() call for IID_IRibbonExtensibility (defined in the MSO.DLL typelibrary). If it does, it takes the IRibbonExtensibility pointer and QI's it for the IDispatch interface and saves both pointers off in a safe place.
Note that Office queries the IRibbonExtensibility interface for IDispatch, instead of the main interface. Normally this is unimportant, but it allows complicated add-ins to split their IDispatch interfaces off onto multiple objects if they provide multiple IDispatch implementations. For example, Excel add-ins can provide User-Defined Functions (UDFs) via IDispatch, and they usually won't want to have all of their RibbonX callbacks and UDFs on the same object.
Next, RibbonX will call the IRibbonExtensibility::GetCustomUI() method and get the XML for each type of Ribbon that's currently open. Most applications have only one Ribbon that's open all the time (Word, Excel, PowerPoint and Access), but Outlook has many different Ribbon types, any number of which can be open at a given time. GetCustomUI() can be called at arbitrary points after the add-in boots if the user opens up a new type of Ribbon, so add-ins should not do any extraneous processing inside that function or assume that it will always be called immediately after the add-in boots. GetCustomUI() should simply fetch and return the appropriate XML, without any side effects.
Once the appropriate XML is parsed and applied, RibbonX will invoke the add-in's "onLoad" callback (if it exists), as well as any "get" callbacks (such as getEnabled, getVisible or getLabel). These callbacks are all invoked via the IDispatch pointer that was queried for above.
IDispatch
If you're unfamiliar with IDispatch-based interfaces, you may be curious how it is that Office can call arbitrary C++ functions in an add-in, given only their names. For example, consider a button specified with this XML:
<button id="MyButton" onAction="ButtonClicked"/>
In my add-in I can write a ButtonClicked() function, but once it's complied and linked, the "ButtonClicked" name is optimized away and we're left with just a memory address where the function's code begins. How does Office find and call the function? Obviously there's something magic going on, and it's known as IDispatch.
IDispatch is a COM interface used for "dispatching" function calls to objects when their types are unknown or need to be late-bound. It's the reason that this VBA code works even though the "word" variable is not strongly typed:
Dim word
Set word = Application
word.CheckSpelling ("misspellled")
The IDispatch interface contains a whole bunch of methods which you can read all about in the documentation, but the main two to be concerned with are GetIDsOfNames() and Invoke().
The GetIDsOfNames() method provides a mapping between names (strings) and "DISPIDs", which are basically integers that represent functions or properties. With the example button above, Office will call into the add-in's GetIDsOfNames() method and ask "hey, do you implement the ButtonClicked function?", and the add-in with either say "yes I do, and it's DISPID number 2" (for example), or "no, I don't implement that function."
Once the function is found, the IDispatch::Invoke() method is used to actually call the function. Invoke() takes the DISPID of the function, an array of parameters, and gets the return value back. In our example Office will call the add-in's Invoke() method and say "call your ButtonClicked function with this IRibbonControl parameter and let me know how it goes."
Parameters and return values are passed around in VARIANT structs, which are basically big unions that can contain values of many different types. We could go into lots of detail about how to set up and use VARIANTs, but fortunately there are ATL classes that take care of all of this for us so there's normally no reason to worry about them.
That pretty much sums up the high-level overview of how IDispatch works, so let's see it in action and build a simple RibbonX add-in in C++ with ATL.
Building a simple C++/ATL RibbonX add-in
The steps for creating a C++ RibbonX add-in start off pretty much the same as for a C# add-in:
- Open up Visual Studio
- Click "New Project"
- Select "Extensibility" under "Project types" and choose "Shared Add-in"
- Give it a name and click OK:

Click to view full picture
- Click through the wizard that shows up, making sure to check "Create an Add-in using Visual C++/ATL" and "I would like my Add-in to load when the host application loads."
Now you have an empty C++ add-in. Click "Build Solution" just to make sure that it all compiles OK with no problem.
Next, open up Class View, right-click on your CConnect class and select "Add -> Implement Interface…" In the dialog that pops up, select the "Microsoft Office 12.0 Object Library <2.4>" type library and add the "IRibbonExtensibility" interface from it:

Note: you may have an older type library registered instead (such as "Office 11.0 Object Library") if you previously had older versions of Office installed on the same computer. In those cases you can just browse to the "OFFICE12" version of MSO.DLL and select it manually.
Once you're done with that, Visual Studio should have auto-generated your GetCustomUI() function for you. Delete its "return E_NOTIMPL;" and paste in some valid code, like this:
STDMETHOD(GetCustomUI)(BSTR RibbonID, BSTR * RibbonXml)
{
if (!RibbonXml)
return E_POINTER;
*RibbonXml = SysAllocString(
L"<customUI xmlns=\"http://schemas.microsoft.com/office/2006/01/customui\">"
L" <ribbon>"
L" <tabs>"
L" <tab id=\"CustomTab\""
L" label=\"Custom Tab\">"
L" <group id=\"CustomGroup\""
L" label=\"Custom Group\">"
L" <button id=\"CustomButton\""
L" imageMso=\"HappyFace\""
L" size=\"large\""
L" label=\"Click me!\""
L" onAction=\"ButtonClicked\"/>"
L" </group>"
L" </tab>"
L" </tabs>"
L" </ribbon>"
L"</customUI>"
);
return (*RibbonXml ? S_OK : E_OUTOFMEMORY);
}
Now, a real add-in would obviously not hard-code its XML like this (embedding it as a resource in the DLL would be much better), but this suffices for our simple demo. Don't do this at home!
At this point we should try to compile the add-in and see our dummy button sitting on the Ribbon. Unfortunately when I tried compiling at this stage, there were several compilation errors in the auto-generated code due to namespace conflicts between the MSO type library and other Windows headers. I did these things to fix it:
- Open up "stdafx.h" and move the #import statement for MSO.dll from the bottom of the file up next to the #import statement for the Extensibility library inside the #pragma blocks (remove any 'no_namespace' annotations from that line as well)
- Add "using namespace Office;" to the top of the Connect.h file.
Now we can build successfully and see our button:

If we click it we get an error saying "The callback function 'ButtonClicked' was not found," which makes sense since we haven't written that function or implemented it via IDispatch yet. Let's use ATL to do that now.
Unfortunately Visual Studio 2005 doesn't seem to have a "New ATL Interface" wizard, but we can get the same thing accomplished by creating a generic ATL class and then deleting the implementation. Click "Add Class…" on the Standard Toolbar and select "ATL Simple Object" in the ATL category. Name the object something like "CallbackInterface" and hit Finish.
Now in Class View we have several new objects: an ATL interface called "ICallbackInterface" and an implementation class called "CCallbackInterface." We don't need the implementation, so go ahead and delete all the CallbackInterface.* files from the Solution Explorer. ICallbackInterface is what we care about and it's defined in our add-in's IDL file.
Back in Class View, right-click on ICallbackInterface and select "Add -> Add Method…" In the Add Method Wizard, add a method named "ButtonClicked" with one [in] parameter of type IDispatch* called RibbonControl:

This parameter is the IRibbonControl object that's passed to all RibbonX callbacks. Since "IRibbonControl" isn't in the parameter type dropdown, we have to go with its base type, which is IDispatch (IRibbonControl is not a type supported by the VARIANT structure). If we need it later, we can always call QueryInterface() on it with IID_IRibbonControl and get it.
Now that our interface is defined, right click on the CConnect class and select "Implement Interface…" again to add ICallbackInterface along with IRibbonExtensibility. Double-click the ButtonClicked function in Class View to be taken to the auto-generated implementation. Swap out its placeholder content with something meaningful, like this:
STDMETHOD(ButtonClicked)( IDispatch * RibbonControl)
{
// Add your function implementation here.
MessageBoxW(NULL,
L"The button was clicked!",
L"Message from ExampleATLAddIn",
MB_OK | MB_ICONINFORMATION);
return S_OK;
}
Now when we compile we should see this MessageBox when we click the button. However, there are a couple of problems left before we can do that, the first of which is "error LNK2001: unresolved external symbol _LIBID_ExampleATLAddInLib." Since our DLL is both the source and consumer of our new typelibrary for ICallbackInterface, we need to link in the MIDL-generated C files for it. In Solution Explorer, add the "AddIn_i.c" file, which is the output from running MIDL on our AddIn.idl file. This new file will inherit the solution defaults for PCH files ("Use Precompiled Headers (/Yu)"), which isn't what we want, so right-click on it and switch the file to "Not Using Precompiled Headers".
The last work item is to set up the COM_MAP to properly route the IDispatch calls to our ICallbackInterface. In Connect.h, switch the IDispatch line in the COM_MAP to ICallbackInterface instead of IRibbonExtensibility:
BEGIN_COM_MAP(CConnect)
COM_INTERFACE_ENTRY2(IDispatch, ICallbackInterface)
COM_INTERFACE_ENTRY(AddInDesignerObjects::IDTExtensibility2)
COM_INTERFACE_ENTRY(IRibbonExtensibility)
COM_INTERFACE_ENTRY(ICallbackInterface)
END_COM_MAP()
Once that's all built, try out the add-in and see that it works!

That's basically all there is to making a C++ RibbonX add-in with ATL. Obviously a more complicated add-in would have many more callbacks, but the only additional work would be to right-click on ICallbackInterface and select "Add Method.." for each one. Different types of callbacks have different parameters, so you just need to make sure that your callbacks match the C++-style signatures in the RibbonX documentation. A "getLabel" callback, for example, would have the same parameters, except it would have an additional "[out, retval] BSTR *Label" parameter for returning the label.
For more info about RibbonX, check out the documentation mentioned above, the Developer category on this blog, or the Office Discussion Groups if you have other questions not specifically related to the topics of this article.
Update: Eric has made the resulting Visual Studio 2005 project available for download.
Today is the official business launch of Windows Vista, the 2007 Office system, and Exchange Server 2007.
This means that as of today, businesses can get these products and start deploying them within their organization.

The consumer launch is scheduled for January 30—that's when you'll be able to go into retail stores and buy shrink-wrapped copies of Office and Windows.
You can read all about the business launch, see videos, and participate in the forums here: http://msnewday.com/
Steve Ballmer sent out mail to everyone at Microsoft commemorating today's business launch. Here's in part what he wrote:
"Eleven years ago, Microsoft launched Windows 95 and Office 95 and introduced an era of unprecedented opportunity, transforming the way people do business, share information, and communicate. Today, in New York I announced the business availability of Windows Vista, the 2007 Office System, and Exchange Server 2007. This announcement marks the beginning of the most significant launch in company history, with more than 1 billion people expected to use these products in the next decade.
"The launch of Windows Vista, the 2007 Office System, and Exchange Server 2007 is an important milestone in our company's history. The result of incredibly hard work, phenomenal perseverance, and remarkable innovation, they are the most advanced work that Microsoft has ever done. For the last three decades, Microsoft has delivered technologies that embody our belief in the power of software to change the world. Windows Vista, the 2007 Office system, and Exchange Server 2007 continue this great tradition and I want to congratulate everyone who worked on these products—thank you for your dedication and commitment to making today possible."
You can also read the external version of the mail that was posted on Microsoft.com.
Want to experience Office 2007 for yourself? Today might be a great day to try taking the new Office for a test drive.
Or, if you want to download a fully-functional trial version, those will be posted online tomorrow, December 1.
Today I'm delighted to present a new guest writer to the blog: Eric Faller, Software Design Engineer on the
Office User Experience Team.
Eric is one of the developers on our team who helped to design and implement RibbonX, the user interface extensibility model for Office developers.
Today's Guest Writer: Eric Faller
Some of the most commonly asked questions around RibbonX deal with how to load and get images to display properly in the Ribbon. This FAQ about images assumes that you're already familiar with writing RibbonX add-ins. If you're just getting started, check out the official documentation or the Developer category on this blog.
Alpha channels, masks, color keys, oh my!
The most significant change in Office 2007 is the switch to use images with alpha channels, instead of the masks or color keys used in previous Office releases. If that sentence sounds confusing, you're not alone. What are all these different technologies and what problem are they trying to solve?
The problem at hand is: how do we specify which parts of our images are transparent and should let the background color of the Ribbon show through? Before tackling that question, we should look at why it's even necessary to do this in the first place.
In the past, many add-in writers bypassed the entire issue by copying the background color of Office's UI and using that as the background color in their image. There are a couple of reasons this doesn't work very well. If the user switches their UI theme colors, or a new release of Office uses a different color, the icon suddenly looks out of place. For example, consider the following add-in image which looked good on gray toolbars but looks out of place in the Ribbon without transparency:
As we can see, in order for an add-in to look professional, it's going to need to pay attention to transparency. Let's look at what features previous releases of Office offered to solve this problem.
Color keys
One way to solve this problem is to mark a certain color in the image as the "color key" and pretend that that color is transparent when drawing the image in the UI. The "hot pink" color is often used for this task since it doesn't occur very often in real icons:
The problems with this approach might be obvious. Back in the day when 16-color icons were the norm, an entire color had to be wasted as the transparent color. This color also had to be kept track of separately from the image itself: the image didn't contain the entire information needed to draw it properly. One way to work around this was to pick a specific pixel, such as the top-left corner, and use that as the color key, which led to the obvious problem of the top-left corner being unavailable for actual image content.
Picture & Mask
The CommandBars system solved the main problems with color keys by requiring add-ins to provide two different images to make up their icons: the "Picture" and "Mask" properties. The Picture image contained the color data of the icon, and the Mask was a black-and-white image that specified which pixels should be transparent. The Pictures and Masks were combined when drawing the final image on the UI. For example:
The most obvious drawback with this system is that you need to draw and keep track of two images per icon.
Another problem with both the Mask and Color Key systems is that they only allow for a single level of transparency: a pixel is either transparent or it's not. There's no room for a pixel to be "half-transparent." In today's world of rich, visual user interfaces, that's just not good enough anymore.
Alpha channels
Alpha channels are a concept from computer graphics which involves adding another "channel" to each image to keep track of transparency information (along with the Red, Green and Blue channels). Each pixel contains a 4th "color" value which keeps track of how transparent it is, on a scale from completely opaque to completely transparent. When each individual pixel can have varying levels of transparency, it's possible to create nice smooth looking images.
For example, here's what our "A" image looks like when it's drawn in the Ribbon with an alpha channel:
The main problem with alpha channel-enabled images is that it's difficult to create them and make them look good. For example, Microsoft Paint does not support alpha channels so you will need to turn to professional-level software such as Photoshop (or free alternatives such as Paint.NET) to draw them.
File formats
Another hurdle to using alpha channels is that common file formats do not support them uniformly:
|
Format
|
Supports Transparency?
|
|
BMP
|
No (technically Yes, but most libraries
don't load it properly)
|
|
JPEG
|
No
|
|
GIF
|
Single level only (no semi-transparency)
|
|
PNG
|
Yes - full support
|
PNG is the only common file format with full alpha channel support and widespread tool support. It's the recommended format for storing RibbonX images.
So, you might be wondering "Which file formats does RibbonX support?"
RibbonX operates on bitmap objects in code, not on files on the disk. It's the add-in which actually loads the files and returns the bitmap objects to RibbonX. Thus, an add-in can use whatever file format it wants when it is loading its images.
A better way to think about the question might be, "What file formats do the libraries I'm using support?" Unfortunately the answer can be a bit complicated because the libraries for different languages and technologies (VBA, C++, .NET, etc.) vary widely in their support for image file formats and alpha channels. GDI+ can be used from both native C++ code as well as managed C#/VB.NET code and it supports loading all common file formats, so it's the recommended library to use to load images.
If you're using VBA, you might think you're out of luck since the native VB APIs like LoadPicture() don't support PNG files, and you can't use GDI+ without mucking around with importing Win32 functions and types. Fortunately, VBA add-ins live in the new Open XML format files (except for in Access), and they can refer to files directly in those ZIP packages. RibbonX will do the work of automatically loading those files out of the packages, so most VBA code should not need to worry about loading image files. In this case RibbonX uses GDI+ to load those files, so any file format supported by GDI+ is supported in Open XML files (almost all formats). VBA add-ins will only need to load images themselves if they want to dynamically switch icons at runtime (this is not recommended by the UI guidelines since this almost never happens in the built-in Office UI.)
16-bit vs. 32-bit
Several things can go wrong in an add-in while it's loading its images before it passes them off to RibbonX. These usually involve the in-memory format used to store the image.
When storing an image in memory, how should the pixel data be represented? In the past, a wide variety of options were available (palletized, 4-bit, 16-bit, 24-bit, etc...), but today the most commonly encountered formats are 16 bits per pixel (bpp) and 32 bpp.
Remember that with alpha channels, each pixel stores its transparency value along with the color data. With 16-bit formats, 5 bits are usually allocated for each of the Red, Green and Blue channels (sometimes 6 bits for Green), leaving only 0 or 1 bits for alpha, which isn't enough. Thus, when an image is loaded into memory in 16-bit format, its alpha channel is usually compacted or deleted completely. Obviously this isn't what we want, so in our RibbonX add-ins, we need to always load images into memory in 32-bit formats, allocating 8 bits each for the Red, Green, Blue, and Alpha channels
So, if the file format you're using (PNG, for example) includes the full 32-bit pixel data, why would the image become compacted to only 16 bits when loading into memory? Unfortunately this happens more than one might expect.
DIB vs. DDB
Windows has a concept of "Device-Dependent Bitmaps" (DDBs) and "Device-Independent Bitmaps" (DIBs). The "device" referenced here is the graphics card and display on the computer. Today most displays can be set to either 16-bit mode or 32-bit mode. If your display is in 16-bit mode, DDBs will be in 16-bit format ("dependent" on the device), while DIBs will usually be 32-bit (since they are "independent" of the mode the device is actually in). If your display is in 32-bit mode, DDBs will be 32-bit and DIBs will usually be too, so there's no practical difference between DDBs and DIBs. Writing your code assuming there is no difference is often a cause of difficult bugs.
A commonly encountered problem is "My RibbonX icon looks fine on my computer, but on my tester's computer it looks horrible," or "It looks fine everywhere except over Remote Desktop, where it looks bad." In this case the tester's computer is probably running a 16-bit display. Remote Desktop and Terminal Services also default to 16-bit display modes in many cases.
The root of the problem is that the add-in is loading its images as DDBs, and on the 16-bit displays, the pixel data gets compacted to 16-bits and the alpha channel is thrown away. On 32-bit displays, the DDBs are equivalent to DIBs, and the pixels are loaded into 32 bits and everything works fine.
The fix is to make sure that your code always loads images as DIBs, never DDBs. Unfortunately for us, most Win32 image loading functions will create DDBs by default. This can be overridden by making sure to pass in LR_CREATEDIBSECTION to functions which take that flag, such as LoadImage(), CopyImage(), etc.. If you want to know whether you have a DIB or a DDB, you can call GetBitmap() on your HBITMAP with a DIBSECTION structure and test if that succeeds or fails.
Fortunately, if you are writing a .NET managed add-in and are using GDI+ to load your images, you don't have to worry about this because GDI+ uses DIBs internally.
IPictureDisp vs. System.Drawing.Bitmap
Once you have your image all loaded up, how do you return it to RibbonX? If you take a look at the return value of the "getImage" and "loadImage" functions, you'll see that it's a generic "object" type (or "IUnknown" in unmanaged code). The following types of values are accepted:
- IPictureDisp objects
- System.Drawing.Bitmap objects
- Strings (equal to the "imageMso" value of a built-in icon to use)
The 3rd option can be used if you want to re-use a built-in image. The first two require loading your own image and are more complicated.
The type of value you should return depends on the language you are using to write your add-in:
- VB6/VBA: IPictureDisp is the "COM name" of Picture, which is the native VB image type. You can just take the return value from the VB LoadPicture() function and return it (LoadPicture does not support PNG files, though, see the discussion above).
- C/C++ and other native code: IPictureDisp is your best bet. IPictureDisp objects are really just wrappers around HBITMAPs or HICONs, which are the native Win32 image types. You can either create IPictureDisps directly using functions like OleLoadPicture(), or indirectly by filling in a PICTDESC structure with an HBITMAP and calling OleCreatePictureIndirect() to convert it to an IPictureDisp. You can get the HBITMAP from any image-loading function you want, but GDI+ is the recommended library since it supports PNG files.
- C#/VB.NET and other managed code: System.Drawing.Bitmap is the native type of .NET languages, so it's easiest to just return Bitmap objects directly. If for some reason you want to convert them to IPictureDisp objects, you could do so using the AxHost.GetIPictureDispFromPicture() method.
Right now you might be wondering to yourself, "If Office is a native unmanaged application, how does it know what a managed System.Drawing.Bitmap object is?" This is a good question, and the answer is that it actually doesn't know. Through the magic of COM interop, the .NET Bitmap object is converted to a COM-compatible IDispatch interface which can be manipulated by Office. RibbonX takes this IDispatch object and checks if there is a "GetHbitmap()" function available on the interface. If there is, it uses Invoke() to call that function and get an HBITMAP object that corresponds to the original Bitmap object.
So in reality, RibbonX functions are not limited to returning System.Drawing.Bitmap objects, they can actually return any objects which have functions named "GetHbitmap." If for some reason you needed to, you could create your own class with a GetHbitmap() function and use that instead of System.Drawing.Bitmap.
Bitmaps vs. Icons
Some add-in writers store their UI icons in .ICO files and load them into HICON or System.Drawing.Icon objects.
RibbonX can load .ICO files from Open XML format files, and it will accept HICON-based IPictureDisps, but its icon support is somewhat limited and it doesn't accept System.Drawing.Icon objects at all.
Several RibbonX features do not work with icon-based images, such as the automatic "graying out" of images when their respective buttons are disabled, so it's recommended that add-ins provide bitmaps instead of icons. If you have a System.Drawing.Icon object, you can convert it to a Bitmap using the .ToBitmap() method.
getImage vs. loadImage
Another common question is "Why are there both getImage and loadImage functions? Which should I use?"
The answer is that you should almost always use loadImage, except when you need to dynamically change your controls' images at runtime, in which case you should use getImage on those controls.
loadImage provides these advantages over getImage:
- If multiple controls use the same image, loadImage is called only once, saving time and space.
- If a control is invalidated (for example, in order to change its enabled state), loadImage is not uselessly called again.
- Arbitrary strings can be specified in the "image" property and passed to loadImage (for example, a resource ID or filename), but with getImage you're stuck with the ID of the specific control you're interested in.
The main advantage of getImage is that its return value can be invalidated using IRibbonUI.InvalidateControl() and changed dynamically at runtime. Once an image is set with loadImage, it's permanent.
Further reading
For more information, check out the official RibbonX documentation.
If you have specific support questions unrelated to this article, try the Office Discussion Groups.
For the last year or so, one of the questions I've been asked again and again has been: "Can I use the new Office user interface in my own product?"
On one hand, it's an immensely satisfying question to hear, because it means that others in the industry believe in the value of what we've built and see how the sound UI research we've done can benefit their own products. Creating the new user interface has been our team's passion for the last three years, and we love sharing the fruits of this hard work.
On the other hand, the new Office user interface was a huge investment by Microsoft and the resulting intellectual property belongs to Microsoft.
As a result, I've never been totally comfortable answering questions about whether people can use the new UI or not publicly because, honestly, I didn't really know the answer. You might have noticed I've been pretty quiet on the subject.
Internally, though, more than a year ago we started talking about how we could share the design work we've done more broadly in a way that also protects the value of Microsoft's investment in this research and development.
Well, I'm pleased to finally be able to definitively answer the question. Today, we're announcing a licensing program for the 2007 Microsoft Office system user interface which allows virtually anyone to obtain a royalty-free license to use the new Office UI in a software product, including the Ribbon, galleries, the Mini Toolbar, and the rest of the user interface.
Last week, I recorded a video along with Judy Jennison, the lawyer who has been spearheading the licensing effort, to chat about the UI license in detail. Take a look, or keep reading to learn more.
(If you ever wondered what my office looks like, here's your chance!)
Watch the Channel 9 video about the Office 2007 UI License
How does the license work?
It's pretty simple really. First, you visit the Office UI Licensing web site. On this page, you'll find some information about the licensing program, a downloadable copy of the license to peruse at your leisure, and further contact information.
If you choose to implement the Office UI, you sign up for the program by accepting the license terms and giving us a little bit of information about your product. There's no fee, you don't owe Microsoft any royalties, and the license is perpetual—meaning that the terms won't change.
This should give you the confidence you need to build a business or product on top of the Office UI platform, secure in the knowledge that you've licensed the technology and research you're using in your product.
You must follow the guidelines, though.
Included with the license you'll find the 2007 Microsoft Office System User Interface Guidelines. This 120+ page document includes all of the information you need to implement Office-style UI; think of it as the specification for how the UI needs to work in your product.
To stay within the terms of the license, you must follow these guidelines.
We want to ensure that when someone implements the Ribbon (for example) that they do so the right way… and in a way consistent with how it works in Office.
There's tremendous value in making sure that we all use these models in a consistent way, because it helps to ensure that people have predictable user experiences moving between Office-style user interfaces.
In the guidelines you'll find REQUIRED sections and OPTIONAL sections. The REQUIRED sections are exactly that—sections that you must implement in order to stay within the letter of the license.
Within each section, you'll see things you MUST implement, things you SHOULD implement, and BEST PRACTICES. Just like it sounds, you must implement the UI as specified by the MUSTs in the document to comply with the terms of the license. We highly recommend implementing the SHOULD sections, and also adhering to the BEST PRACTICES wherever possible. Doing so will make you as consistent as possible with the way Office works.
The 120+ page guidelines document is confidential, so you'll need to visit the licensing site and agree to a short evaluation license before downloading it. But we created a little preview version of one of the sections to give you a flavor of what the guidelines are like.
The particular section we excerpted for the preview is Ribbon Resizing, which details the way in which the Ribbon must scale up and down to adjust to varying horizontal resolutions. The actual guidelines document contains similar information for the entire UI.
Download the 2007 Microsoft Office System UI Guidelines Preview (1.39 MB)
If your goal is to get as close to the Office UI as possible, you'll probably have no trouble complying with the guidelines. The guidelines are just there to help make that process easier and to give you a checklist for the parts of the UI you need to implement in order to comply with the license.
What's the catch?
For almost everyone, there's no catch at all. Just sign up for the license, and follow the guidelines. That's all there is to it.
You can use the UI in open source projects as long as the license terms are consistent with our license. You can use it on any platform: Windows, Mac, Linux, etc. If you're an ISV, you can build and sell a set of controls based on the new Office UI.
There's only one limitation: if you are building a program which directly competes with Word, Excel, PowerPoint, Outlook, or Access (the Microsoft applications with the new UI), you can't obtain the royalty-free license.
Why this exclusion?
Microsoft spent hundreds of millions of dollars on the research, design, and development of the new Office user interface.
We're allowing developers to license this intellectual property and take advantage of these advances in user interface design without any fee whatsoever.
But we want to preserve the innovation for Microsoft's productivity applications that are already using the new UI.
Summary
I am really excited to finally see this program launch. There's nothing our team wants more than to see the concepts and designs introduced in Office benefit others in the software industry. I believe in the new user interface, and I believe in its suitability to a large number of software applications.
I think the license strikes the right balance between allowing developers to use the new Office UI and protecting Microsoft's rights as the company who paid all of us to work on it.
For More Information
Now that we've released Office 2007 to manufacturing, developers can get started modifying their solutions so that they're ready to test with the released version of Office.
Final versions of the RibbonX schema and Control ID list will be published on MSDN soon, but that can take a while—so I'll continue to publish developer resources here first so that you don't have to wait.
First, the entire set of Office 2007 Control ID lists. I'm putting these up in two different formats: .xls (97-2003 format) and .xlsx (2007 format.)
You only need one of these files; the contents of them are the same aside from the different format of the files.
Download Office 2007 RTM Control ID List
(Excel 97-2003 Format)
Download Office 2007 RTM Control ID List
(Excel 2007 Format)
The list of Control IDs hasn't changed too much from the Beta 2 Technical Refresh, but there are around 75 changes—any one of which could potentially break your solution. To help you see at-a-glance what changed since B2TR, we put together a list of just the changes.
Download List of Control ID List Changes between B2TR and RTM
The Control ID lists can be useful even if you aren't a developer. For example, we added a column for Group Policy ID in each of the lists; this ID number is the ID you need to disable Office commands via group policy.
Finally, it's worth mentioning again: a few weeks ago we released the RTM customUI schema for RibbonX. If you didn't catch it then, you might want to download it now:
Download Office 2007 RTM customUI Schema
I've published over 200 posts on this blog since I started it last September.
With all of those posts, it can be hard to remember what you've read and what you haven't… and it can be hard for new people to jump in and figure out where to start reading.
I've been meaning to sit down and create a kind of table of contents for all of the posts here—a starting point for people to read about the Office 2007 UI.
But then, I found out that someone already did the work for me. Patrick Schmid, a OneNote MVP and friend of the Office 2007 UI, put together what he called the Office UI Bible on his blog—a fully organized catalog of many of my posts.
And so with Patrick's kind permission I reprint here the catalog of Office 2007 UI posts (so far.)
I hope you find it useful—and thanks, Patrick!
Why a New UI for Office 2007?
Overview of the New UI
Ribbon UI Elements
The Size of the Ribbon, Screen Real-Estate, Ribbon Scaling, and Minimization
Migrating to Office 2007
UI Themes and Visuals
Keyboard Control of the Ribbon
New Fonts for Office 2007
Customizing Office 2007 (Add-ins, RibbonX)
Note that most examples shown in the following posts need to be updated for use with the RTM version.
From First Sketches to the Final Design
Design Tenets
Design Ponderings
An Inside Look Into UI Design, Usability, Development and Testing at Microsoft
Office Themes
New Features in Office 2007 Involving the New UI
Miscellaneous
The Office 2007 UI team
I'm proud to announce that last Friday, November 3 at approximately 2:30 PM, we signed off on build 4518.1014 as the 2007 Microsoft Office system and released it to manufacturing.
This was followed by a ship party for everyone in Office including a few minutes of speeches, the traditional sounding of the RTM siren, and plenty of champagne (much of which I ended up wearing.) The rain even stopped for a few hours!
You can read the official press release here.

This release has been such a great pleasure to work on. It was more than three years ago when Julie walked into my office (I barely knew her at the time) and asked if I wanted to come over to the user experience team to help figure out if there was something better than menus and toolbars. I had no idea what an adventure I was about to embark on!
Three years later and we've shipped a product that I'm so proud of.
In the near future, we'll be sharing more of the research we've been doing on Beta 2 and B2TR deployments around the world. Just last week, we got back the most recent round of data from ~4000 people in long-term enterprise deployments of Beta 2 in the United States, Europe, and Asia. The results are positive beyond what I would have dared to dream.
To those of you who have been active in the beta program and here on the blog, and to everyone who sent feedback on the betas, thank you. Your feedback truly made the product better than it ever could have been without you.
To the app teams and partner teams around Office and at Microsoft who helped make this release possible, thank you. This couldn't have happened without your ide