<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jensen Harris: An Office User Interface Blog : Developer</title><link>http://blogs.msdn.com/b/jensenh/archive/category/11280.aspx</link><description>Posts relating to the developer and extensibility story around the new Microsoft Office 2007 user interface.</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Using RibbonX with C++ and ATL</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/12/08/using-ribbonx-with-c-and-atl.aspx</link><pubDate>Fri, 08 Dec 2006 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1241672</guid><dc:creator>jensenh</dc:creator><slash:comments>52</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=1241672</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/12/08/using-ribbonx-with-c-and-atl.aspx#comments</comments><description>&lt;H3&gt;Today's Guest Writer: Eric Faller&lt;/H3&gt;
&lt;P&gt;&lt;I&gt;Eric is a Software Design Engineer on the Office User Experience team focused on user interface extensibility for Office developers.&lt;/I&gt; &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;IRibbonExtensibility &lt;/B&gt;&lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;IDispatch &lt;/B&gt;&lt;/P&gt;
&lt;P&gt;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: &lt;/P&gt;&lt;CODE&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&amp;lt;button id="MyButton" onAction="ButtonClicked"/&amp;gt; &lt;/P&gt;&lt;/CODE&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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: &lt;/P&gt;&lt;CODE&gt;
&lt;P&gt;Dim word&lt;BR&gt;Set word = Application &lt;BR&gt;word.CheckSpelling ("misspellled") &lt;/P&gt;&lt;/CODE&gt;
&lt;P&gt;The IDispatch interface contains a whole bunch of methods which you can read all about in the &lt;A href="http://msdn2.microsoft.com/en-us/library/ms221608.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms221608.aspx"&gt;documentation&lt;/A&gt;, but the main two to be concerned with are GetIDsOfNames() and Invoke(). &lt;/P&gt;
&lt;P&gt;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." &lt;/P&gt;
&lt;P&gt;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." &lt;/P&gt;
&lt;P&gt;Parameters and return values are passed around in &lt;A href="http://msdn2.microsoft.com/en-us/library/ms221627.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms221627.aspx"&gt;VARIANT&lt;/A&gt; 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. &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Building a simple C++/ATL RibbonX add-in &lt;/B&gt;&lt;/P&gt;
&lt;P&gt;The steps for creating a C++ RibbonX add-in start off pretty much the same as for a C# add-in: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Open up Visual Studio &lt;/LI&gt;
&lt;LI&gt;Click "New Project" &lt;/LI&gt;
&lt;LI&gt;Select "Extensibility" under "Project types" and choose "Shared Add-in" &lt;/LI&gt;
&lt;LI&gt;Give it a name and click OK: &lt;/LI&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/ATL1.png"&gt;&lt;IMG src="http://officeblogs.net/UI/ATL1_thumb.png"&gt;&lt;/A&gt;&lt;BR&gt;&lt;I&gt;Click to view full picture&lt;/I&gt;&lt;/P&gt;
&lt;LI&gt;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." &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Now you have an empty C++ add-in. Click "Build Solution" just to make sure that it all compiles OK with no problem. &lt;/P&gt;
&lt;P&gt;Next, open up Class View, right-click on your CConnect class and select "Add -&amp;gt; Implement Interface…" In the dialog that pops up, select the "Microsoft Office 12.0 Object Library &amp;lt;2.4&amp;gt;" type library and add the "IRibbonExtensibility" interface from it: &lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ATL2.png"&gt;&lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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: &lt;/P&gt;&lt;PRE&gt;&lt;P&gt;STDMETHOD(GetCustomUI)(BSTR RibbonID, BSTR * RibbonXml)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if (!RibbonXml)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return E_POINTER; &lt;/P&gt;&lt;BR&gt;&lt;P&gt;&amp;nbsp; *RibbonXml = SysAllocString(&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"&amp;lt;customUI xmlns=\"http://schemas.microsoft.com/office/2006/01/customui\"&amp;gt;"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L" &amp;lt;ribbon&amp;gt;"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"&amp;nbsp;&amp;nbsp; &amp;lt;tabs&amp;gt;"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tab id=\"CustomTab\"" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label=\"Custom Tab\"&amp;gt;" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;group id=\"CustomGroup\"" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label=\"Custom Group\"&amp;gt;" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button id=\"CustomButton\"" &lt;BR&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imageMso=\"HappyFace\""&lt;BR&gt;&amp;nbsp; &amp;nbsp; L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; size=\"large\"" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label=\"Click me!\"" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; onAction=\"ButtonClicked\"/&amp;gt;" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/group&amp;gt;" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L"&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tab&amp;gt;" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L"&amp;nbsp;&amp;nbsp; &amp;lt;/tabs&amp;gt;" &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;L" &amp;lt;/ribbon&amp;gt;" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"&amp;lt;/customUI&amp;gt;"&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; ); &lt;/P&gt;&lt;BR&gt;&lt;P&gt;&amp;nbsp; return (*RibbonXml ? S_OK : E_OUTOFMEMORY); &lt;BR&gt;} &lt;/P&gt;&lt;/PRE&gt;
&lt;P&gt;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! &lt;/P&gt;
&lt;P&gt;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: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;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) &lt;/LI&gt;
&lt;LI&gt;Add "using namespace Office;" to the top of the Connect.h file. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Now we can build successfully and see our button: &lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ATL3.jpg"&gt;&lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;Back in Class View, right-click on ICallbackInterface and select "Add -&amp;gt; Add Method…" In the Add Method Wizard, add a method named "ButtonClicked" with one [in] parameter of type IDispatch* called RibbonControl: &lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ATL4.jpg"&gt;&lt;/P&gt;
&lt;P&gt;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. &lt;/P&gt;
&lt;P&gt;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: &lt;/P&gt;&lt;CODE&gt;
&lt;P&gt;STDMETHOD(ButtonClicked)( IDispatch * RibbonControl)&lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; // Add your function implementation here. &lt;/P&gt;
&lt;P&gt;&amp;nbsp; MessageBoxW(NULL,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"The button was clicked!", &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L"Message from ExampleATLAddIn", &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MB_OK | MB_ICONINFORMATION); &lt;/P&gt;&lt;/CODE&gt;
&lt;P&gt;&amp;nbsp; return S_OK; &lt;BR&gt;} &lt;/P&gt;
&lt;P&gt;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 &lt;I&gt;and&lt;/I&gt; 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". &lt;/P&gt;
&lt;P&gt;The last&amp;nbsp;work item&amp;nbsp;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: &lt;/P&gt;&lt;CODE&gt;
&lt;P&gt;BEGIN_COM_MAP(CConnect) &lt;BR&gt;&amp;nbsp; COM_INTERFACE_ENTRY2(IDispatch, ICallbackInterface) &lt;BR&gt;&amp;nbsp; COM_INTERFACE_ENTRY(AddInDesignerObjects::IDTExtensibility2) &lt;BR&gt;&amp;nbsp; COM_INTERFACE_ENTRY(IRibbonExtensibility) &lt;BR&gt;&amp;nbsp; COM_INTERFACE_ENTRY(ICallbackInterface) &lt;BR&gt;END_COM_MAP() &lt;/P&gt;&lt;/CODE&gt;
&lt;P&gt;Once that's all built, try out the add-in and see that it works! &lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ATL5.jpg"&gt;&lt;/P&gt;
&lt;P&gt;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 &lt;A href="http://msdn.microsoft.com/office/tool/ribbon" mce_href="http://msdn.microsoft.com/office/tool/ribbon"&gt;RibbonX documentation&lt;/A&gt;. 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. &lt;/P&gt;
&lt;P&gt;For more info about RibbonX, check out the documentation mentioned above, the &lt;A href="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx" mce_href="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx"&gt;Developer category&lt;/A&gt; on this blog, or the &lt;A href="http://www.microsoft.com/office/community/en-us/default.mspx" mce_href="http://www.microsoft.com/office/community/en-us/default.mspx"&gt;Office Discussion Groups&lt;/A&gt; if you have other questions not specifically related to the topics of this article.&lt;/P&gt;
&lt;P&gt;&lt;I&gt;Update: Eric has made the &lt;A href="http://officeblogs.net/UI/ExampleATLAddIn.zip" mce_href="http://officeblogs.net/UI/ExampleATLAddIn.zip"&gt;resulting Visual Studio 2005 project available for download&lt;/A&gt;.&lt;/I&gt;&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1241672" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>RibbonX Image FAQ</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/11/27/ribbonx-image-faq.aspx</link><pubDate>Mon, 27 Nov 2006 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1156857</guid><dc:creator>jensenh</dc:creator><slash:comments>25</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=1156857</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/11/27/ribbonx-image-faq.aspx#comments</comments><description>&lt;p&gt;&lt;i&gt;Today I'm delighted to present a new guest writer to the blog: Eric Faller, Software Design Engineer on the
Office User Experience Team. &lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Eric is one of the developers on our team who helped to design and implement RibbonX, the user interface extensibility model for Office developers.&lt;br&gt;&lt;/i&gt;&lt;/p&gt;
&lt;h3&gt;Today's Guest Writer: Eric Faller&lt;/h3&gt;
&lt;p&gt;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 &lt;a href="http://msdn.microsoft.com/office/tool/ribbon" mce_href="http://msdn.microsoft.com/office/tool/ribbon"&gt;official documentation&lt;/a&gt; or the &lt;a href="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx" mce_href="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx"&gt;Developer category&lt;/a&gt; on this blog.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Alpha channels, masks, color keys, oh my!
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;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?
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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:
&lt;/p&gt;

&lt;p align="center"&gt;&lt;img src="http://officeblogs.net/UI/EricImage1.png"&gt;
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Color keys
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;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:
&lt;/p&gt;

&lt;p align="center"&gt;&lt;img src="http://officeblogs.net/UI/EricImage2.png"&gt;
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Picture &amp;amp; Mask
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;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:
&lt;/p&gt;

&lt;p align="center"&gt;&lt;img src="http://officeblogs.net/UI/EricImage3.png"&gt;
&lt;/p&gt;

&lt;p&gt;The most obvious drawback with this system is that you need to draw and keep track of &lt;i&gt;two&lt;/i&gt; images per icon. 
&lt;/p&gt;

&lt;p&gt;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. 
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Alpha channels
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;For example, here's what our "A" image looks like when it's drawn in the Ribbon with an alpha channel:
&lt;/p&gt;

&lt;p align="center"&gt;&lt;img src="http://officeblogs.net/UI/EricImage4.png"&gt;
&lt;/p&gt;

&lt;p&gt;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 &lt;a href="http://www.getpaint.net" mce_href="http://www.getpaint.net"&gt;Paint.NET&lt;/a&gt;) to draw them.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;File formats
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Another hurdle to using alpha channels is that common file formats do not support them uniformly:&lt;br&gt;&lt;/p&gt;

&lt;table align="center" border="1" cellpadding="0" cellspacing="0" height="275" width="392"&gt;
 &lt;tbody&gt;
&lt;tr&gt;
  
&lt;td valign="top" width="144"&gt;
  
&lt;p align="center"&gt;&lt;b&gt;Format&lt;/b&gt;&lt;/p&gt;
  &lt;/td&gt;
  
&lt;td valign="top" width="162"&gt;
  
&lt;p align="center"&gt;&lt;b&gt;Supports Transparency?&lt;/b&gt;&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 
&lt;tr&gt;
  
&lt;td valign="top" width="144"&gt;
  
&lt;p align="center"&gt;BMP&lt;/p&gt;
  &lt;/td&gt;
  
&lt;td valign="top" width="162"&gt;
  
&lt;p align="center"&gt;No (technically Yes, but most libraries
  don't load it properly) &lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 
&lt;tr&gt;
  
&lt;td valign="top" width="144"&gt;
  
&lt;p align="center"&gt;JPEG&lt;/p&gt;
  &lt;/td&gt;
  
&lt;td valign="top" width="162"&gt;
  
&lt;p align="center"&gt;No&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 
&lt;tr&gt;
  
&lt;td valign="top" width="144"&gt;
  
&lt;p align="center"&gt;GIF&lt;/p&gt;
  &lt;/td&gt;
  
&lt;td valign="top" width="162"&gt;
  
&lt;p align="center"&gt;Single level only (no semi-transparency)&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 
&lt;tr&gt;
  
&lt;td valign="top" width="144"&gt;
  
&lt;p align="center"&gt;PNG&lt;/p&gt;
  &lt;/td&gt;
  
&lt;td valign="top" width="162"&gt;
  
&lt;p align="center"&gt;Yes - full support&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;



&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;So, you might be wondering "Which file formats does RibbonX support?"
&lt;/p&gt;

&lt;p&gt;RibbonX operates on &lt;i&gt;bitmap objects&lt;/i&gt; in code, not on &lt;i&gt;files&lt;/i&gt; 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.
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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.)
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;16-bit vs. 32-bit
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;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. 
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;DIB vs. DDB
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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. 
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;IPictureDisp vs. System.Drawing.Bitmap
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;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:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;IPictureDisp objects
&lt;/li&gt;

&lt;li&gt;System.Drawing.Bitmap objects
&lt;/li&gt;

&lt;li&gt;Strings (equal to the "imageMso" value of a built-in icon to use)
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;The type of value you should return depends on the language you are using to write your add-in:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;b&gt;VB6/VBA:&lt;/b&gt; 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).&lt;br&gt;&lt;br&gt;
&lt;/li&gt;

&lt;li&gt;&lt;b&gt;C/C++ and other native code:&lt;/b&gt; 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. 
&lt;br&gt;&lt;br&gt;&lt;/li&gt;

&lt;li&gt;&lt;b&gt;C#/VB.NET and other managed code:&lt;/b&gt; 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.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Bitmaps vs. Icons
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Some add-in writers store their UI icons in .ICO files and load them into HICON or System.Drawing.Icon objects. 
&lt;/p&gt;

&lt;p&gt;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. 
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;getImage vs. loadImage
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Another common question is "Why are there both getImage and loadImage functions? Which should I use?"
&lt;/p&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;loadImage provides these advantages over getImage:
&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;If multiple controls use the same image, loadImage is called only once, saving time and space.&lt;br&gt;&lt;br&gt;
&lt;/li&gt;&lt;li&gt;If a control is invalidated (for example, in order to change its enabled state), loadImage is not uselessly called again.
&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;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.
&lt;/li&gt;&lt;/ul&gt;&lt;ul style="margin-left: 37pt;"&gt;





&lt;/ul&gt;

&lt;p&gt;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.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Further reading
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;For more information, check out the official &lt;a href="http://msdn.microsoft.com/office/tool/ribbon" mce_href="http://msdn.microsoft.com/office/tool/ribbon"&gt;RibbonX documentation&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;If you have specific support questions unrelated to this article, try the &lt;a href="http://www.microsoft.com/office/community/en-us/default.mspx" mce_href="http://www.microsoft.com/office/community/en-us/default.mspx"&gt;Office Discussion Groups&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1156857" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>Licensing the 2007 Microsoft Office User Interface</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/11/21/licensing-the-2007-microsoft-office-user-interface.aspx</link><pubDate>Wed, 22 Nov 2006 00:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1113831</guid><dc:creator>jensenh</dc:creator><slash:comments>98</slash:comments><description>&lt;p&gt;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?" &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;On the other hand, the new Office user interface was a huge investment by Microsoft and the resulting intellectual property belongs to Microsoft. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;Well, I'm pleased to finally be able to definitively answer the question. Today, &lt;a href="http://www.microsoft.com/presspass/features/2006/nov06/11-21officeui.mspx" mce_href="http://www.microsoft.com/presspass/features/2006/nov06/11-21officeui.mspx"&gt;we're announcing a licensing program for the 2007 Microsoft Office system user interface&lt;/a&gt; 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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;&lt;i&gt;(If you ever wondered what my office looks like, here's your chance!) &lt;/i&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://channel9.msdn.com/Showpost.aspx?postid=259548" class="" target="_blank" mce_href="http://channel9.msdn.com/Showpost.aspx?postid=259548"&gt;Watch the Channel 9 video about the Office 2007 UI License&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;b&gt;How does the license work?&lt;/b&gt; &lt;/p&gt;
&lt;p&gt;It's pretty simple really. First, you visit the &lt;a href="http://msdn.microsoft.com/officeui" mce_href="http://msdn.microsoft.com/officeui"&gt;Office UI Licensing web site&lt;/a&gt;. 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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;You must follow the guidelines, though.&lt;/b&gt; &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;To stay within the terms of the license, you must follow these guidelines. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://officeblogs.net/UI/Preview%202007%20Microsoft%20Office%20System%20UI%20Design%20Guidelines.pdf" mce_href="http://officeblogs.net/UI/Preview%202007%20Microsoft%20Office%20System%20UI%20Design%20Guidelines.pdf"&gt;Download the 2007 Microsoft Office System UI Guidelines Preview&lt;/a&gt; &lt;i&gt;(1.39 MB)&lt;/i&gt; &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;What's the catch?&lt;/b&gt; &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;Why this exclusion? &lt;/p&gt;
&lt;p&gt;Microsoft spent hundreds of millions of dollars on the research, design, and development of the new Office user interface. &lt;/p&gt;
&lt;p&gt;We're allowing developers to license this intellectual property and take advantage of these advances in user interface design without any fee whatsoever. &lt;/p&gt;
&lt;p&gt;But we want to preserve the innovation for Microsoft's productivity applications that are already using the new UI. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt; &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;For More Information&lt;/b&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/officeui" mce_href="http://msdn.microsoft.com/officeui"&gt;2007 Microsoft Office System User Interface Licensing web site&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://officeblogs.net/UI/Preview%202007%20Microsoft%20Office%20System%20UI%20Design%20Guidelines.pdf" mce_href="http://officeblogs.net/UI/Preview%202007%20Microsoft%20Office%20System%20UI%20Design%20Guidelines.pdf"&gt;User Interface Guidelines Preview&lt;/a&gt; &lt;i&gt;(A short excerpt of the actual guidelines) &lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://channel9.msdn.com/Showpost.aspx?postid=259548" class="" mce_href="http://channel9.msdn.com/Showpost.aspx?postid=259548"&gt;Channel 9 video discussion with more about the UI and the UI license&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/presspass/features/2006/nov06/11-21officeui.mspx" mce_href="http://www.microsoft.com/presspass/features/2006/nov06/11-21officeui.mspx"&gt;Press release and Q &amp;amp; A about the licensing announcement&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E2DDD3FB-8635-4D54-8730-102B75C31DB6&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E2DDD3FB-8635-4D54-8730-102B75C31DB6&amp;amp;displaylang=en"&gt;Frequently asked questions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1113831" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/FAQ/">FAQ</category></item><item><title>Developer Resources for Office 2007 RTM</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/11/13/developer-resources-for-office-2007-rtm.aspx</link><pubDate>Mon, 13 Nov 2006 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1067577</guid><dc:creator>jensenh</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=1067577</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/11/13/developer-resources-for-office-2007-rtm.aspx#comments</comments><description>&lt;p&gt;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.
&lt;/p&gt;&lt;p&gt;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.
&lt;/p&gt;&lt;p&gt;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.)
&lt;/p&gt;&lt;p&gt;You only need one of these files; the contents of them are the same aside from the different format of the files.
&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a href="http://officeblogs.net/UI/RibbonX-ControlIDs-xlsFormat.zip" mce_href="http://officeblogs.net/UI/RibbonX-ControlIDs-xlsFormat.zip"&gt;&lt;b&gt;Download Office 2007 RTM Control ID List&lt;/b&gt;&lt;b&gt;
		&lt;/b&gt;&lt;i&gt;(Excel 97-2003 Format)&lt;/i&gt;&lt;/a&gt;&lt;b&gt;
		&lt;/b&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a href="http://officeblogs.net/UI/RibbonX-ControlIDs.zip" mce_href="http://officeblogs.net/UI/RibbonX-ControlIDs.zip"&gt;&lt;b&gt;Download Office 2007 RTM Control ID List&lt;/b&gt;&lt;b&gt;
		&lt;/b&gt;&lt;i&gt;(Excel 2007 Format)&lt;/i&gt;&lt;/a&gt;&lt;b&gt;
		&lt;/b&gt;&lt;/p&gt;&lt;p&gt;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.
&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a href="http://officeblogs.net/UI/RTMUpdates.zip" mce_href="http://officeblogs.net/UI/RTMUpdates.zip"&gt;&lt;b&gt;Download List of Control ID List Changes between B2TR and RTM&lt;/b&gt;&lt;/a&gt;
	&lt;/p&gt;&lt;p&gt;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.
&lt;/p&gt;&lt;p&gt;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:
&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a href="http://officeblogs.net/UI/customUI.zip" mce_href="http://officeblogs.net/UI/customUI.zip"&gt;&lt;b&gt;Download Office 2007 RTM customUI Schema&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1067577" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>Final Schema for RibbonX-based Solutions</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/10/26/final-schema-for-ribbonx-based-solutions.aspx</link><pubDate>Thu, 26 Oct 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:875328</guid><dc:creator>jensenh</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=875328</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/10/26/final-schema-for-ribbonx-based-solutions.aspx#comments</comments><description>&lt;p&gt;This morning, I posted the final customUI XML schema for creating Office 2007 RibbonX-based solutions.
&lt;/p&gt;&lt;p&gt;You can use this schema to develop solutions that will work with the upcoming final release of Office 2007; it will also continue to work just fine with Beta 2 Technical Refresh. The changes from the previous version I posted are all minor (and in fact I updated the B2TR link in a previous post to point to the updated RTM schema as well.)
&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a href="http://officeblogs.net/UI/customUI.zip" mce_href="http://officeblogs.net/UI/customUI.zip"&gt;Download the RTM customUI Schema&lt;/a&gt;
	&lt;/p&gt;&lt;p&gt;This updated version will also find its way onto MSDN in the coming weeks, but I wanted you guys to have access to it first.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=875328" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>RibbonX Updates for B2TR</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/09/15/755336.aspx</link><pubDate>Fri, 15 Sep 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:755336</guid><dc:creator>jensenh</dc:creator><slash:comments>45</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=755336</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/09/15/755336.aspx#comments</comments><description>&lt;H3&gt;Today's Guest Writer: Savraj Dhanjal&lt;/H3&gt;&lt;EM&gt;Savraj is a Program Manager on the Office User Experience team focused on user interface extensibility for Office developers.&lt;/EM&gt; 
&lt;P&gt;As you may have discovered, we made a few tweaks to the UI developer story in Beta 2 Technical Refresh. &lt;/P&gt;
&lt;P&gt;The biggest change is the updated Control ID list we published yesterday. We've updated the name of nearly every command in Office to be more logical, searchable, and easy to understand. If you are interested in finding out the ID numbers of commands for use with Group Policy, you can find them in these lists as well, in the Policy ID column. &lt;/P&gt;
&lt;P&gt;We do not expect to change these IDs again for RTM, so (cross our fingers) this is the final list for Office 2007. We hope you find the new Excel-based lists easier to use and more flexible than the text files released with Beta 2. &lt;/P&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;A href="http://www.sunflowerhead.com/msimages/Office2007ControlIDs.zip"&gt;&lt;STRONG&gt;Download Office 2007 B2TR Control ID List&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;If you have Beta 2 UI customizations which use a large number of built-in control IDs, manually updating each ID will take a while. So we wrote a command-line tool, UpdateIdMso, that takes a customUI xml file containing Beta 2 ID's and outputs a file with updated B2TR IDs. We hope this tool will make the upgrade process a bit easier for you. &lt;/P&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;A href="http://www.sunflowerhead.com/msimages/UpdateIdMso.zip"&gt;&lt;STRONG&gt;Download UpdateIdMso Tool&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;We also have a new customUI schema for B2TR. The schema has only a couple of notable changes. We renamed the &lt;EM&gt;fileMenu&lt;/EM&gt; tag to &lt;EM&gt;officeMenu&lt;/EM&gt; and also changed &lt;EM&gt;advanced&lt;/EM&gt; to &lt;EM&gt;dialogBoxLauncher&lt;/EM&gt;. We made these changes to ensure that the developer model matches the final feature names in the product. &lt;/P&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;A href="http://www.sunflowerhead.com/msimages/CustomUISchema.zip"&gt;&lt;STRONG&gt;Download B2TR customUI Schema&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Along with the control ID list, another reference we've created is the Office 2007 Icons Gallery. Open this file and you'll get a new group on the Developer tab in Excel, filled with galleries of the icons you can reuse in your Office 2007 solutions. Just click an icon, and you'll learn its control ID. Use this ID with the imageMso attribute to copy our icons to your controls. &lt;/P&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;A href="http://www.sunflowerhead.com/msimages/Office2007IconsGallery.zip"&gt;&lt;STRONG&gt;Download Office 2007 Icons Gallery&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Perhaps the most interesting functionality we added in B2TR is the ability to execute built-in controls by control ID, and the ability to query control properties by control ID. &lt;/P&gt;
&lt;P&gt;For example, if you want to find out if the Save button is enabled, just call: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;application.CommandBars.GetEnabledMso("FileSave") &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;and we'll return a boolean with the answer. And if you want to programmatically execute an obscure command that has no object model equivalent, just fire off: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;application.CommandBars.ExecuteMso("MyObscureControlID") &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The other functions are GetImageMso, GetLabelMso, GetPressedMso, GetScreentipMso, GetSupertipMso, and GetVisibleMso. &lt;/P&gt;
&lt;P&gt;The VBA object browser lists the function parameters and return values, which will also be detailed &lt;A href="http://msdn.microsoft.com/office/tool/ribbon/"&gt;on our MSDN site&lt;/A&gt; when it is updated in the coming weeks. &lt;/P&gt;
&lt;P&gt;Thanks and let us know if you have questions. Happy solution-building!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=755336" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>Ribbon Extensibility: A VBA Sample</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/06/01/613157.aspx</link><pubDate>Thu, 01 Jun 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:613157</guid><dc:creator>jensenh</dc:creator><slash:comments>35</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=613157</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/06/01/613157.aspx#comments</comments><description>&lt;H3&gt;Today's Guest Writer: Savraj Dhanjal&lt;/H3&gt;&lt;EM&gt;Savraj is a Program Manager on the Office User Experience team focused on user interface extensibility for Office developers.&lt;/EM&gt; 
&lt;P&gt;Now that you've got Beta 2, you can download and open &lt;A href="http://officeblogs.net/UI/RxDemo.zip"&gt;RxDemo.xlsm&lt;/A&gt;, a new file format document that uses RibbonX and works on Beta 2. &lt;/P&gt;
&lt;P&gt;If you haven't changed your Macro security settings from the default, you'll receive a security alert. If you trust the document, click "Enable Content..." After carefully reading the ensuing dialog box, select "Enable this content." If everything worked, you can now click around on the custom controls. Notice the items added to the Office Menu, the custom "RibbonX" tab that can be made visible on from the add-ins tab, and the various controls that you should recognize from previous blog posts. &lt;/P&gt;
&lt;P&gt;Take a look at the code behind the buttons in VBA, and if you want to look at the markup behind the document, I suggest you try out the &lt;A href="http://openxmldeveloper.org/articles/CustomUIeditor.aspx"&gt;Custom UI editing tool&lt;/A&gt;, a tool that lets you insert and edit images and the customUI part in new file format documents. There are some comments in the code as well as a number of explanatory super tooltips in this sample, so take a look and enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=613157" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>RibbonX Resources</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/05/25/606819.aspx</link><pubDate>Thu, 25 May 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:606819</guid><dc:creator>jensenh</dc:creator><slash:comments>22</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=606819</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/05/25/606819.aspx#comments</comments><description>&lt;P&gt;
&lt;H3&gt;Today's Guest Writer: Savraj Dhanjal&lt;/H3&gt;&lt;EM&gt;Savraj is a Program Manager on the Office User Experience team focused on user interface extensibility for Office developers. &lt;/EM&gt;
&lt;P&gt;Yesterday Jensen linked to the &lt;A href="http://msdn.microsoft.com/office/tool/ribbon/default.aspx"&gt;Ribbon developer center&lt;/A&gt;. It's where we are bringing together all of our content on Ribbon Extensibility. I just wanted to highlight some of the key resources on the site. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/en-us/ms406046(office.12).aspx"&gt;Customizing the Ribbon For Developers, Part 1&lt;/A&gt; takes you through the details of building a solution that customizes the Ribbon. If you're new to the whole idea, which you probably are, start here. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/en-us/ms406047(office.12).aspx"&gt;Customizing the Ribbon For Developers, Part 2&lt;/A&gt; includes a complete reference for every valid tag and attribute in a valid custom UI file. It also includes a FAQ with answers to common questions. For example, it tells you how to turn on RibbonX-related error messages. (Application Options &amp;gt; Advanced &amp;gt; General &amp;gt; Show add-in user interface errors.) &lt;/P&gt;
&lt;P&gt;The site also includes an &lt;A href="http://msdn2.microsoft.com/en-us/ms406052(office.12).aspx"&gt;overview document&lt;/A&gt; and a half-hour &lt;A href="http://download.microsoft.com/download/a/6/1/a61dd5df-f52c-42d5-a95c-7a7fb7a6a466/ExtendedRibbon.wmv"&gt;screencast&lt;/A&gt; that details ribbon customization via the extensibility model. &lt;/P&gt;
&lt;P&gt;The Beta 2 Schema will also be on the site shortly. For those of you that can't wait for it, I've &lt;A href="http://officeblogs.net/UI/customUI.xsd"&gt;attached it here&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Finally, the one document I hope every solution author reads is the &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=19e3bf38-434b-4ddd-9592-3749f6647105&amp;amp;displaylang=en"&gt;Style Guide for Solutions and Add-ins&lt;/A&gt;. It'll give you a basic idea of how to think about your add-in or solution in the context of the new user interface. The style guide is really about the cliché "with great power comes great responsibility," a quote that appears on blogs.msdn.com quite often. &lt;/P&gt;
&lt;P&gt;Please take a look at the documents and let us know what you think. They'll get updated between now and RTM for sure. Are there any particular samples that you would like to see?&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=606819" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>RibbonX Control Type Tour, Part 3</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/04/27/585051.aspx</link><pubDate>Thu, 27 Apr 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:585051</guid><dc:creator>jensenh</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=585051</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/04/27/585051.aspx#comments</comments><description>&lt;H3&gt;Today's Guest Writer: Savraj Dhanjal&lt;/H3&gt;
&lt;P&gt;&lt;I&gt;Savraj is a Program Manager on the Office User Experience team focused on user interface extensibility for Office developers.&lt;/I&gt; 
&lt;P&gt;This week, we'll take a look at the &lt;CODE&gt;gallery&lt;/CODE&gt; control. It's one of the most important controls in the new Office 2007 user experience, and we've exposed a good chunk of core gallery functionality for you to use in your own Office-based solutions.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/jensenh/archive/category/11719.aspx"&gt;As you may have read in the many blog postings already written about galleries&lt;/A&gt;, the purpose of a gallery is to roll up features which would have taken many clicks into a gallery of choices that lets you get the same result in just one click.&lt;/P&gt;
&lt;P&gt;In the example add-in I'm going to show, I've mocked up a gallery that allows you to insert pictures in one click, instead of opening a dialog, navigating the file tree, and selecting an image. I've dropped this gallery on the Insert tab in Word after the Illustrations group, because that's where it fits in best with the surrounding features.&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/ribbonx7/b1.jpg"&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx7/b1t.jpg"&gt;&lt;/A&gt;&lt;BR&gt;&lt;I&gt;The nature photos gallery, courtesy RibbonX &lt;BR&gt;(Click to enlarge)&lt;/I&gt;&lt;/P&gt;&lt;PRE&gt;&amp;lt;gallery id="nature" &lt;BR&gt;    label="Nature Photos"&lt;BR&gt;    size="large"&lt;BR&gt;    imageMso="FlyoutAnchorMovie"
    onAction="nature_OnAction"
    getItemCount="nature_getItemCount"
    getItemImage="nature_getItemImage"
    getItemLabel="nature_getItemLabel"
    showItemLabel="false"/&amp;gt;&lt;/PRE&gt;
&lt;P&gt;The anchor for a &lt;CODE&gt;gallery&lt;/CODE&gt; is similar to that of a &lt;CODE&gt;menu&lt;/CODE&gt; in that it can be small or large. In this case, I'm using a large, built-in film strip icon, with the &lt;CODE&gt;imageMso&lt;/CODE&gt; attribute. &lt;A href="http://blogs.msdn.com/jensenh/archive/2006/03/30/564894.aspx"&gt;As I've previously written&lt;/A&gt;, our controls use callbacks to specify dynamic properties like labels, and in some cases, the content of the control. The gallery control asks callbacks for the items that populate the gallery, unless the gallery contains statically declared items. In my example above, a callback returns 150x150 pixel PNG images converted to an &lt;CODE&gt;IPictureDisp&lt;/CODE&gt; for each item.&lt;/P&gt;
&lt;P&gt;One of the neat features of our gallery control is that it can automatically scale your images. The original PNG images used in my example are 150 pixels square. By specifying a new &lt;CODE&gt;itemHeight&lt;/CODE&gt; and &lt;CODE&gt;itemWidth&lt;/CODE&gt; the gallery will resize the images. I also changed the return value of my &lt;CODE&gt;getItemCount&lt;/CODE&gt; callback to return sixteen items instead of nine. The gallery creates a 4x4 grid for a group of sixteen items.&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/ribbonx7/b2.jpg"&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx7/b2t.jpg"&gt;&lt;/A&gt;&lt;BR&gt;&lt;I&gt;Sixteen items and smaller images&lt;BR&gt;(Click to enlarge)&lt;/I&gt;&lt;/P&gt;&lt;PRE&gt;&amp;lt;gallery id="nature"&lt;BR&gt;    label="Nature Photos"&lt;BR&gt;    size="large"&lt;BR&gt;    imageMso="FlyoutAnchorMovie"
    onAction="nature_OnAction"
    getItemCount="nature_getItemCount"
    getItemImage="nature_getItemImage"
    getItemLabel="nature_getItemLabel"
    itemHeight="75"
    itemWidth="75"
    showItemLabel="false"/&amp;gt;
&lt;/PRE&gt;
&lt;P&gt;You can also scale up images, of course. In the next example, the gallery is enlarging the 150-pixel square images to 200-pixel square images. The gallery control can also resize images without preserving the aspect ratio of the original image, but because it doesn't look great I didn't include a screenshot. :)&lt;/P&gt;
&lt;P&gt;You can also specify the number of rows and columns the gallery should display. In this case, I've got just one column and two rows.&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/ribbonx7/b3.jpg"&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx7/b3t.jpg"&gt;&lt;/A&gt;&lt;BR&gt;&lt;I&gt;Scaling up images, setting rows and columns&lt;BR&gt;(Click to enlarge)&lt;/I&gt;&lt;/P&gt;&lt;PRE&gt;&amp;lt;gallery id="nature"&lt;BR&gt;    label="Nature Photos" &lt;BR&gt;    size="large" imageMso="FlyoutAnchorMovie"
    onAction="nature_OnAction"
    getItemCount="nature_getItemCount"
    getItemImage="nature_getItemImage"
    getItemLabel="nature_getItemLabel"
    itemHeight="200"
    itemWidth="200"
    rows="2"
    columns="1"
    showItemLabel="false"/&amp;gt;
&lt;/PRE&gt;
&lt;P&gt;You can also choose to display labels on gallery items. The example below contains labels for each item, resizes the images to be much smaller, and is set to show ten rows.&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/ribbonx7/b4.jpg"&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx7/b4t.jpg"&gt;&lt;/A&gt;&lt;BR&gt;&lt;I&gt;Showing labels on gallery items&lt;BR&gt;(Click to enlarge)&lt;/I&gt;&lt;/P&gt;&lt;PRE&gt;&amp;lt;gallery id="nature"&lt;BR&gt;    label="Nature Photos"&lt;BR&gt;    size="large"&lt;BR&gt;    imageMso="FlyoutAnchorMovie"
    onAction="nature_OnAction"
    getItemCount="nature_getItemCount"
    getItemImage="nature_getItemImage"
    getItemLabel="nature_getItemLabel"
    itemHeight="20"
    itemWidth="20"
    rows="10"
    columns="1"
    showItemLabel="true"/&amp;gt;
&lt;/PRE&gt;
&lt;P&gt;Just like in many of the built-in galleries it Office 2007, you can also add buttons to the bottom of a gallery. Typically these buttons would configure what appears in the gallery or open a related settings dialog box.&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/ribbonx7/b5.jpg"&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx7/b5t.jpg"&gt;&lt;/A&gt;&lt;BR&gt;&lt;I&gt;Buttons at the bottom&lt;BR&gt;(Click to enlarge)&lt;/I&gt;&lt;/P&gt;&lt;PRE&gt;&amp;lt;gallery id="nature"&lt;BR&gt;    label="Nature Photos"&lt;BR&gt;    size="large" &lt;BR&gt;    imageMso="FlyoutAnchorMovie"
    onAction="nature_OnAction"
    getItemCount="nature_getItemCount"
    getItemImage="nature_getItemImage"
    getItemLabel="nature_getItemLabel"
    rows="2"
    columns="2"
    showItemLabel="false"&amp;gt;
    &lt;BR&gt;    &amp;lt;button id="b222"&lt;BR&gt;      imageMso="Save"&lt;BR&gt;      label="Save selection to Nature Photos Server..."/&amp;gt;
    &lt;BR&gt;    &amp;lt;button id="b229"&lt;BR&gt;      imageMso="Dollar"&lt;BR&gt;      label="Purchase more photos..."/&amp;gt;&lt;BR&gt;
&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&amp;lt;/gallery&amp;gt;
&lt;/PRE&gt;
&lt;P&gt;That's the high-level overview of the functionality provided by the gallery control. We can't wait to see how you'll use it in the solutions you create!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=585051" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item><item><title>Finding a New Purpose</title><link>http://blogs.msdn.com/b/jensenh/archive/2006/04/20/579867.aspx</link><pubDate>Thu, 20 Apr 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:579867</guid><dc:creator>jensenh</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/jensenh/rsscomments.aspx?WeblogPostID=579867</wfw:commentRss><comments>http://blogs.msdn.com/b/jensenh/archive/2006/04/20/579867.aspx#comments</comments><description>&lt;h3&gt;Today's Guest Writer: Savraj Dhanjal&lt;/h3&gt;
&lt;p&gt;&lt;i&gt;Savraj is a Program Manager on the Office User Experience team focused on user interface extensibility for Office developers.&lt;/i&gt; 
&lt;/p&gt;&lt;p&gt;Today we're going to take a break from control types to highlight one of the more powerful features exposed by RibbonX: Command Repurposing.&lt;/p&gt;
&lt;p&gt;In our research to understand how people were using extensibility in Office 2003, we found that developers at corporations often modified the built-in UI. Beyond adding a few buttons to the menus and toolbars, developers fundamentally changed the behavior of built-in buttons. If you're not familiar with Office development, you might ask, "Why in the world would someone do that?"&lt;/p&gt;
&lt;p&gt;Imagine the international law firm of Faller, Mogilevsky, and Luu. FML doesn't want its employees printing Word documents or PowerPoint presentations unless they conform to the firm's strict standards for document formatting and style. To ensure standards are met, FML's software development team builds, as one of their many add-ins, a solution that overrides a click on the Print button. Clicking on Print now runs FML's code that checks the document for errors. If there are any errors, the user is notified. If not, the code sends the document to the printer.&lt;/p&gt;
&lt;p&gt;You can imagine this same scenario applying to the Save button. FML wants to make sure all the metadata attached to a document is properly formatted before the user saves it. So FML takes over the Save button as well. When the user clicks Save, FML's code runs, updates metadata, and permits Office to continue with the built-in Save operation.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;A few ways to do it today&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;There are a few ways to do this in Office 2003. The first way is through specially named macros in Word. Hit Alt-F11, select Insert &amp;gt; Module in the Visual Basic Editor, and paste the following macro into the code window.&lt;/p&gt;&lt;code&gt;Sub FileSave()&lt;br&gt;MsgBox ("Surprise! This works!")&lt;br&gt;End Sub &lt;/code&gt;
&lt;p&gt;Test the macro by pressing F5 while your insertion point is inside the macro code. If you see the message box, it works. Now select Save from Word's File Menu. Surprise, it really does work. Every time you select "Save" Word will run your Macro and display a message box, instead of the built-in Save command. As yet another testament to Office as a platform, this behavior was introduced well before 1996, as part of WordBasic. The Word MVP's have a nice &lt;a href="http://word.mvps.org/faqs/MacrosVBA/InterceptSavePrint.htm"&gt;write-up&lt;/a&gt; on this behavior, and there are a number of other special macro names. Since this functionality pre-dated CommandBars, it only works in Word, and it hooks all instances of the Save button, including the one on the toolbar, as well as the control key shortcuts. So if you hit CTRL-S, the macro runs. The same goes for a click on the floppy disk icon in the Standard Toolbar. Isn't that neat? With three lines of VBA code (in Word) you can change the behavior of Save.&lt;/p&gt;
&lt;p&gt;If you wanted to match this precise behavior using CommandBars, you would need to find each instance of the Save button and give it a new "onAction" macro, and the user might have customized the interface, so you'll have to find all instances of it. The following code snippet changes the onAction of the Save button on just the Standard Toolbar. After you run the Macro below, the Save button in the Toolbar and the Save button in the File Menu will do different things, and this method doesn't capture CTRL-S.&lt;/p&gt;&lt;code&gt;Sub newSaveAction()&lt;br&gt;Application.CommandBars("Standard").Controls("Save").OnAction = "surprise"&lt;br&gt;End Sub&lt;br&gt;&lt;br&gt;Sub surprise()&lt;br&gt;MsgBox ("Surprise!")&lt;br&gt;End Sub&lt;br&gt;&lt;/code&gt;
&lt;p&gt;Run the first macro above, and then a click on the Save button will call the second one. This general idea works in all of the Applications with CommandBars.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;But wait, there's more!&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;It shouldn't surprise you that there's one more way to do this. If I want to take over the Print button in Office 2003, I can listen for the button click event. Once the right control comes through this event, I can run some code and decide whether the built-in action should continue. The following code repurposes the Print button on Word's File Menu. Just copy and paste the code below into the Visual Basic Editor (Alt-F11), and run the first Macro.&lt;/p&gt;&lt;code&gt;Private WithEvents buttonEvent As CommandBarButton&lt;br&gt;&lt;br&gt;Sub RunMe()&lt;br&gt;Set buttonEvent = Application.CommandBars(&lt;br&gt;&amp;nbsp; "Menu Bar").Controls("File").Controls("Print...")&lt;br&gt;End Sub&lt;br&gt;&lt;br&gt;Private Sub buttonEvent_Click(ByVal Ctrl As&lt;br&gt;&amp;nbsp; CommandBarButton, CancelDefault As Boolean)&lt;br&gt;MsgBox ("File has errors.")&lt;br&gt;CancelDefault = True&lt;br&gt;End Sub &lt;/code&gt;
&lt;p&gt;After you run the macro called &lt;code&gt;RunMe&lt;/code&gt; a click on the Print button in the File Menu will yield a message box that says "File has errors." The code above sets &lt;code&gt;cancelDefault&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; to cancel the default action, in this case, printing. If you set CancelDefault to &lt;code&gt;false&lt;/code&gt; the built-in action will continue after you close the message box. With the event-based method, you get an additional feature of continuing or stopping the built-in event, and this works in VBA and COM for all of the applications.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Enter RibbonX...&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The sample code to repurpose the built-in Save and Print buttons, in RibbonX, looks like this:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;CustomUI Markup&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"&amp;gt;&lt;br&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;&amp;lt;commands&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;command idMso="Save" onAction="mySave"/&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;command idMso="Print" onAction="myPrint"/&amp;gt;&lt;br&gt;&amp;lt;/commands&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;/customUI&amp;gt;&lt;br&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;C# Code&lt;/b&gt;&lt;/p&gt;&lt;code&gt;public void mySave(IRibbonControl control, ref bool&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CancelDefault)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show("Hello!");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CancelDefault = true;&lt;br&gt;}&lt;br&gt;&lt;br&gt;public void myPrint(IRibbonControl control, ref bool&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CancelDefault)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show("Hello!");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CancelDefault = false;&lt;br&gt;}&lt;br&gt;&lt;/code&gt;
&lt;p&gt;As you can see from the markup, we've endeavored to make it as simple as possible. Just tell us the control IDs of the built-in controls you would like to repurpose in the &lt;code&gt;&amp;lt;commands&amp;gt;&lt;/code&gt; section. A click on that command, wherever it appears in the user interface, will trigger the onAction callback you specify. Your onAction callback can then, just like the buttonClick_event, decide whether to continue with the built-in functionality.&lt;/p&gt;
&lt;p&gt;We've also added a little more functionality -- control over state. You can specify if this control should always be disabled, or give us a callback to manage the enabled state.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;CustomUI Markup&lt;/b&gt;&lt;/p&gt;&lt;code&gt;&amp;lt;customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;commands&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;command idMso="Save" enabled="false"/&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;command idMso="Print" getEnabled="myState"/&amp;gt;&lt;br&gt;&amp;lt;/commands&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;/customUI&amp;gt;&lt;br&gt;&lt;/code&gt;
&lt;p&gt;In the example above, the Save button is permanently disabled, and the Print button gets its state from the "AND" of its built-in state and the getEnabled callback "myState." When both Office says it's enabled, AND when your callback says it's enabled, the control is enabled. If either your code or Office says the Print button should be disabled, it's disabled.&lt;/p&gt;
&lt;p&gt;In RibbonX, just give us one line of XML and you completely own what happens when the control is clicked. Best of all, in Word and PowerPoint, keyboard shortcuts are also captured, a marked improvement over Office 2003 events behavior.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=579867" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/All+Office+2007+UI+Posts/">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/b/jensenh/archive/tags/Developer/">Developer</category></item></channel></rss>