<?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/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>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Using RibbonX with C++ and ATL</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/1241672.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=1241672</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=1241672</wfw:comment><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/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>RibbonX Image FAQ</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/1156857.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=1156857</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=1156857</wfw:comment><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/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>Licensing the 2007 Microsoft Office User Interface</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/1113831.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=1113831</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=1113831</wfw:comment><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/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/FAQ/default.aspx">FAQ</category></item><item><title>Developer Resources for Office 2007 RTM</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/1067577.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=1067577</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=1067577</wfw:comment><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/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>Final Schema for RibbonX-based Solutions</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/875328.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=875328</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=875328</wfw:comment><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/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>RibbonX Updates for B2TR</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/755336.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=755336</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=755336</wfw:comment><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/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>Ribbon Extensibility: A VBA Sample</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/613157.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=613157</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=613157</wfw:comment><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/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>RibbonX Resources</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/606819.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=606819</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=606819</wfw:comment><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/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>RibbonX Control Type Tour, Part 3</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/585051.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=585051</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=585051</wfw:comment><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;img src="http://blogs.msdn.com/aggbug.aspx?PostID=585051" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>Finding a New Purpose</title><link>http://blogs.msdn.com/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><comments>http://blogs.msdn.com/jensenh/comments/579867.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=579867</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=579867</wfw:comment><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;img src="http://blogs.msdn.com/aggbug.aspx?PostID=579867" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>RibbonX Control Type Tour, Part 2</title><link>http://blogs.msdn.com/jensenh/archive/2006/04/13/575745.aspx</link><pubDate>Thu, 13 Apr 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:575745</guid><dc:creator>jensenh</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/jensenh/comments/575745.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=575745</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=575745</wfw:comment><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;Hey everyone! Another week, another batch of RibbonX controls and attributes. You can use &lt;A href="http://blogs.msdn.com/jensenh/archive/2006/04/06/569876.aspx"&gt;last week's markup wrapper&lt;/A&gt; to create valid XML from code snippets below. 
&lt;P&gt;&lt;B&gt;CheckBox&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;The &lt;CODE&gt;checkBox&lt;/CODE&gt; is one of the many new control types exposed in the Ribbon. It's got the same behavior as a &lt;CODE&gt;toggleButton&lt;/CODE&gt;, but it has a completely different visual style. Checkboxes are useful for settings and options that don't change content in your document. ToggleButtons, like the built-in Bold button, are better for cases where you want the state of your selection reflected. Office 2007's most prominent built-in checkBoxes are on the View Tab.&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx5/checkboxes.jpg"&gt;&lt;BR&gt;&lt;I&gt;Three checkBoxes. The mouse hovers over the second checkBox.&lt;/I&gt;&lt;/P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="Settings"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c1" label="Office Seat Heater" onAction="heater"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c2" label="Mouse Traction Control" onAction="traction"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c3" label="Keyboard Sport Mode" onAction="sport"/&amp;gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;
&lt;P&gt;Unlike most other controls, a &lt;CODE&gt;checkBox&lt;/CODE&gt;, when promoted to the QAT, keeps its label by default. Just right click a custom &lt;CODE&gt;checkBox&lt;/CODE&gt;, select add to QAT, and voila, it's available so you can always get to it.&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx5/i2.jpg"&gt;&lt;BR&gt;&lt;I&gt;Custom checkBox on the QAT.&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Separator&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;A separator is just that--a logical division between controls in your group. Separators have no label--just a unique ID. By themselves, they're not very interesting, but they can politely part controls that are too close for comfort within a group. 
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx5/i3.jpg"&gt;&lt;BR&gt;&lt;I&gt;Separation in action.&lt;/I&gt;&lt;/P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="Settings"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c1" label="Office Seat Heater" onAction="heater"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c2" label="Mouse Traction Control" onAction="traction"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c3" label="Keyboard Sport Mode" onAction="sport"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;separator id="s1"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b1" imageMso="ExcelChartGallery1" size="large" label="Air/Fuel Mixture" /&amp;gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;
&lt;P&gt;&lt;B&gt;LabelControl&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;The &lt;CODE&gt;labelControl&lt;/CODE&gt; lets you put a text label in your group. The label provides a little extra information to make sure the user's on the right track, and often eliminates text duplication among the controls below it. Labels, like checkBoxes, are seen in very few places in the Office 2007 Ribbon.&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx5/i4.jpg"&gt;&lt;BR&gt;&lt;I&gt;Labels. Use sparingly.&lt;/I&gt;&lt;/P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="Settings"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;labelControl id="lc1" label="HCI PowerToys" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c2" label="Mouse Traction Control" onAction="traction"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c3" label="Keyboard Sport Mode" onAction="sport"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;separator id="s1"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;labelControl id="lc2" label="Ambiance" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c4" label="Background Music" onAction="enableMusic"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c5" label="Mood Lighting" onAction="enableLights"/&amp;gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;
&lt;P&gt;&lt;B&gt;Tips &amp;amp; Launchers&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;To provide more information about a particular control on hover, you can use the &lt;CODE&gt;tooltip&lt;/CODE&gt; (soon to be renamed &lt;CODE&gt;screentip&lt;/CODE&gt;) and &lt;CODE&gt;supertip&lt;/CODE&gt; attributes on controls. The &lt;CODE&gt;tooltip&lt;/CODE&gt; works as you would expect, and the &lt;CODE&gt;supertip&lt;/CODE&gt; is a multi-line text string. 
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx5/i5.jpg"&gt;&lt;BR&gt;&lt;I&gt;Using the tooltip and supertip properties to explain traction control on mouse hover.&lt;/I&gt;&lt;/P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="Settings" &amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;labelControl id="lc1" label="HCI PowerToys" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c2" label="Mouse Traction Control" onAction="traction" tooltip="Office 2007 Traction PowerToy" supertip="Enable enhanced mouse traction on snow, ice, and loose paper."/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c3" label="Keyboard Sport Mode" onAction="sport"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;separator id="s1"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;labelControl id="lc2" label="Ambiance" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c4" label="Background Music" onAction="enableMusic"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;checkBox id="c5" label="Mood Lighting" onAction="enableLights"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;advanced&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;lt;button id="b5" label="Settings Dialog" tooltip="Open settings dialog." supertip="All the power you expect from Office." onAction="dialog"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/advanced&amp;gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;
&lt;P&gt;The group shown above also has a "dialog launcher," in the bottom-right corner. This launcher opens a the full settings dialog. You declare the launcher by putting a &lt;CODE&gt;button&lt;/CODE&gt; in the &lt;CODE&gt;advanced&lt;/CODE&gt; section of a group.&lt;/P&gt;
&lt;P&gt;As a final note, you'll notice my COM Add-In's name, "RibbonX Demo," is in the footer of the super tooltip. This way, end-users can directly associate additional functionality with the add-in that provided it, giving credit where credit is due. Pressing F1 for help will take end-users to help on Office add-ins. Unfortunately, end-users would probably uninstall my add-in, because Mouse Traction Control isn't implemented. I hear we're working on it for Office 14. :) &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=575745" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>RibbonX Control Type Tour, Part 1</title><link>http://blogs.msdn.com/jensenh/archive/2006/04/06/569876.aspx</link><pubDate>Thu, 06 Apr 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:569876</guid><dc:creator>jensenh</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/jensenh/comments/569876.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=569876</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=569876</wfw:comment><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;This week, we'll look at the different types of buttons you can create with RibbonX. The Ribbon is a two-dimensional UI space, and as you can see from our built-in groups, there's a fair amount of variety in controls and control arrangement. The extensibility model exposes much of the richness and flexibility available in the different Ribbon control types, and buttons are no exception. I've included some code snippets that you can paste inside the following wrapper, to get valid customUI markup.&lt;/P&gt;&lt;CODE&gt;&amp;lt;customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;ribbon&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tabs&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tab idMso="TabAddins"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- insert snippet here --&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tab&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tabs&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/ribbon&amp;gt;&lt;BR&gt;&amp;lt;/customUI&amp;gt;&lt;BR&gt;&lt;/CODE&gt;
&lt;P&gt;&lt;B&gt;"It's just Buttons"&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Ribbon extensibility, at its core, is about how developers can make a custom button show up in the Ribbon. Profound, isn't it? :) Anyway, A &lt;CODE&gt;button&lt;/CODE&gt; can be small or large, and it can show or hide its label. It can also have a tooltip or a super tooltip. Like all custom controls in RibbonX that have images, you can copy the image for this button from a built-in control, using the &lt;CODE&gt;imageMso&lt;/CODE&gt; property.&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx4/b1.jpg"&gt;&lt;BR&gt;&lt;I&gt;Four custom buttons. Each button snags its image from a built-in control.&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="My Group"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b1" imageMso="WebInsertHyperlink"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size="large" label="Surf the Net" onAction="surf"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;lt;button id="b2" imageMso="HappyFace"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/CODE&gt;&lt;CODE&gt;label="Smile"&amp;nbsp;onAction="smile"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b3" imageMso="FormatPainter" label="Paint"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; onAction="paint"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b4" imageMso="AutoFilter" label="Filter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/CODE&gt;&lt;CODE&gt;onAction="filter"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;You can also hide the labels on built-in buttons, so you get small 16x16 icons that appear quite like the icons on toolbars in non-Ribbon applications. Large buttons images are 32x32 pixels. 
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx4/b2.jpg"&gt;&lt;BR&gt;&lt;I&gt;Hiding labels with the &lt;CODE&gt;showLabel&lt;/CODE&gt; property.&lt;/I&gt;&lt;/P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="My Group"&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b1" imageMso="WebInsertHyperlink"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; size="large" label="Surf the Net" onAction="surf"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b2" imageMso="HappyFace"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" label="Smile" onAction="smile"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b3" imageMso="FormatPainter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" label="Paint" onAction="paint"/&amp;gt; &lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b4" imageMso="AutoFilter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" label="Filter" onAction="filter"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;
&lt;P&gt;&lt;B&gt;ToggleButtons&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;The canonical example of a toggleButton is the Bold button. You can create your own toggleButtons, and you can make them behave just like the bold button by writing callbacks. By tweaking the XML from the first example, we get a pair of toggleButtons. 
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx4/b3.jpg"&gt;&lt;BR&gt;&lt;I&gt;ToggleButtons stay down when you click them.&lt;/I&gt;&lt;/P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="My Group"&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;toggleButton id="b1" imageMso="WebInsertHyperlink"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; size="large" label="Surf the Net" onAction="surf"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b2" imageMso="HappyFace"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" label="Smile" onAction="smile"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;toggleButton id="b3" imageMso="FormatPainter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" label="Paint" onAction="paint"/&amp;gt; &lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="b4" imageMso="AutoFilter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" label="Filter" onAction="filter"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;
&lt;P&gt;&lt;B&gt;SplitButtons&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;SplitButtons combine the wonders of a one-click button with a set of choices in a menu. Here's a splitButton that I've placed in the Ribbon, using our existing button images.&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx4/b4.jpg"&gt;&lt;BR&gt;&lt;I&gt;Left: Hovering the button-half of a splitButton.&lt;BR&gt;Right: Dropping the menu-half of a splitButton.&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="My Group"&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;splitButton id="mySplit" size="large"&amp;gt; &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b1" imageMso="WebInsertHyperlink"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; label="Surf the Net" onAction="surf"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;menu id="splitMenu" itemSize="large"&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b2" imageMso="HappyFace" label="Smile"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/CODE&gt;&lt;CODE&gt;onAction="smile" description="View pages about smiles."/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b3" imageMso="FormatPainter" label="Paint"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; onAction="paint" description="Learn to paint&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; your house."/&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b4" imageMso="AutoFilter" label="Filter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/CODE&gt;&lt;CODE&gt;onAction="filter" description="Read about water&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; purification."/&amp;gt;&lt;BR&gt;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/menu&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/splitButton&amp;gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;There are a few interesting things going on in the image above. First, you might notice that the menu items are large, and each item is displaying its description. You get this visual when you set your menu's &lt;CODE&gt;itemSize&lt;/CODE&gt; to &lt;CODE&gt;large&lt;/CODE&gt; -- we call this a "rich menu." You'll also notice that the &lt;CODE&gt;HappyFace&lt;/CODE&gt; icon is a bit blurry. Wondering why? We didn't create, for Office 2007, a 32x32 version of this icon, because none of the applications use it. Office is scaling up the built-in 16x16 icon. (We could probably write a separate blog entry about the origins of the built-in HappyFace icon.) By the same token, if your add-in only has a large icon, and it needs to display the icon on a small button, Office will scale it down.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Button Arrangement&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;So you can have big and small buttons, and you can set properties like visibility, enabled state, and the label dynamically. What else can you do? Well you've probably noticed the fancy runs of buttons on some of the tabs in the Ribbon applications. You can create your own &lt;CODE&gt;buttonGroups&lt;/CODE&gt; in RibbonX as well. Just wrap your buttons in this tag, and you get that neat visual style, a throwback to the days of toolbars. For the example below I also grabbed a couple built-in Office controls, using &lt;CODE&gt;idMso&lt;/CODE&gt;, and these buttons work as you would expect.&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx4/b5.jpg"&gt;&lt;BR&gt;&lt;I&gt;Matching the toolbar-esque visual style. The last six buttons are in buttonGroups.&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="My Group"&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="r1" label="Vanilla Button" imageMso="Cut" /&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;buttonGroup id="myBGroup"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b1" imageMso="WebInsertHyperlink"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/CODE&gt;&lt;CODE&gt;label="Surf the Net" onAction="surf"/&amp;gt;&lt;BR&gt;&lt;/CODE&gt;&lt;CODE&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b2" imageMso="HappyFace" label="Smile"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; onAction="smile" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/buttonGroup&amp;gt;&lt;BR&gt;&lt;/CODE&gt;&lt;CODE&gt;&lt;BR&gt;&amp;nbsp; &amp;lt;buttonGroup id="myBGroup2"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b3" imageMso="FormatPainter" label="Paint"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" onAction="paint" /&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;toggleButton idMso="Bold"/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="b4" imageMso="AutoFilter" label="Filter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; showLabel="false" onAction="filter" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;toggleButton idMso="Italic"/&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/buttonGroup&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;lt;/group&amp;gt; &lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Custom Button Images&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;If you're an icon buff, you'll be excited to know that RibbonX now supports icon images with 32-bits -- 8 bits for red, green, and blue, and 8 bits for an alpha (transparency) channel. The "M" below is a 24-bit PNG with transparency. The soft edge of the shadow is preserved, thanks to the alpha channel. When you hover over the buttons, or when you click on them, you get all of the visual effects of the Ribbon for free.&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/ribbonx4/b6.jpg"&gt;&lt;BR&gt;&lt;I&gt;Custom button with alpha channel.&lt;/I&gt;&lt;/P&gt;&lt;CODE&gt;&amp;lt;group id="myGroup" label="My Group"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;button id="M" size="large" label="The M Button"&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; getImage="getM"/&amp;gt;&lt;BR&gt;&amp;lt;/group&amp;gt;&lt;BR&gt;&lt;/CODE&gt;
&lt;P&gt;In the sample above, my C# callback, &lt;CODE&gt;getM&lt;/CODE&gt;, grabs the PNG file, converts it to an &lt;CODE&gt;IPictureDisp&lt;/CODE&gt;, and returns it to Office. In CommandBars, transparency was governed by the &lt;CODE&gt;mask&lt;/CODE&gt; property -- which allowed to you "mask off" pixels in your button's &lt;CODE&gt;picture&lt;/CODE&gt; property. Before picture and mask, we had copyFace and pasteFace, which are currently &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dno2k3ta/html/odc_ofcmdbarbest.asp"&gt;deprecated&lt;/A&gt;, because calls to these functions overwrite the user's clipboard.&lt;/P&gt;
&lt;P&gt;So that's a quick preview of a few things you can do with buttons in the Ribbon. Stay posted for more exciting control types.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=569876" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>Hollywood Meets Office Add-ins</title><link>http://blogs.msdn.com/jensenh/archive/2006/03/30/564894.aspx</link><pubDate>Thu, 30 Mar 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:564894</guid><dc:creator>jensenh</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/jensenh/comments/564894.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=564894</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=564894</wfw:comment><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;One of the key design features of RibbonX is the "pull" model, a model where Office asks add-in controls for their state. Though different than the "push" model of CommandBars, the pull model enables a number of scenarios for add-ins such as end-user customization, a separation between UI and core solution code, and better performance.&lt;/P&gt;
&lt;P&gt;The model is straightforward--Office asks you for information about your controls--it "pulls" this information from your solution. Typically, Office asks for control properties that you did not declare up front in your customUI markup. Let's say you've got a button that should only be enabled when a certain condition is present. You write a function that returns true when your button is enabled. In your customUI markup, you associate this function with your button.&lt;/P&gt;
&lt;P&gt;When Office first loads your button, and the button is on screen, Office calls back to your code to see if the button should be enabled. Office doesn't ask again, unless you indicate that your state has changed, by calling IRibbonUI.Invalidate, which invalidates all of your custom controls, or IRibbonUI.InvalidateControl, which invalidates a particular control. The function that Office calls is called a callback.&lt;/P&gt;
&lt;P&gt;The interaction between Office and your add-in is best summarized in the following excerpt from a screenplay: &lt;/P&gt;&lt;PRE&gt;Add-in:   Hi Excel! Here's some customUI markup.
           ...
	  &amp;lt;button id="ButtonOne" label="Hello World!" 
	    getEnabled=”enabledState” onAction="sayHello"
            imageMso="HappyFace" /&amp;gt;
	   ...
	
Excel :   Great, I've applied it to the Ribbon. By the way, 
          it looks like you have set a callback for the enabled 
          state of ButtonOne. I'll call back to your function, 
          enabledState, the first time your button is on screen.

&lt;I&gt;Time passes, user clicks on custom tab&lt;/I&gt;

Excel :   The user clicked on your tab, your button is appearing.
          Calling enabledState, is ButtonOne enabled?

Add-in:   Yes.

Excel :   Ok great, I won't ask you again until your state changes.&lt;/PRE&gt;&lt;PRE&gt;*&lt;I&gt;Time passes, user does something&lt;/I&gt;

Add-in:   My state changed.  I'm calling Invalidate.

Excel :   Ok, calling enabledState, is ButtonOne enabled?

Add-in:   Yes.

Excel :   I won't ask you again until state changes.

&lt;I&gt;Go to *, until user closes the app.&lt;/I&gt;
&lt;/PRE&gt;
&lt;P&gt;Ok, so that wasn't too exciting. But it's an illustration of how pull works. Add-ins can return just about all of the properties you can declare in markup, like the images, labels, descriptions, screentips, visibility, and enabled state of controls, through callbacks. For dynamic controls, like galleries and comboboxes, callbacks return the items that populate these controls.&lt;/P&gt;
&lt;P&gt;The pull model affords several benefits for developers. The first is free end-user customization. If an end-user wants to promote a custom gallery to the &lt;A HREF="/jensenh/archive/2006/03/14/551142.aspx"&gt;quick access toolbar&lt;/A&gt;, she can. This behavior is completely transparent to the solution developer. Since code is never tied to the location of a control, callbacks for the state, label, or other properties still work even if the control is on the QAT. If your control was copied elsewhere in the world of CommandBars, you would have to write code to update the state of your control in both locations.&lt;/P&gt;
&lt;P&gt;If you've ever developed a complex solution with a large amount of UI, you probably understand the benefit of keeping core application code and the UI separate -- the benefit is that the UI remains easy to change. Because of the "location agnostic" nature of the pull model, RibbonX developers get this benefit as well. You (or a UI designer) can rearrange your UI without ever touching your core application code.&lt;/P&gt;
&lt;P&gt;We're also making add-ins more performant (in our own small way) with the pull model. In CommandBars, you could waste time updating controls that were not available or visible to the user. With RibbonX, if you tell us your state has changed, we only ask you for the new state of your controls if it is applicable -- that is, if your controls are visible to the user. If your controls are not on the screen (perhaps they're on a different tab) there's not reason to keep these hidden controls up to date.&lt;/P&gt;
&lt;P&gt;As a final note, the RibbonX implementation of the pull model brings add-ins much closer to how the applications have always worked internally. It should be no surprise that the Office apps follow this very same design pattern: If something changes, the on-screen controls get updated. When the state changes in an add-in, or in the application, Office updates its UI to reflect the new state.&lt;/P&gt;
&lt;P&gt;I'm sure some of you are wondering about the Hollywood-quality screenplay I'm writing regarding Office add-ins. Does anyone have any connections to get it submitted? A tentative title could be "Don't call us, we'll call you."&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/hw.jpg"&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=564894" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>Good Service for Add-ins</title><link>http://blogs.msdn.com/jensenh/archive/2006/03/23/558886.aspx</link><pubDate>Thu, 23 Mar 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:558886</guid><dc:creator>jensenh</dc:creator><slash:comments>26</slash:comments><comments>http://blogs.msdn.com/jensenh/comments/558886.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=558886</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=558886</wfw:comment><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;For Office 2007, we built the UI extensibility model around a simple idea: If your add-in or solution is installed, its UI customizations are present. If it's uninstalled, its customizations are no longer present. I would venture to guess that this is how anyone would expect UI extensibility to work.&lt;/P&gt;
&lt;P&gt;In Office 2003, you had to take a few extra steps to make sure your add-in behaved in this reasonable manner. As a first line of defense, you created controls as &lt;I&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dno2k3ta/html/odc_ofcmdbarbest.asp"&gt;temporary&lt;/A&gt;&lt;/I&gt;, ensuring that they would not be persisted beyond the current session. If you changed anything built-in, you needed to write code to clean up your changes on uninstall. A tricky task, because you didn't know what other add-ins, or the user, had done to customize the UI. You could set various protection bits to shield yourself from modification by users, and you could call ".reset" on built-in toolbars to get them back to a default state. But you might have just reset another add-ins customizations on a built-in toolbar. And how does the end user get that add-in back? Perhaps by reinstalling the add-in?&lt;/P&gt;
&lt;P&gt;In many ways, the CommandBars OM is a free-for-all. Any add-in can show up, change the UI (whether built-in or from another add-in), and then disappear. In Office 2003, these changes are persisted in Word and Excel in the Normal template and the Excel11.xlb file. As many of you know, the quickest way to reset your UI in these applications is to delete Normal.dot or Excel11.xlb. And for those of you that didn't know that, there's a chance that you're harboring UI customizations in those files from add-ins you uninstalled long ago.&lt;/P&gt;
&lt;P&gt;We wanted to move to a model where solutions didn't have to worry about what other add-ins were doing--a model that didn't leave the user with a bunch of "dead" buttons cluttering the UI. And if we could pull it off, it would be nice if this played well with end-user customization. Sure, it was &lt;I&gt;possible&lt;/I&gt; to author a well-behaved add-in with CommandBars, but it often involved a number of special steps, among them setting protection bits, and in the case of Word, using the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbawd10/html/woproCustomizationContext.asp"&gt;CustomizationContext&lt;/A&gt; variable. &lt;/P&gt;
&lt;P&gt;So we decided to move most persistence away from the application, and instead associate it with the add-ins and solutions. With RibbonX, add-ins provide Office with markup to customize the Ribbon, as you saw in last week's post. Since a solution's UI customizations are defined in XML, we can keep track of who's done what. For example, if we have three add-ins, each supplying markup to change the user interface, and add-in #2 gets uninstalled, we can remove its UI changes, because we know exactly what each add-in did. We do this in a manner transparent to developers--we've squarely taken on the burden of UI "housekeeping."&lt;/P&gt;
&lt;P&gt;With the UI as markup attached to solutions, we've also enabled a number of scenarios that were complicated or required extra code in Office 2003 to work properly. One of our favorite examples is document switching in Excel. In Excel 2003, you can attach a toolbar to a document. If you have two such documents open, with focus on one of them, you see both toolbars. As you switch between documents in Word 2003, however, the attached toolbars appear and disappear appropriately. If you wanted to get the same behavior in Excel, you would need to write code to show and hide the toolbars. In fact, if you ever want the attached toolbars to go away, even after the Excel workbook is closed, you need to write code--in Excel 2007, it just works as you would expect.&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/Savraj-b1.jpg"&gt;&lt;IMG src="http://officeblogs.net/UI/Savraj-b1_thumb.jpg"&gt;&lt;/A&gt;&lt;I&gt;&lt;BR&gt;With Book 1 selected, there are no customizations present.&lt;/I&gt;&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://officeblogs.net/UI/Savraj-b2.jpg"&gt;&lt;IMG src="http://officeblogs.net/UI/Savraj-b2_thumb.jpg"&gt;&lt;/A&gt;&lt;I&gt;&lt;BR&gt;When you select Book 2, the customizations magically appear, in this case, a custom tab, and a new group on the Sheet tab.&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;RibbonX works with both COM and VBA solutions, and we have endeavored to make the model as similar as possible between the two. You can create both application-level and document-level solutions with this model. If you want to create an application-level solution--that is, UI customizations that are visible for all open documents, you can create a COM Add-In, a VBA Excel Add-in (.xlam), a VBA PowerPoint Add-in (.ppam) or a Word Global Template (.dotm). Document level solutions can be authored as individual documents: .docx, .xlsx, .pptx--or the matching macro-enabled formats.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;COM Add-Ins&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dno2kta/html/msotrcom.asp"&gt;COM Add-ins&lt;/A&gt; come in many flavors, including &lt;A href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q302901"&gt;C#&lt;/A&gt;, C++, VB6, and VB.Net. On load of a COM Add-in, Office asks for your customUI markup via a method on the new IRibbonExtensibility interface, and this markup gets applied to the Ribbon.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;VBA Solutions&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;If you have built a VBA-based solution, be it a document, an add-in, or global template, Office looks for the customUI part in your new file format document. Once found, the customUI gets applied to the Ribbon.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Support for the Quick Access Toolbar&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;For all RibbonX add-ins, the user is free to add controls to the Quick Access Toolbar by right-clicking on them. When the solution or document is gone, the control no longer appears on the Quick Access Toolbar. Of course, you don't need to write a single line of extra code to make this work--we've written those lines here at Microsoft. :)&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="http://officeblogs.net/UI/Savraj-rx-customize.jpg"&gt;&lt;I&gt;&lt;BR&gt;Hello World group on the QAT&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Demand Loading&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Ribbon Extensibility is also designed to support "demand loading" of COM Add-Ins. So if you set your COM Add-In as demand-loaded, on first boot, we get (and cache) your XML, and on subsequent boots, your add-in isn't loaded until someone clicks on one of your controls. This allows you to minimize your solution's impact on application boot. Of course, we clear the cache if your add-in is ever uninstalled, again, all transparent to you.&lt;/P&gt;
&lt;P&gt;Last month I had the pleasure of traveling to the UK for some visits with customers and partners. While gathering feedback and understanding customer scenarios, I had a chance to ride on the &lt;A href="http://www.tfl.gov.uk/tube/"&gt;London Underground&lt;/A&gt;, a marvel of engineering, efficiency, and design. When in the Tube, I would often hear announcements like, "There is a good service on the Jubilee Line," which meant that the Jubilee Line trains were on time, as one would expect. Well I'm proud to say that Office 2007 will also offer "good service" with regard to add-in UI customizations--that is, they will come and go as you expect.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=558886" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item><item><title>Hello World, For Real</title><link>http://blogs.msdn.com/jensenh/archive/2006/03/16/552825.aspx</link><pubDate>Thu, 16 Mar 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:552825</guid><dc:creator>jensenh</dc:creator><slash:comments>25</slash:comments><comments>http://blogs.msdn.com/jensenh/comments/552825.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jensenh/commentrss.aspx?PostID=552825</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jensenh/rsscomments.aspx?PostID=552825</wfw:comment><description>&lt;p&gt;&lt;em&gt;Today I present guest writer Savraj Dhanjal, Program Manager on the Office User Experience Team. He is one of the members of our team focused on user interface extensibility for Office developers.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Articles on the Office 2007 user interface developer story will be published every Thursday for the next few weeks.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Today's Guest Writer: Savraj Dhanjal&lt;/h3&gt;
&lt;p&gt;I'm &lt;a href="mailto:savrajd@microsoft.com"&gt;Savraj Dhanjal&lt;/a&gt;, and I'm a program manager on the Office User Experience team. At the start of the Office 2007 product cycle, I worked on the technical framework that underlies the new user interface, and then I started working on UI extensibility--making sure existing solutions still work and can be updated to work well with the Ribbon.&lt;/p&gt;
&lt;p&gt;You've probably asked yourself: "when am I going to learn about how to create my own ribbon tabs, groups, and controls, so I can harness the power of the New UI in my Office 2007 add-ins and solutions?"&lt;/p&gt;
&lt;p&gt;You've read about all of the cool aspects of the new user interface from this blog, so as a developer, you want to know how you can update your solutions to work with the new UI. If you're not a developer, well, you may still find the discussion interesting.&lt;/p&gt;
&lt;p&gt;Enter the new UI extensibility model, code-named RibbonX. Optimized for common developer scenarios, we built RibbonX from the ground up, just like the new user interface itself.&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://officeblogs.net/UI/MyCodeGroup.png"&gt;&lt;/p&gt;
&lt;p&gt;As with all of the components of the new UI, the extensibility story was subject to the same "first-principles" scrutiny that every other feature received. Did we even need a developer story for Office 2007? Was it really used in the past? Would custom Task Panes be the solution which obviated the need for a UI extensibility story?&lt;/p&gt;
&lt;p&gt;Many of these questions came up because the last time UI extensibility was actively worked on was early in 1996, when the shared UI team rolled out the CommandBars object model. CommandBars attempted to unify the various UI extensibility models of the applications. After its release, we made a few tweaks, but as far as we were concerned, it was done, and most of the original people that worked on it moved on.&lt;/p&gt;
&lt;p&gt;In researching the question of whether the UI extensibility story was a necessary component of Office 2007, we began to realize how silly the question was in the first place. It became quite apparent that, in the ten years since CommandBars, hundreds of thousands, if not millions of solutions were built on Office, and almost all of them changed the UI in some way. Even though the first Office Developer Conference was in 2005, the notion of Office as a platform had been around almost as long as Office itself.&lt;/p&gt;
&lt;p&gt;So it was obvious that we needed a developer story. Again, like all of our other features, we wanted to know what didn't make sense with the existing model, so the new model would be free of these issues. Furthermore, we wanted to understand what developers were trying to accomplish, so that we could optimize for common scenarios. We turned to our customers, partners, and MVPs to understand the problems with, and uses of, UI extensibility today.&lt;/p&gt;
&lt;p&gt;We viewed the entire spectrum of Office extensibility, from the small freeware add-in that sprinkled a few buttons in the menus, to the whole hog remake of Excel that created a fully customized application. We uncovered issues with solution localization, control repurposing, end-user customization, consistency between the Office applications, and “housekeeping”--making sure buttons only appear when your solution is loaded, and disappear when unloaded. We found that it was hard to create a well-behaved add-in, and the right way to do it differed between the applications.&lt;/p&gt;
&lt;p&gt;We also found developers isolating menu and toolbar changes from the core of a solution. Developers created solutions where the UI is represented in a text or proprietary XML, so the UI can be updated without the overhead of rebuilding and redeploying an add-in. At first we thought it amazing, until we remembered that keeping UI separate from code is a good development practice. In fact, the Ribbon internally is built on markup--Office developers can change the layout of the Ribbon without going near core application code. &lt;/p&gt;
&lt;p&gt;Taking all of this in, the extensibility feature crew was tasked with building an extensibility story while UI itself was still being designed. We knew that our model should focus on consistency across all applications, close integration into the new UI, optimization for common scenarios, and allow for well-behaved add-ins by default. &lt;/p&gt;
&lt;p&gt;The feature crew set to work and exposed an XML schema that allows developers to create their own tabs, groups, and almost a dozen different control types, far more than the set of five custom controls offered by CommandBars. Since add-ins give us markup that contains customizations, it's easy for us to fix all of the housekeeping issues: when the add-in disappears, the UI disappears with it, and then markup is also easier to localize, understand, and manage. &lt;/p&gt;
&lt;p&gt;Here's the XML required for the special group shown above.&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;br&gt;&amp;lt;ribbon&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;tabs&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tab idMso="TabEnterData"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;group id="myGroup" label="My Code"&lt;br&gt;&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; insertBeforeMso="GroupEditingTools"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button id="myButton"&amp;nbsp;&lt;br&gt;&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="Hello World!" onAction="Hi"&amp;nbsp;&lt;br&gt;&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;size="large" imageMso="WebInsertHyperlink" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/group&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tab&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/tabs&amp;gt;&lt;br&gt;&amp;lt;/ribbon&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;/customUI&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In many ways, the model continues to evolve and improve, and we on the extensibility crew are still hard at work building the extensibility model, so stay tuned for more posts on how you can harness the power of the new UI.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=552825" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx">All Office 2007 UI Posts</category><category domain="http://blogs.msdn.com/jensenh/archive/tags/Developer/default.aspx">Developer</category></item></channel></rss>