DCSIMG
June 2011 - Posts - Arik Poznanski's Blog

Arik Poznanski's Blog

It CAN be done with .NET

News

MVP

MCC

CodeProject MVP

MCPD

MCTS

Subscribe to my blog by email

Arik Poznanski LinkedIn Profile

Email: arik.com at gmail dot com
or, use this form

Locations of visitors to this page


Sela Group

Sela Canada

DZone MVB

Links

Official Blogs

WPF / SL Blogs

Developers Blogs

June 2011 - Posts

Workaround For Crash In Performance Profiling Tools for WPF

Introduction

Every WPF developer knows the situation where you have a large line-of-business application, you’ve implemented all the features and when you finally run it on real data – it runs s-l-o-w.

Optimization Time!

Optimization for performance is fun since a 1% change of code gets you 99% change in performance. However, finding the one location you should change can be a pain.

This is why we’ve invented performance profilers. Profilers can help you pin-point the problem.

WPF?

WPF applications performance problems can usually be categorized to several kinds, for example, layout related, rendering related, etc.
Following is a nice list of common places to optimize when you work with WPF applications.

Microsoft provides a profiler specifically tuned for finding WPF related issues. You can find the installation guidelines on MSDN.

Note: if this is the first time you use it, and you don’t get the data, try the patch mentioned in this post.

When the profiler does work, it produces very interesting information.
For example, in the following image we can see the visual tree on the left and in it the hot element (painted red) where a lot of CPU cycles went (either due to rendering or layout).

Performance profiling tools for WPF

You can also see different categories of WPF (dispatcher related, layout related, rendering related, etc.) on the right and how much they affect the running application.

For more information I suggest you read on MSDN on how to work with this excellent tool, but now I want to discuss a different aspect of it.

Real Life Scenario

On real life applications the visual tree on the left can get quite big and the fact is that when you go too deep with the tree control the WPF profiler crash! Usually with an error similar to this:

Layout recursion reached allowed limit to avoid stack overflow: '255'

The problem is that the tree got too deep and WPF itself doesn’t support it.

Optimal Solution

What I would have liked from MS is a button that lets me set the current element as the new root of the tree so I could continue my search on the visual tree to find the hot element. Or at least provide the code for the WPF profiler, so I could do this myself.

Unfortunately, none of these options are available so I was forced to find a different solution.

My Solution

What I did was a little hacky, but nevertheless provides a solution to the problem.

The WPF profiler works with plugins. In fact the Visual Profiler itself is implemented as a plugin which comes by default.

So I’ve create a new plugin, which I called “My Visual Profiler”. My plugin aggregated the original plugin and adds a button on top of it. Then, using some nasty reflection I modify the tree so that the currently selected item in the tree is added to the root element. This enables me to continue debugging and effectively remove the limitation I previously had.

If you come across the same problem, you can use my plugin, provided here.

That’s it for now,
Arik Poznanski.

Ribbon with C++, Post 6: Ribbon Dynamic Structure Capabilities

This is the 6th and last post about using Windows Ribbon Framework features in C++. You can find the previous parts here: Part 1, Part 2, Part 3, Part 4 & Part 5.

In this post we will dive into the ribbon's dynamic structure capabilities, i.e. we will learn about the different ways to change the structure of the ribbon at runtime.

Specifically we will learn about Application Modes and Contextual Tabs. We will see what are these features, when to use them and how.

Application Modes

What is Application Modes?

Application Modes is a feature of the Windows Ribbon Framework that lets you completely change the ribbon according to the current application state.

This feature is best explained with an example. Consider Microsoft Paint.
When you open Microsoft Paint you see it in its default "edit mode":

image

Now, if you choose from the application menu: Print à Print Preview, the entire ribbon changes to the following "print mode":

image

Notice that in the different application "modes" you have completely different ribbon tabs.

More generally, applications sometimes have different modes in which they show a different user interface, for example:

  • Simple mode VS Advanced mode
  • Regular editor mode VS Print mode

The Windows Ribbon Framework supports the change of its ribbon user interface according to the current application mode. In order to use the ribbon application modes you need to:

  1. Set the available application modes for each ribbon item. This is done in design time.
  2. Set the current application mode. This is done in run time.

To summarize, Application Modes is a feature that allows the ribbon to change its UI according to the current application context.

Application Modes Remarks

  • You can set up to 32 different application modes, each identified by a number between 0 and 31.
  • Application modes can coexist, meaning you can set both "simple" mode and "advanced" mode as active at the same time. Internally the current application modes are represented by a single 32bit variable (which represents a Boolean array of size 32), thus explaining why you can only have 32 modes.
  • Mode 0 is the default mode. So if you don’t set the ApplicationModes attribute, 0 is the default.
  • At least one mode should be set at all times. You can’t disable all the modes (the framework will just ignore your last set).

How to use Application Modes?

Following is an example of an application with two modes: Simple and Advanced.
The application loads in simple mode. When the "Switch to Advanced" button is pressed the application changes to the advanced mode and as a result the ribbon changes and additional buttons are added. Note that some buttons appear in both simple and advanced modes.

The end result looks like this:

image

Figure 1: Demo application in simple mode

image

Figure 2: Demo application in advanced mode

Defining Application Modes in Ribbon Markup

Following is how we set the ApplicationModes attribute on various visual elements:

<?xml version='1.0' encoding='utf-8'?>
<Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
    <Application.Commands>
        ?
    </Application.Commands>

    <Application.Views>
        <Ribbon>
            <Ribbon.Tabs>
                <Tab CommandName="cmdTabMain"
                     ApplicationModes="0,1">
                    <Group CommandName="cmdGroupCommon"
                           SizeDefinition="ThreeButtons"
                           ApplicationModes="0,1">
                        <Button CommandName="cmdButtonNew" />
                        <Button CommandName="cmdButtonOpen" />
                        <Button CommandName="cmdButtonSave" />
                    </Group>
                    <Group CommandName="cmdGroupSimple"
                           SizeDefinition="TwoButtons"
                           ApplicationModes="0">
                        <Button CommandName="cmdButtonSwitchToAdvanced" />
                        <Button CommandName="cmdButtonMoreA" />
                    </Group>
                    <Group CommandName="cmdGroupAdvanced"
                           SizeDefinition="FourButtons"
                           ApplicationModes="1">
                        <Button CommandName="cmdButtonSwitchToSimple" />
                        <Button CommandName="cmdButtonMoreA" />
                        <Button CommandName="cmdButtonMoreB" />
                        <Button CommandName="cmdButtonMoreC" />
                    </Group>
                </Tab>
            </Ribbon.Tabs>
        </Ribbon>
    </Application.Views>
</Application>

Note we didn't specify the commands sections since there is nothing new in this respect.

In this example we create a tab with 3 groups in it: Common, Simple and Advanced.
The common group should always appears so we set its ApplicationModes attribute to “0,1”. The simple group should only appear in simple mode (0). Similarly, the advanced group should only appear in advanced mode (1).
Note that the tab element should appear in both modes, so you must also set its ApplicationModes attribute to “0,1”.

ApplicationModes can be set on the following elements:

  • Core tabs (as opposed to contextual tabs, which we will soon review).
  • Groups which are children of core tabs.
  • Button, SplitButton and DropDownButton but only when those controls are in the application menu.
Changing the Application Mode at runtime

Following is the command handler implementation for the two ribbon buttons, “Switch to Simple” and “Switch to Advanced”; each button changes the current application mode.

STDMETHODIMP CCommandHandler::Execute(
    UINT nCmdID,
    UI_EXECUTIONVERB verb,
    const PROPERTYKEY* key,
    const PROPVARIANT* ppropvarValue,
    IUISimplePropertySet* pCommandExecutionProperties)
{
    switch (nCmdID)
    {
        ?

    case ID_CMD_SWITCH_TO_ADVANCED:
        // set advanced mode
        g_pFramework->SetModes(UI_MAKEAPPMODE(1));
        break;

    case ID_CMD_SWITCH_TO_SIMPLE:
        // set simple mode
        g_pFramework->SetModes(UI_MAKEAPPMODE(0));
        break;
    }

    return S_OK;
}

The UI_MAKEAPPMODE macro is just a simple helper that converts an index number to a 32bit integer with the index bit set. It is defined in UIRibbon.h like this:

#define UI_MAKEAPPMODE(x) (1 << (x))

Of course, you can set several modes at the same time. Although in our application it doesn't make any sense, you can use the following code to set both 0 and 1 application modes:

g_pFramework->SetModes(UI_MAKEAPPMODE(0) | UI_MAKEAPPMODE(1));

Contextual Tabs

What is Contextual Tabs?

Contextual tabs are additional tabs that appear when you enable their context.
For example, in Microsoft Word 2007 / 2010, when you select a table in your document, you get two additional tabs (Design and Layout) that contain commands relevant only to tables. Put another way, the Design and Layout tabs are shown only if the "table context" is available.

image

Figure 3: Microsoft Word 2010 with two Contextual Tabs: Design and Layout

When working with Contextual Tabs the basic working unit is a TabGroup, which is a group of contextual tabs with the same context. For example, in figure 3, you can see the tab group named "Table Tools".

A TabGroup has a property named ContextAvailable (Property Identifier: UI_PKEY_ContextAvailable) of type UI_CONTEXTAVAILABILITY which can have the following values:

  • UI_CONTEXTAVAILIBILITY_ACTIVE – Meaning the context is currently available and the tab group should be active (i.e. selected).
  • UI_CONTEXTAVAILIBILITY_AVAILABLE – Meaning the context is currently available (but the tabs are not necessarily active).
  • UI_CONTEXTAVAILIBILITY_AVAILABLE – Meaning the context is currently not available (hence the additional tabs are hidden).

How to use Contextual Tabs?

Following is an example of an application that uses contextual tabs.
We define two tabs, "Design" and "Layout" which are in the same tab group.
In this example the context will be set and unset by pressing the "Select" button and "Unselect" button respectively. Of course, in a real application you should set the context according to a real context change.

The end result looks like this:

image

Figure 4: Demo application before setting the "Table Tools" context

 

image

Figure 5: Demo application after setting the "Table Tools" context

 

Defining Contextual Tabs in Ribbon Markup

Following is the views section for defining contextual tabs. The commands section is straightforward.

<?xml version='1.0' encoding='utf-8'?>
<Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
    <Application.Commands>
        ...
    </Application.Commands>

    <Application.Views>
        <Ribbon>
            <Ribbon.ContextualTabs>
                <TabGroup CommandName='cmdTabGroupTableTools'>
                    <Tab CommandName='cmdTabDesign'>
                        <Group CommandName='cmdGroupDesign'
                               SizeDefinition='ThreeButtons'>
                            <Button CommandName='cmdButtonDesign1' />
                            <Button CommandName='cmdButtonDesign2' />
                            <Button CommandName='cmdButtonDesign3' />
                        </Group>
                    </Tab>
                    <Tab CommandName='cmdTabLayout'>
                        <Group CommandName='cmdGroupLayout'
                               SizeDefinition='TwoButtons'>
                            <Button CommandName='cmdButtonLayout1' />
                            <Button CommandName='cmdButtonLayout2' />
                        </Group>
                    </Tab>
                </TabGroup>
            </Ribbon.ContextualTabs>
            <Ribbon.Tabs>
                <Tab CommandName="cmdTabMain">
                    <Group CommandName="cmdGroupCommon"
                           SizeDefinition="FiveButtons">
                        ...
                        <Button CommandName='cmdButtonSelect' />
                        <Button CommandName='cmdButtonUnselect' />
                    </Group>
                    ...
                </Tab>
            </Ribbon.Tabs>
        </Ribbon>
    </Application.Views>
</Application>

Note the new Ribbon.ContextualTabs section, where we define a single TabGroup for “Table Tools”, with two contextual tabs, “Design” and “Layout”.
Each tab has some buttons in it.
In addition we define in the main tab two buttons that we will use to set and unset the “Table Tools” context.

Setting Context for Contextual Tabs at Runtime

Following is the command handler implementation for the two ribbon buttons, “Select” and “Unselect”; each button changes the availability of the "Table Tools" context.

STDMETHODIMP CCommandHandler::Execute(
    UINT nCmdID,
    UI_EXECUTIONVERB verb,
    const PROPERTYKEY* key,
    const PROPVARIANT* ppropvarValue,
    IUISimplePropertySet* pCommandExecutionProperties)
{
    PROPVARIANT varNew;

    switch (nCmdID)
    {
        ?
        case ID_CMD_SELECT:
            // mark context as active
            UIInitPropertyFromUInt32(UI_PKEY_ContextAvailable,
                                        UI_CONTEXTAVAILABILITY_ACTIVE, &varNew);
            g_pFramework->SetUICommandProperty(ID_CMD_TABGROUP_TABLE,
                                        UI_PKEY_ContextAvailable, varNew);
            break;

        case ID_CMD_UNSELECT:
            // mark context as not available
            UIInitPropertyFromUInt32(UI_PKEY_ContextAvailable,
                                        UI_CONTEXTAVAILABILITY_NOTAVAILABLE, &varNew);
            g_pFramework->SetUICommandProperty(ID_CMD_TABGROUP_TABLE,
                                        UI_PKEY_ContextAvailable, varNew);
            break;
    }

    return S_OK;
}

Summary

In this post we have learned about the different ways we can use to change the structure of the ribbon at runtime.
We have seen how to use Application Modes to completely change the ribbon user interface according to the current application state. We have also seen how to use Contextual Tabs which enable us to add tabs depending on the current context.

You can find the full source code of the sample application used in this post here.

That's it for now,
Arik Poznanski.

Ribbon with C++, Part 5: Using Galleries with Windows Ribbon Framework

This is the 5th post about Windows Ribbon Framework features.
On previous posts we have introduced the ribbon framework, seen a complete example, and reviewed how to use buttons-based UI controls and how to control their layout.

In this post we continue our exploration of the Windows Ribbon Framework, this time focusing on Gallery controls.

We will learn what galleries are and what is the difference between an item gallery and a command gallery. We will learn about the different gallery controls: ComboBox, DropDownGallery, SplitButtonGallery and InRibbonGallery.
Of course we will see how to set gallery items and how to respond to a user choice.

What is a gallery?

A gallery is a ribbon UI control which contains a list of elements. The elements in the list are represented by a text caption or an image, and can be organized by categories.

image

Figure 1: An example of a gallery

The galleries that we will soon review comes in two flavors: item gallery and command gallery.

Item Gallery vs. Command Gallery

In this section we will learn about the differences between an item gallery and a command gallery. There are three differences between the two types of galleries:

The first difference relates to what the gallery elements are.
In the item gallery, every element is a "simple" element and is characterized by a text and an image.
On the other hand, an element in a command gallery is literally a command. This means it has a command ID, which we can handle (as seen in previous posts), and has all the attached resources that a command can have.
You may think of it as a list of images vs. a list of buttons.

The second difference is that an item gallery supports the concept of a "selected item".
Every element in an item gallery has an index and there is a property on the gallery which we can check for getting the selected item index.
On the other hand, the commands in the command gallery are not indexed and thus the gallery doesn't support the concept of a selected item.

Finally, item galleries support "live preview". This means you get a notification when the user is hovering over an item (before actual selection); the notification is received via the IUICommandHandler::Execute method, more on this later. This allows application developers to implement a preview feature where the user can see the result of selecting an item before he actually selects it.
The Styles control in Microsoft Word 2007 / 2010 is a great example for an item gallery with live preview. Hovering over different styles shows immediately what the effect will be.

image

Figure 2: Styles item gallery in Word 2010

Command galleries doesn't support preview. Every element in a command gallery can only be clicked.

Gallery Controls

ComboBox

A ribbon ComboBox control is basically the normal ComboBox control that we all know and love, but with the added feature of dividing the items into categories. A category is not an item and cannot be selected from the ComboBox. It is only used to organize the items.
Categories will be discussed further in this post.

image

Figure 3: A ComboBox with categories

A ribbon ComboBox is considered a gallery, although it has one limitation that the other gallery types don't have: It can only be used as an item gallery. This means that the ComboBox items are always "text / image" items and cannot be, for example, buttons.

Defining ComboBox in markup

Following is an example of defining a ComboBox in ribbon markup:

<Application xmlns="http://schemas.microsoft.com/windows/2009/Ribbon">
    <Application.Commands>
        ...
        <Command Name="cmdLayoutGroup"
                 LabelTitle="Border" />
        <Command Name="cmdLayouts"
                 Symbol="IDR_CMD_LAYOUTS"
                 LabelTitle="Grid Size" />
        ...
    </Application.Commands>

    <Application.Views>
        <Ribbon>
            <Ribbon.Tabs>
                <Tab CommandName="cmdTabHome">
                    ...
                    <Group CommandName="cmdLayoutGroup">
                        <ComboBox CommandName="cmdLayouts"
                                  IsEditable="false"
                                  IsAutoCompleteEnabled="false"
                                  ResizeType="VerticalResize" />
                    </Group>
                </Tab>
            </Ribbon.Tabs>
        </Ribbon>
    </Application.Views>
</Application>

As you can see, all it takes is a simple ComboBox markup element, attached to a command.

The ComboBox XML attributes are as follows:

  • CommandName – The name of the command attached to this ComboBox.
  • IsAutoCompleteEnabled – A flag that indicated whether the ComboBox control should automatically complete the word as you write.
  • IsEditable – A flag that indicates whether to allow free text in the ComboBox.
  • ResizeType – Indicates the allowed type of resizing for the ComboBox. Can be either NoResize or VerticalResize.
    Setting ComboBox items

    As you may recall from previous posts, every command has an implementation of IUICommandHandler attached to it.
    Setting the ComboBox items is done by implementing the IUICommandHandler::UpdateProperty function, specifically, handling the case when the property key is UI_PKEY_ItemsSource. You can find more information on how to implement IUICommandHandler::UpdateProperty in part 3 of this series.

    The type of the property ItemsSource is a collection (IUICollection) of IUISimplePropertySet.
    The interface IUICollection represents a simple collection and has all the common collection functions, such as: Add, Insert, RemoveAt, GetCount, etc.
    The interface IUISimplePropertySet represents, as his name suggests, a set of properties. It has only a single function, GetValue, which should return a property value, given the property identifier.
    Both IUICollection and IUISimplePropertySet are defined in the UIRibbon.h, which comes with the Windows 7 SDK.

    Every element in the ComboBox or more generally, in an item gallery, has the following properties:

    • UI_PKEY_Label – Represents the label of the item.
    • UI_PKEY_ItemImage – Represents the item image.
    • UI_PKEY_CategoryId – Represents the category id of which this item belongs.

    Note that an element in a command gallery has different properties. We will review those properties later in this post.

    Following is an example of how to fill the ItemsSource property inside the command handler of a ComboBox. Error handling has been omitted for brevity.

    STDMETHODIMP CLayoutHandler::UpdateProperty(UINT nCmdID,
                                                REFPROPERTYKEY key,
                                                const PROPVARIANT* ppropvarCurrentValue,
                                                PROPVARIANT* ppropvarNewValue)
    {
        HRESULT hr = S_FALSE;

        if (key == UI_PKEY_ItemsSource)
        {
            IUICollection* pCollection;
            hr = ppropvarCurrentValue->punkVal->QueryInterface(
                                                          IID_PPV_ARGS(&pCollection));
            
            int labelIds[] = {IDS_LAYOUT_1, IDS_LAYOUT_2, IDS_LAYOUT_3};

            // Populate the combobox with the three layout options.
            for (int i=0; i<_countof(labelIds); i++)
            {
                // Create a new property set for each item.
                CPropertySet* pItem;
                hr = CPropertySet::CreateInstance(&pItem);
                  
                // Load the label from the resource file.
                WCHAR wszLabel[MAX_RESOURCE_LENGTH];
                LoadString(GetModuleHandle(NULL), labelIds[i], wszLabel,
                                                                 MAX_RESOURCE_LENGTH);

                // Initialize the property set with no image, the label that was just
                // loaded, and no category.
                pItem->InitializeItemProperties(
                                          NULL, wszLabel, UI_COLLECTION_INVALIDINDEX);

                pCollection->Add(pItem);
            }
            pCollection->Release();
            hr = S_OK;
        }
        
        return hr;
    }

    In this example we add three items to the ItemsSource property of the ComboBox. This is done by creating an object that implements IUISimplePropertySet, setting its properties (we set only the label, which is loaded from the resource file), and adding it to the collection.

    The CPropertySet class is a helper class that implements IUISimplePropertySet and exposes convenient initialization functions. Its full source is available with the sample application attached to this post.

    The end result for this ComboBox looks like this:

    image

    Figure 4: The ComboBox created by the previous markup and code

    Handling User Selection

    In this section we will see how to respond to a selection made by the interactive user.
    We will also handle the case where we have an editable ComboBox (IsEditable = "true"), in which case the user might enter a value which is not part of the ComboBox values.

    Handling the "Selected Change" event is done by implementing IUICommandHandler::Execute, when the verb parameter has the value UI_EXECUTIONVERB_EXECUTE and the key parameter has the value UI_PKEY_SelectedItem.

    In the following example we see code that handles the user selection.

    STDMETHODIMP CBorderSizeHandler::Execute(UINT nCmdID,
                       UI_EXECUTIONVERB verb,
                       const PROPERTYKEY* key,
                       const PROPVARIANT* ppropvarValue,
                       IUISimplePropertySet* pCommandExecutionProperties)
    {
        HRESULT hr = E_FAIL;
        if (verb == UI_EXECUTIONVERB_EXECUTE)
        {
            if (key && *key == UI_PKEY_SelectedItem)
            {
                ULONG newSize;
                UINT selected = ppropvarValue->uintVal;
                switch (selected)
                {
                case 0:
                    newSize = 1;
                    break;
                case 1:
                    newSize = 3;
                    break;
                case 2:
                    newSize = 5;
                    break;
                // The new selection is a value that the user typed.
                case UI_COLLECTION_INVALIDINDEX:

                    if (pCommandExecutionProperties != NULL)
                    {
                        PROPVARIANT var;
                        // The text entered by the user is contained in the property set
                        // with the pkey UI_PKEY_Label.
                        pCommandExecutionProperties->GetValue(UI_PKEY_Label, &var);
                        
                        // Convert string to int
                        BSTR bstr = var.bstrVal;
                        hr = VarUI4FromStr(bstr,GetUserDefaultLCID(),0,&newSize);
                        
                        // Validate new size
                        if (FAILED(hr) || newSize < 1 || newSize > 15)
                        {
                            // report invalid size
                            ...
                        }
                        PropVariantClear(&var);
                    }
                    break;
                }
                // Do something with newSize
                ...
            }
        }
        return hr;
    }

    First we check that the correct verb (Execute) and property key (SelectedItem) is handled. Then we use ppropvarValue->uintVal to extract the index of the selected item. According to the index we can know what the selected value is. In case the index is UI_COLLECTION_INVALIDINDEX, which is just a fancy way of saying -1, we can safely assume that the user entered the text manually, in which case we get the label property and parse it.

    image

    Figure 5: An editable ComboBox with custom user text

    DropDownGallery and SplitButtonGallery

    A DropDownGallery is just a button that a click on it displays a list of items. The button itself has no action.

    On the other hand, a SplitButtonGallery has two buttons, one that is used as a default action and another one that opens a list of items.

    This difference between these two galleries is similar to the difference between the SplitButton control and DropDownButton control, seen on part 3 (Add link to post 3) of this post series.

    In the following image, on the right, you can see a SplitButtonGallery which is composed of a split button, on the top part (the image) there is a button and on the lower part (the "Style" text) there is an arrow that opens the list of items.

    image

    Figure 6: On the left: a DropDownGallery with categories, On the right: a SplitButtonGallery

    Defining SplitButtonGallery in markup

    In the following markup code we see how to define a SplitButtonGallery. The code should be placed in the ribbon markup "views" section.

    <SplitButtonGallery CommandName="cmdBorderStyles"
                        Type="Items"
                        TextPosition="Hide"
                        HasLargeItems="false">
        <SplitButtonGallery.MenuLayout>
            <VerticalMenuLayout />
        </SplitButtonGallery.MenuLayout>
    </SplitButtonGallery>

    The SplitButtonGallery XML attributes are as follows:

    • CommandName – The name of the command attached to this SplitButtonGallery.
    • Type – The type of the gallery. It can be either Items or Commands.
    • TextPosition – The position where to show the attached text. This can be one the following values: Top, Left, Right, Bottom, Overlap and Hide.
    • HasLargeItems – Indicates whether the large or small image resource of the Command is displayed.

    The MenuLayout attribute defines how the list of elements will present itself.
    VerticalMenuLayout is used to show a vertical layout.
    Another option is FlowMenuLayout, which we will review on the next code example.

    Setting SplitButtonGallery items with images

    Since in this example the SplitButtonGallery is used as an item gallery, adding items is done similarly to how it was done in the previous ComboBox sample. However, we will also see how we can provide image resources to the items. As always, error handling has been omitted.

    STDMETHODIMP CBorderStyleHandler::UpdateProperty(UINT nCmdID,
                                                REFPROPERTYKEY key,
                                                const PROPVARIANT* ppropvarCurrentValue,
                                                PROPVARIANT* ppropvarNewValue)
    {
        HRESULT hr = S_FALSE;

        if (key == UI_PKEY_ItemsSource)
        {
            IUICollection* pCollection;
            hr = ppropvarCurrentValue->punkVal->QueryInterface(
                                                              IID_PPV_ARGS(&pCollection));

            int imageIds[] = {IDB_NONE, IDB_SOLID, IDB_DASH};
            int labelIds[] = {IDS_BORDER_NONE, IDS_BORDER_SOLID, IDS_BORDER_DASH};

            // Populate the dropdown with the three border styles.
            for (int i=0; i<_countof(labelIds); i++)
            {
                // Create a new property set for each item.
                CPropertySet* pItem;
                hr = CPropertySet::CreateInstance(&pItem);

                // Create an IUIImage from a resource id.
                IUIImage* pImg;
                CreateUIImageFromBitmapResource(MAKEINTRESOURCE(imageIds[i]), &pImg);

                // Load the label from the resource file.
                WCHAR wszLabel[MAX_RESOURCE_LENGTH];
                LoadString(GetModuleHandle(NULL), labelIds[i], wszLabel,
                                                                     MAX_RESOURCE_LENGTH);

                // Initialize the property set with the image and label that were just
                // loaded and no category.
                pItem->InitializeItemProperties(pImg, wszLabel,
                                                              UI_COLLECTION_INVALIDINDEX);

                // Add the newly-created property set to the collection
                // supplied by the framework.
                pCollection->Add(pItem);

                pItem->Release();
                pImg->Release();
            }
            pCollection->Release();
            hr = S_OK;
        }
        
        return hr;
    }
    // Factory method to create IUIImages from resource identifiers.
    void CBorderStyleHandler::CreateUIImageFromBitmapResource(LPCTSTR pszResource,
                                                                 IUIImage **ppimg)
    {
        IUIImageFromBitmap* m_pifbFactory;
        
        CoCreateInstance(CLSID_UIRibbonImageFromBitmapFactory,
                         NULL, CLSCTX_ALL, IID_PPV_ARGS(&m_pifbFactory));
        
        // Load the bitmap from the resource file.
        HBITMAP hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), pszResource,
                                          IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
        
        // Use the factory implemented by the framework to produce an IUIImage.
        m_pifbFactory->CreateImage(hbm, UI_OWNERSHIP_TRANSFER, ppimg);
    }

    The important thing to note is the helper function CreateUIImageFromBitmapResource. This function loads a bitmap resource and converts it to an instance of IUIImage, which is the ribbon wrapper for a bitmap. The conversion is done using a COM object provided by the Windows Ribbon Framework, named UIRibbonImageFromBitmapFactory. This object implements the interface IUIImageFromBitmap which has only one function, CreateImage.

    The CreateImage function takes an HBITMAP handle as its first parameter and returns a pointer to IUIImage. The second parameter controls the ownership of the created image, and take the value UI_OWNERSHIP_TRANSFER in case you want to transfer the responsibility of releasing the handle to the ribbon framework, or UI_OWNERSHIP_COPY in case you plan to reuse the same HBITMAP from other places in your application, and so need to release it only when you are done.

    Defining DropDownGallery in markup

    In the following markup code we see how to define a DropDownGallery. The code should be placed in the ribbon markup "views" section.

    <DropDownGallery CommandName="cmdSizeAndColor"
                     TextPosition="Hide"
                     Type="Commands">
        <DropDownGallery.MenuLayout>
            <FlowMenuLayout Rows="2"
                            Columns="3"
                            Gripper="None" />
        </DropDownGallery.MenuLayout>
    </DropDownGallery>

    Note that this time we used "Commands" as the type of the gallery. This means that this particular instance of DropDownGallery will be used as a command gallery.
    Most of the DropDownGallery XML attributes are similar to the attributes of SplitButtonGallery, so I'll only explain the FlowMenuLayout.

    The FlowMenuLayout XML element is used to define a rich layout for the gallery items. We use the Rows and Columns attributes to control the number of rows and columns in the gallery rectangle. On figure 6, the left control is the result of this definition. Note that the categories seen in the image will be defined later in the code.

    Before we continue, I owe you from a previous section the available properties for an element in a command gallery.
    Every element in a command gallery has the following properties:

    • UI_PKEY_CommandId – Represents the command id of the element.
    • UI_PKEY_CommandType – Represents the type the command.
    • UI_PKEY_CategoryId – Represents the category id of which this item belongs.
    Setting DropDownGallery commands items with categories

    In the following code we see how to fill the previously defined DropDownGallery. This time we fill it with commands elements. In addition we will divide the commands into two categories.

    STDMETHODIMP CSizeAndColorHandler::UpdateProperty(UINT nCmdID,
                                  REFPROPERTYKEY key,
                                  const PROPVARIANT* ppropvarCurrentValue,
                                  PROPVARIANT* ppropvarNewValue)
    {
        HRESULT hr = E_FAIL;

        if (key == UI_PKEY_Categories)
        {
            IUICollection* pCollection;
            hr = ppropvarCurrentValue->punkVal->QueryInterface(
                                                              IID_PPV_ARGS(&pCollection));

            // Create a property set for the Size category.
            CPropertySet *pSize;
            hr = CPropertySet::CreateInstance(&pSize);

            // Load the label for the Size category from the resource file.
            WCHAR wszSizeLabel[MAX_RESOURCE_LENGTH];
            LoadString(GetModuleHandle(NULL), IDS_SIZE_CATEGORY,
                                                       wszSizeLabel, MAX_RESOURCE_LENGTH);

            // Initialize the property set with the label that was just loaded and
            // a category id of 0.
            pSize->InitializeCategoryProperties(wszSizeLabel, 0);

            // Add the newly-created property set to the collection supplied
            // by the framework.
            pCollection->Add(pSize);

            pSize->Release();


            // Create a property set for the Color category.
            CPropertySet *pColor;
            hr = CPropertySet::CreateInstance(&pColor);

            // Load the label for the Color category from the resource file.
            WCHAR wszColorLabel[MAX_RESOURCE_LENGTH];
            LoadString(GetModuleHandle(NULL), IDS_COLOR_CATEGORY,
                                                      wszColorLabel, MAX_RESOURCE_LENGTH);

            // Initialize the property set with the label that was just loaded and
            // a category id of 1.
            pColor->InitializeCategoryProperties(wszColorLabel, 1);
            
            // Add the newly-created property set to the collection supplied
            // by the framework.
            pCollection->Add(pColor);

            pColor->Release();
            pCollection->Release();

            hr = S_OK;
        }
        else if (key == UI_PKEY_ItemsSource)
        {
            IUICollection* pCollection;
            hr = ppropvarCurrentValue->punkVal->QueryInterface(
                                                              IID_PPV_ARGS(&pCollection));

            int commandIds[] = {IDR_CMD_SMALL, IDR_CMD_MEDIUM, IDR_CMD_LARGE,
                                IDR_CMD_RED, IDR_CMD_GREEN, IDR_CMD_BLUE};
            int categoryIds[] = {0, 0, 0, 1, 1, 1};

            // Populate the gallery with the three size and three colors in
            // two separate categories.
            for (int i=0; i<_countof(commandIds); i++)
            {
                // Create a new property set for each item.
                CPropertySet* pCommand;
                hr = CPropertySet::CreateInstance(&pCommand);

                // Initialize the property set with the appropriate command id and
                // category id and type Boolean (which makes these appear as
                // ToggleButtons).
                pCommand->InitializeCommandProperties(categoryIds[i], commandIds[i],
                                                                  UI_COMMANDTYPE_BOOLEAN);

                // Add the newly-created property set to the collection supplied
                // by the framework.
                pCollection->Add(pCommand);

                pCommand->Release();
            }
            pCollection->Release();
            hr = S_OK;
        }
        return hr;
    }

    In this code we first define Categories property, which contains the list of available categories (in our case, just two items), and then the ItemsSource property.

    The items elements are now commands which have a command id and command type. In our case we used UI_COMMANDTYPE_BOOLEAN which makes the commands appear as ToggleButton controls. Note that we didn't define any image resource for the elements. The image comes from the previously define command resources.

    Also, check the implementation of the gallery's Execute function:

    STDMETHODIMP CSizeAndColorHandler::Execute(UINT nCmdID,
                       UI_EXECUTIONVERB verb,
                       const PROPERTYKEY* key,
                       const PROPVARIANT* ppropvarValue,
                       IUISimplePropertySet* pCommandExecutionProperties)
    {
        return E_FAIL;
    }

    The implementation is rather empty since the handling of the commands is done by the command handler attached to the elements command id. The gallery's Execute function is never actually called.

    InRibbonGallery

    An InRibbonGallery is a gallery in which the items are displayed inside the ribbon. Other than its visual representation, it's functionally equivalent to the DropDownGallery.

     

    image

    Figure 7: An example of InRibbonGallery control

    Defining InRibbonGallery in markup

    In the following markup code we see how to define an InRibbonGallery. As always, view related code should be placed in the ribbon markup "views" section.

     

    <InRibbonGallery CommandName="cmdShapes"
                     Type="Items"
                     TextPosition="Bottom"
                     MaxColumns="3"
                     MaxRows="1" />

    All of these XML attributes are already known or self-explanatory.

    Handling live preview in an item gallery

    One of the benefits of an item gallery is its support for the live preview feature, i.e. it allows the user to see the result of a selection before just by hovering over an item. If the user doesn't select an item and move the mouse cursor away, the selection effect is removed.

    In the following code we see how to implement IUICommandHandler::Execute in order to handle the live preview feature:

    STDMETHODIMP CShapeHandler::Execute(UINT nCmdID,
                       UI_EXECUTIONVERB verb,
                       const PROPERTYKEY* key,
                       const PROPVARIANT* ppropvarValue,
                       IUISimplePropertySet* pCommandExecutionProperties)
    {
        HRESULT hr = E_FAIL;

        UINT selected;
        hr = UIPropertyToUInt32(*key, *ppropvarValue, &selected);
        switch (verb)
        {
        case UI_EXECUTIONVERB_PREVIEW:
            // Show a preview of a new shape.    
            ShowItem(selected);
            hr = S_OK;
            break;

        case UI_EXECUTIONVERB_CANCELPREVIEW:
            // Show the shape that was selected before the preview -
            // ppropvarValue contains the previous selected item.
            // Note that the developer did not have to store the value from before
            // preview was called.
            ShowItem(selected);
            hr = S_OK;
            break;

        case UI_EXECUTIONVERB_EXECUTE:
            if ( key && *key == UI_PKEY_SelectedItem)
            {      
                // Update the renderer with the newly-selected shape.
                ShowItem(selected);
                hr = S_OK;
            }
        }
        return hr;
    }

    We handle three different verbs: Preview, CancelPreview and Execute.
    The Preview verb is passed when the user hovers over an item, in which case we also get the hovered item index. The CancelPreview verb is passed when a user moves the mouse cursor away from the item gallery. Note that in the CancelPreview case we get the previously selected item so the developer doesn't need to save the previous item.
    The last case is when the passed verb is Execute, which means the user has selected an item.

    The ShowItem function is in charge of doing the selection effect, for example, drawing a new shape according to the selected one.

    Summary

    The sample application attached to this post is the taken from the Windows 7 SDK "Gallery" ribbon sample. You can find it either here or in your local folder
    "\Program Files\Microsoft SDKs\Windows\v7.0\Samples\winui\WindowsRibbon\Gallery\"

     

    image

    Figure 8: Sample application for this post

    In this post we have learned how to use the ribbon gallery controls. We learned about the difference between an item gallery and a command gallery. We saw the different gallery controls: ComboBox, SplitButtonGallery, DropDownGallery and InRibbonGallery. And we saw how to add items, categories and images, and how to provide support for live preview.

    That's it for now,
    Arik Poznanski.

    Posted: Jun 16 2011, 11:36 PM by arik | with 7 comment(s) |
    תגים:, , , ,

    Ribbon with C++, Part 4: Layout Controls in Windows Ribbon Framework

    This is the 4th post about Windows Ribbon Framework features.
    On previous posts we have introduced the Windows Ribbon Framework, shown a complete example of how to develop a ribbon enabled application and reviewed the different buttons-based UI controls that the ribbon framework provides.

    In this post we continue our review of the various features in the Windows Ribbon Framework. This time we will focus on a task that every ribbon application developer should address: How to layout UI controls on the ribbon.

    We will see how to define tabs and groups, what the tab scaling policy is, and how to control it. After that we will see how to layout controls in groups using predefined layouts and how to define new custom layouts.

    On the second half of this post we will see what the ribbon application menu is, and how to add ribbon controls to it.

    Arranging Controls in Tabs and Groups

    The ribbon is divided into tabs. A Tab encapsulates commands which belong to the same logical category. For example, the "Insert" tab in Microsoft Word contains all the different objects one might insert into a word document, such as picture, shape, table, etc.

    clip_image002

    Figure 1: Tabs and groups in Microsoft Word 2010

    A Group, also called Chunk in some Ribbon APIs, is like a sub category inside a tab.

    Defining Tabs and Groups in Ribbon Markup

    Defining tabs and groups is done using the Tab and Group XML elements.
    In the following code snippet we define a ribbon with two tabs, and three groups:

    <Application.Views>
        <Ribbon>
            <Ribbon.Tabs>

                <Tab CommandName="cmdTabMain">
                    <Group CommandName="cmdGroupFileActions"
                           SizeDefinition="ThreeButtons">
                        <Button CommandName="cmdButtonNew" />
                        <Button CommandName="cmdButtonOpen" />
                        <Button CommandName="cmdButtonSave" />
                    </Group>
                    <Group CommandName="cmdGroupExit"
                           SizeDefinition="OneButton">
                        <Button CommandName="cmdButtonExit" />
                    </Group>
                </Tab>

                <Tab CommandName="cmdTabMore">
                    <Group CommandName="cmdGroupMore"
                           SizeDefinition="ThreeButtons">
                        <Button CommandName="cmdButtonMoreA" />
                        <Button CommandName="cmdButtonMoreB" />
                        <Button CommandName="cmdButtonMoreC" />
                    </Group>
                </Tab>

            </Ribbon.Tabs>
        </Ribbon>
    </Application.Views>

    The SizeDefinition attribute of the Group XML element defines what will be the actual layout of the controls inside the group. We will learn more on this attribute later in this post.

    Tab Scaling Policy

    In order to understand this part you should know that one of the features of the Windows Ribbon Framework is the ability to re-layout your ribbon controls according to the amount of screen space the ribbon has. It pretty much handles this automatically but it does require you to define hints on how you want your layout to scale when the application form gets smaller and smaller.

    To better understand the meaning of scaling policy, let's consider the "View" tab in Microsoft Paint when the window is resized.

    Following is an image of Microsoft Paint, where the "View" tab is in its fullest form:

    clip_image001

    Figure 2: View tab in full form

    On the next image, the window size has been reduced, which caused the "Zoom" group to scale to a smaller layout:

    clip_image001[5]

    Figure 3: Zoom group scaled to a smaller layout

    On the next image, the window size has been reduced again, resulting in a scale down of the "Display" group:

    clip_image002

    Figure 4: Display group scaled to a smaller layout

    On the next image, the window size has been reduced yet again, resulting in another scale down of the "Zoom" group, this time into a pop-up layout:

    clip_image003

    Figure 5: Zoom group scaled to popup layout

    On the next image, we see what happens when the window size gets too small. The ribbon will disappear completely:

    clip_image004

    Figure 6: Ribbon disappear when the window size is too small

    So, to summarize the example: each group has a starting size, which from now on will be called "ideal size". As the window size gets smaller the groups start to scale down to smaller sizes, but not necessarily in the "normal" order of the groups.

    First, the Zoom group scaled to Small size.
    Then, the Display group scaled to Small size.
    Finally, the Zoom group scaled to Popup size.

    In general, one can define for each group in the ribbon the ideal size for it, which is the default size if the group has an infinite amount of space. The size can be one of four values: Large, Medium, Small and Popup.
    The actual layout of the controls in the group with different value sizes is dependent on the layout template, which we shall review later on.
    The Popup value means that the group has shrunk to a single icon that popups the original group (in ideal size) upon clicking.

    After defining the ideal size for the group we can define the order of scaling down, meaning which group should scale down first and to what size. In this way you can have your most important controls in your application visible longer that the less important ones.

    Following is an example of how to define the tab scaling policy for a specific tab:

    <Application.Views>
        <Ribbon>
            <Ribbon.Tabs>

                <Tab CommandName="cmdTabMain">

                    <Tab.ScalingPolicy>
                        <ScalingPolicy>
                            <ScalingPolicy.IdealSizes>
                                <Scale Group="cmdGroupFileActions"
                                       Size="Large" />
                                <Scale Group="cmdGroupExit"
                                       Size="Large" />
                            </ScalingPolicy.IdealSizes>
                            <Scale Group="cmdGroupFileActions"
                                   Size="Medium" />
                        </ScalingPolicy>
                    </Tab.ScalingPolicy>

                    <Group CommandName="cmdGroupFileActions"
                           SizeDefinition="ThreeButtons">
                        <Button CommandName="cmdButtonNew" />
                        <Button CommandName="cmdButtonOpen" />
                        <Button CommandName="cmdButtonSave" />
                    </Group>
                    <Group CommandName="cmdGroupExit"
                           SizeDefinition="OneButton">
                        <Button CommandName="cmdButtonExit" />
                    </Group>
                </Tab>

                <Tab CommandName="cmdTabMore">
                    <Group CommandName="cmdGroupMore"
                           SizeDefinition="ThreeButtons">
                        <Button CommandName="cmdButtonMoreA" />
                        <Button CommandName="cmdButtonMoreB" />
                        <Button CommandName="cmdButtonMoreC" />
                    </Group>
                </Tab>
            </Ribbon.Tabs>
        </Ribbon>
    </Application.Views>

    In this example we define that the ideal size for both the "File Actions" group and "Exit" group is Large. This is done using the ScalingPolicy.IdealSizes XML element.
    Then we define the order of scaling when the window size gets smaller. In our example we only define that the next scaling operation should scale the "File Actions" group down to Medium size.

    Setting Group Layout

    Now we will see how to actually define the layout of the controls inside a ribbon group.

    If you remember from the previous examples, we often set a SizeDefinition attribute on the group element. The SizeDefinition is the ribbon markup attribute which allows us, developers, to control the layout of controls in a group.

    The value of the SizeDefinition attribute is a name of a layout template.
    Every layout template defines:

    • A list of controls participating in the layout template.
    • A definition of how to arrange these controls for a given group size.
      Remember that every group can scale to the following sizes: Large, Medium, Small and Popup.

    There are two types of layout templates: Predefined layout templates and Custom layout templates.

    Predefined Layout Templates

    Microsoft has provided with the Windows Ribbon Framework a list of predefined common layout template so we can use them in our groups without having to specify the exact layout. Up until now, ALL the previous examples used them.

    Reminder:

    <Group CommandName="cmdGroupFileActions"
           SizeDefinition="ThreeButtons">
        <Button CommandName="cmdButtonNew" />
        <Button CommandName="cmdButtonOpen" />
        <Button CommandName="cmdButtonSave" />
    </Group>

    The “ThreeButtons” is a name of a predefined layout template that handles the layout for three buttons. This layout template defines two possible sizes: Large and Medium.
    Note that Popup is always available since it doesn't have a special layout definition (It's always a single icon).

    clip_image001[7]

    Figure 7: Medium size and Large size defined in ThreeButtons predefined layout template

    Following is the list of all available predefined layout templates:

    • OneButton
    • TwoButtons
    • ThreeButtons
    • ThreeButtons-OneBigAndTwoSmall
    • ThreeButtonsAndOneCheckBox
    • FourButtons
    • FiveButtons
    • FiveOrSixButtons
    • SixButtons
    • SixButtons-TwoColumns
    • SevenButtons
    • EightButtons
    • EightButtons-LastThreeSmall
    • NineButtons
    • TenButtons
    • ElevenButtons
    • OneFontControl
    • OneInRibbonGallery
    • InRibbonGalleryAndBigButton
    • InRibbonGalleryAndButtons-GalleryScalesFirst
    • ButtonGroups
    • ButtonGroupsAndInputs
    • BigButtonsAndSmallButtonsOrInputs

    Their exact layout can be found at Customizing a Ribbon Through Size Definitions and Scaling Policies on MSDN.

    Defining Custom Layout Templates

    Custom layout templates can be defined in two ways: Inline and Standalone.

    Standalone definition
    Standalone means you define the layout once, under the Ribbon.SizeDefinitions markup element and then use its name in your group definition, exactly like the predefined layout templates.

    For example, we want to define a layout that is consistent with the Microsoft WordPad "Paragraph" group:

    clip_image002[7]

    Figure 8: Microsoft WordPad

    Defining such a layout template in a standalone definition is done like this:

    <Ribbon.SizeDefinitions>
        <SizeDefinition Name="ParagraphLayout">
            <ControlNameMap>
                <ControlNameDefinition Name="button1" />
                <ControlNameDefinition Name="button2" />
                <ControlNameDefinition Name="button3" />
                <ControlNameDefinition Name="button4" />
                <ControlNameDefinition Name="button5" />
                <ControlNameDefinition Name="button6" />
                <ControlNameDefinition Name="button7" />
                <ControlNameDefinition Name="button8" />
                <ControlNameDefinition Name="button9" />
            </ControlNameMap>
            <GroupSizeDefinition Size="Large">
                <Row>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button1"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button2"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button3"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button4"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                </Row>
                <Row>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button5"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button6"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button7"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button8"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button9"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                </Row>
            </GroupSizeDefinition>
        </SizeDefinition>
    </Ribbon.SizeDefinitions>

    Although this looks intimidating, this is actually pretty simple. First, the ControlNameMap markup element is a definition of placeholders controls used in the layout. In our example we define 9 controls.
    The mapping between controls in the actual group and controls in the template layout is done according to the order of the controls, define in the ControlNameMap element.

    Then we define the actual layout definition for each group size. This is done in a GroupSizeDefinition markup element, where we set the Size attribute to indicate what group scale size we are defining. Remember that different groups' sizes will have different layouts. In our example we define a layout only for the large size.

    Then we use the Row markup elements to specify that our layout comes in two lines (three lines is the maximum).

    In every row we use ControlGroup elements to specify grouping of controls. Controls which are in the same group have no spacing between them.

    Using the standalone custom layout is very simple:

    <Group CommandName="cmdGroupParagraph"
           SizeDefinition="ParagraphLayout">
        <Button CommandName="cmdDecreaseIndent" />
        <Button CommandName="cmdIncreaseIndent" />
        <SplitButton>
            <Button CommandName="cmdStartList" />
        </SplitButton>
        <DropDownButton CommandName="cmdLineSpacing">
            <Button />
        </DropDownButton>
        <Button CommandName="cmdAlignLeft" />
        <Button CommandName="cmdAlignCenter" />
        <Button CommandName="cmdAlignRight" />
        <Button CommandName="cmdJustify" />
        <Button CommandName="cmdParagraph" />
    </Group>

     

    clip_image001[9]

    Figure 9: ParagraphLayout custom layout template

    Inline definition
    Inline means you write the custom layout definition inside your actual group definition, instead of in a general place where it can serve other groups.

    Here is the same example as before, only now we use an inline version of the custom layout template:

    <Group CommandName="cmdGroupParagraph">
        <SizeDefinition>
            <ControlNameMap>
                <ControlNameDefinition Name="button1" />
                <ControlNameDefinition Name="button2" />
                <ControlNameDefinition Name="button3" />
                <ControlNameDefinition Name="button4" />
                <ControlNameDefinition Name="button5" />
                <ControlNameDefinition Name="button6" />
                <ControlNameDefinition Name="button7" />
                <ControlNameDefinition Name="button8" />
                <ControlNameDefinition Name="button9" />
            </ControlNameMap>
            <GroupSizeDefinition Size="Large">
                <Row>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button1"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button2"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button3"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button4"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                </Row>
                <Row>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button5"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button6"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button7"
                                               IsLabelVisible="false" />
                        <ControlSizeDefinition ControlName="button8"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                    <ControlGroup>
                        <ControlSizeDefinition ControlName="button9"
                                               IsLabelVisible="false" />
                    </ControlGroup>
                </Row>
            </GroupSizeDefinition>
        </SizeDefinition>
        <Button CommandName="cmdDecreaseIndent" />
        <Button CommandName="cmdIncreaseIndent" />
        <SplitButton>
            <Button CommandName="cmdStartList" />
        </SplitButton>
        <DropDownButton CommandName="cmdLineSpacing">
            <Button />
        </DropDownButton>
        <Button CommandName="cmdAlignLeft" />
        <Button CommandName="cmdAlignCenter" />
        <Button CommandName="cmdAlignRight" />
        <Button CommandName="cmdJustify" />
        <Button CommandName="cmdParagraph" />
    </Group>

    Arranging Controls in the Application Menu

    Every ribbon application has an application menu. It is used as the main menu for the application and can be access via a button located on the left of the tabs.

    clip_image001[11]

    Figure 10: Application menu button in Microsoft Paint

    The application menu button opens up a drop down menu that can contain various button like ribbon controls. Note that not all of the ribbon controls can be used in the application menu.

    Defining Application Menu in Ribbon Markup

    Defining an application menu in the ribbon markup is extremely simple:

    <Application.Views>
        <Ribbon>
            <Ribbon.ApplicationMenu>
                <ApplicationMenu>
                    <MenuGroup Class="MajorItems">
                        <Button CommandName='cmdButtonNew' />
                        <Button CommandName='cmdButtonOpen' />
                        <Button CommandName='cmdButtonSave' />
                    </MenuGroup>
                    <MenuGroup Class="MajorItems">
                        <Button CommandName='cmdButtonExit' />
                    </MenuGroup>
                </ApplicationMenu>
            </Ribbon.ApplicationMenu>
        </Ribbon>
    </Application.Views>

    In this example we define an application menu that contains two menu groups and four buttons.

    We use the MenuGroup markup element to group the buttons into logical groups. This creates a separator between the groups, as shown in the following image:

    clip_image001[13]

    Figure 11: Application menu with menu groups

    The MenuGroup markup element has a single attribute, named Class, which can have the value StandardItems or MajorItems. This attribute controls the size of the elements in the menu group.

    For example, using the following ribbon markup:

    <Application.Views>
        <Ribbon>
            <Ribbon.ApplicationMenu>
                <ApplicationMenu>
                    <MenuGroup Class="StandardItems">
                        <Button CommandName='cmdButtonNew' />
                        <Button CommandName='cmdButtonOpen' />
                        <Button CommandName='cmdButtonSave' />
                    </MenuGroup>
                    <MenuGroup Class="StandardItems">
                        <Button CommandName='cmdButtonExit' />
                    </MenuGroup>
                </ApplicationMenu>
            </Ribbon.ApplicationMenu>
        </Ribbon>
    </Application.Views>

    We get the result:

    clip_image001[15]

    Figure 12: Application menu with menu group of class StandardItems

    Another nice UI tweak we can do using a MenuGroup element is set a title for the group. This is done by attaching a command to the MenuGroup element; the title will be defined according to the LabelTitle attribute of the command.

    The end result looks like this:

    clip_image002[4]

    Figure 13: Application menu with menu group titles

    Defining Sub-Menus in Ribbon Markup

    Defining sub-menus is done by using two buttons we already know from the previous post, namely, DropDownButton and SplitButton.

    Each of them can contain a list of buttons, and as seen before, the difference between the two is that DropDownButton is not a button itself but only a container of such, and SplitButton is both a button and a container of buttons.

    Following is an example for creating a sub-menu using a DropDownButton:

    <Application.Views>
        <Ribbon>
            <Ribbon.ApplicationMenu>
                <ApplicationMenu>
                    <MenuGroup Class="MajorItems"
                               CommandName="cmdMenuGroupFile">
                        <Button CommandName='cmdButtonNew' />
                        <Button CommandName='cmdButtonOpen' />
                        <Button CommandName='cmdButtonSave' />
                    </MenuGroup>
                    <MenuGroup>
                        <DropDownButton CommandName='cmdDropDownButton'>
                            <MenuGroup Class='MajorItems'>
                                <Button CommandName='cmdButtonMoreA' />
                                <Button CommandName='cmdButtonMoreB' />
                                <Button CommandName='cmdButtonMoreC' />
                            </MenuGroup>
                        </DropDownButton>
                    </MenuGroup>
                    <MenuGroup Class="MajorItems"
                               CommandName="cmdMenuGroupExit">
                        <Button CommandName='cmdButtonExit' />
                    </MenuGroup>
                </ApplicationMenu>
            </Ribbon.ApplicationMenu>
        </Ribbon>
    </Application.Views>

    The result is shown in the following image:

    clip_image001[17]

    Figure 14: Application menu with sub-menus

    Setting shortcuts to menu items

    Setting a key shortcut for a menu item is done by adding “&amp;" in the LabelTitle attribute before the letter you want to use as a shortcut (similar to shortcuts in the “old” menu system).
    For example see the LabelTitle attribute in the following command definition:

    <Command Name="cmdButtonNew"
             Symbol="ID_CMD_NEW"
             LabelTitle="&amp;New"
             LabelDescription="New Description"
             TooltipTitle="New (Ctrl+N)"
             TooltipDescription="Create a new image.">
        <Command.LargeImages>
            <Image>Res/New32.bmp</Image>
        </Command.LargeImages>
    </Command>

    Pressing the Alt key will now add an underscore under the letter and a small box with the letter in it, as shown in the next image:

    clip_image001[19]

    Figure 15: Application menu with key modifiers

    Note that this way of setting key shortcuts is only valid in the application menu.
    For setting key shortcuts on ribbon controls in the tabs and groups you should set the Keytip attribute of the attached command.

    You can find the full code of the sample application used in this post here.

    clip_image003

    Figure 16: Sample application for this post

    In this post we have learned how to layout UI controls on the ribbon. We've seen how to define groups and tabs, what tab scaling policy is, how to use predefined layouts and how to define custom layouts. Finally, we have seen what the application menu is and how to use it in a ribbon enabled application.

    That's it for now,
    Arik Poznanski.

    Posted: Jun 15 2011, 01:16 AM by arik | with 8 comment(s) |
    תגים:, , , ,

    Ribbon with C++, Part 3: Using Buttons with Windows Ribbon Framework

    On previous posts we have seen an introduction to the Windows Ribbon Framework and learned how to develop a ribbon enabled application.

    In this post we continue our review of the various features in the Windows Ribbon Framework. This time we will focus on the most common feature in the ribbon: Buttons.

    I assume the concept of a button needs no introduction; however, there are several kinds of buttons available with the Windows Ribbon Framework and in this post we will review them.

    But first, let's dive into the details of how we use the ribbon in an application.
    The important parts are to define the ribbon user interface using the ribbon markup and then implement handlers for the UI we used.

    The ribbon markup is composed of two main sections, Commands and Views.

    Commands and Views

    A command is an action that is identified by a number. It can be opening the save-as dialog, printing the current document, closing the application, etc. every thing you can do in a function call.

    A view is a graphical representation of [usually several] commands. It defines the type of controls used to activate the commands, their size, order and layout on the screen.

    So using commands and views is actually just another instance of the well-known MVC design pattern, which allows us to separate business logic from presentation logic.

    The basic template for all ribbon markup files looks like this:

    <?xml version='1.0' encoding='utf-8'?>
    <Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
        <Application.Commands>
            ...
        </Application.Commands>

        <Application.Views>
            <Ribbon>
                ...
            </Ribbon>
        </Application.Views>
    </Application>

    Commands Section

    In the Commands section we define, well, commands. Every command is defined in its own Command XML element.

    Following is a common definition for a command:

    <Command Name="cmdButtonNew"
             Symbol="ID_CMD_NEW"
             Id="1001"
             LabelTitle="New"
             LabelDescription="New Description"
             TooltipTitle="New"
             TooltipDescription="Create a new image.">
        <Command.LargeImages>
            <Image>Res/New32.bmp</Image>
        </Command.LargeImages>
        <Command.SmallImages>
            <Image>Res/New16.bmp</Image>
        </Command.SmallImages>
    </Command>

    In this example we define a command that will encapsulate the "New" button functionality.

    Command Properties

    The Command XML element has several properties, we divide them to categories:

    Properties used for referencing the command:

    The Name attribute is used to reference this command in the markup, for example, in order to attach a button with this command.

    The Symbol attribute represents the name of the constant that will reference this command, later, when we will write the command handler code.

    The Id attribute is just a way to control what the constant value will be.

    Properties used for defining command related resources:

    The LabelTitle attribute is used to define the label title of the command.
    The LabelDescription attribute is used to define the label description of the command.
    The TooltipTitle attribute is used to define the tooltip title of the command.
    The TooltipDescription attribute is used to define the tooltip description of the command.
    The LargeImages attribute is used to define the large image filename for the command, usually 32x32 pixels.
    The SmallImages attribute is used to define the small image filename for the command, usually 16x16 pixels.

    Setting image resources in ribbon markup

    The filename defined in the markup (like in the LargeImages and SmallImages XML element), should be a valid (relative or full) path to a filename, otherwise the Visual C++ Resource Compiler (rc.exe) will output a compilation error: “error RC2135: file not found: <filename>”.

    The image file format should be BMP with 32 BPP ARGB pixel format. Many image editing programs, like Microsoft Paint do not preserve the highest order 8-bit alpha channel when saving, thus creating only 24 bit images, the result is that the image will not appear at all.

    You can use the tool convert2bmp to convert your images to the required format.

    Under both images elements you can put several image files in different sizes, the ribbon framework will choose the best size according to the current DPI setting. For us, normal users, setting two images for 32x32 and 16x16 should be enough. For more information, see "Specifying Ribbon Image Resources" on MSDN.

    Views Section

    The Views section defines the UI controls we want to use, and their layout in the ribbon.
    Following is a definition for a view which has a tab, a group and a single button:

    <Application.Views>
        <Ribbon>
            <Ribbon.Tabs>
                <Tab CommandName="cmdTabMain">
                    <Group CommandName="cmdGroupFileActions">
                        <Button CommandName="cmdButtonNew" />
                    </Group>
                </Tab>
            </Ribbon.Tabs>
        </Ribbon>
    </Application.Views>

    The views syntax is somewhat self-explanatory, we use the Tab element to define a tab, a Group element to define a group and a Button element to define a button.

    The CommandName attribute is used to bind a UI element to a given command (along with its resources. In this example, our button will be bound to the predefined cmdButtonNew command element. This means our button will have the label title, tooltip and images of this command.

     

    clip_image001

    Figure 1: Button with command resources

    Handling "Button Clicked" Event

    As we've seen in the previous post, handling the button click event is done by implementing the IUICommandHandler::Execute function, of the IUICommandHandler instance provided by IUIApplication for the given command id.

    Following is an example where in responds to the click on the "New" button we show a message box to the screen:

    // Called by the Ribbon framework when a command is executed by the user.  
    // For example, when a button is pressed.
    STDMETHODIMP CCommandHandler::Execute(
        UINT nCmdID,
        UI_EXECUTIONVERB verb,
        const PROPERTYKEY* key,
        const PROPVARIANT* ppropvarValue,
        IUISimplePropertySet* pCommandExecutionProperties)
    {
        switch (nCmdID)
        {
        case ID_CMD_NEW:
            MessageBox(GetForegroundWindow(),
                              L"New button was clicked", L"New Clicked", 0);
            break;

        }

        return S_OK;
    }

    Few things we should note here:

    The first parameter, nCmdID, is the id of the command which is bound to the button. In our case, we define this id to be 1001 (using the Id attribute of the command).

    The second parameter, verb, usually has the value UI_EXECUTIONVERB_EXECUTE. Two other values it can have are: UI_EXECUTIONVERB_PREVIEW and UI_EXECUTIONVERB_CANCELPREVIEW, These values are used with ribbon galleries.

    The other parameters are not used in this context.

    Other Button Types

    Up until now we have seen the most common button type, which is available to us by using the <Button> XML element.

    We will see now a few more types of buttons, the main difference between the different types are their GUI representations.
    In fact, all of these buttons are used in the exact same way:

    • Declare them in the ribbon markup
    • Implement IUICommandHandler::Execute

       

      Using HelpButton

      The HelpButton is a button with a specific GUI. It always has the same predefined image and is always positioned in the same place in the ribbon. Also, there can be at most one help-button in the ribbon.

      clip_image002

      Figure 2: Help button

      Note that despite its name, it doesn't have to handle any help-related functionality.
      That being said, it is recommended you provide help information using this button, to maintain a consistent user experience with other windows applications.

      To use a HelpButton in your application you need to use the following ribbon markup:

      <Application.Views>
          <Ribbon>
              <Ribbon.HelpButton>
                  <HelpButton CommandName="cmdHelpButton" />
              </Ribbon.HelpButton>
              <Ribbon.Tabs>
                  ?
              </Ribbon.Tabs>
          </Ribbon>
      </Application.Views>

      In this case, since the HelpButton requires no resources, the command declaration is as simple as:

      <Command Name="cmdHelpButton"
               Symbol="ID_CMD_HELP">
      </Command>

       

      Using SplitButton and DropDownButton

      SplitButton and DropDownButton are both ribbon UI controls which can hold several buttons and which shows these buttons upon clicking on a small arrow button:

      clip_image003

      Figure 3: SplitButton that contains three buttons

      So what is actually the difference between these two?

      Well, the difference between them is that DropDownButton is in fact NOT a button.
      This means that clicking on a DropDownButton only shows the buttons list, but doesn't run any custom code.

      On the other hand, SplitButton is itself a button, which you can respond to. A click on the arrow part will cause it to show the buttons list.

      The common use for a DropDownButton is when you want to expose a set of items which doesn't have an obvious default option. For example, consider the “Rotate” feature in Microsoft Paint. You can rotate by 90, 180 and 270 degrees, but none of these options is an obvious default.

      The common use for a SplitButton is when you want to expose a set of items which have an obvious default option. For example, consider the “Save As” button in an application that supports several file-format but does have an obvious default save format.

      The following example shows how to define both DropDownButton and SplitButton in a ribbon application:

      <Application.Views>
          <Ribbon>
              <Ribbon.Tabs>
                  <Tab CommandName="cmdTabMain">
                      <Group CommandName="cmdGroupFileActions" SizeDefinition="ThreeButtons">

                          <Button CommandName="cmdButtonNew" />

                          <DropDownButton CommandName='cmdDropDownButton'>
                              <MenuGroup Class='MajorItems'>
                                  <Button CommandName='cmdButtonMoreA' />
                                  <Button CommandName='cmdButtonMoreB' />
                                  <Button CommandName='cmdButtonMoreC' />
                              </MenuGroup>
                          </DropDownButton>

                          <SplitButton>
                              <SplitButton.ButtonItem>
                                  <Button CommandName='cmdButtonMoreB' />
                              </SplitButton.ButtonItem>
                              <SplitButton.MenuGroups>
                                  <MenuGroup Class='MajorItems'>
                                      <Button CommandName='cmdButtonMoreA' />
                                      <Button CommandName='cmdButtonMoreB' />
                                      <Button CommandName='cmdButtonMoreC' />
                                  </MenuGroup>
                              </SplitButton.MenuGroups>
                          </SplitButton>

                      </Group>
                  </Tab>
              </Ribbon.Tabs>
          </Ribbon>
      </Application.Views>

      Note that in the DropDownButton XML element you define only the buttons in the buttons list. On the other hand, the SplitButton XML element contains a definition for both the buttons list and a specific default button (defined in the SplitButton.ButtonItem element).

      The commands bound to these buttons are defined and handled similarly to the commands we already saw.

      CheckBox and ToggleButton

      CheckBox and ToggleButton are two ribbon UI controls that represent a button with a Boolean state. The sole difference between the two is their GUI representation. The Toggle button looks like a button that remains pressed until pressed again. The Checkbox control looks like the familiar checkbox control we all know and love:

      clip_image004

      Figure 4: Toggle button and check box

      Using CheckBox and ToggleButton

      Following is an example of ribbon markup that defines both a ToggleButton and a CheckBox:

      <Application.Views>
          <Ribbon>
              <Ribbon.Tabs>
                  <Tab CommandName="cmdTabMain">

                      <Group CommandName="cmdGroupToggleButton" SizeDefinition="OneButton">
                          <ToggleButton CommandName="cmdToggleButton" />
                      </Group>

                      <Group CommandName="cmdGroupCheckBox">
                          <CheckBox CommandName="cmdCheckBox" />
                      </Group>

                  </Tab>
              </Ribbon.Tabs>
          </Ribbon>
      </Application.Views>

      What's left for us to know is how to handle the "Checked Changed" event and how to get the current value of the CheckBox / ToggleButton.

      Handling "Checked Changed" Event

      Handling the "Checked Changed" event is done exactly the same way we handled the "Button Clicked" event, that is, by implementing IUICommandHandler::Execute function.

      In order to get the current Boolean value of the CheckBox we use another function that IUIFramework provides, namely, IUIFramework::GetUICommandProperty.
      This GetUICommandProperty function receives three parameters.
      The first is the command id we need the property from, in our sample it is ID_CMD_TOGGLE_BUTTON, which is defined in the auto-generated file RibbonIds.h. The second parameter is the id of the property we want to get, in this case it has the value UI_PKEY_BooleanValue, which is defined in UIRibbon.h (comes with Windows SDK).
      The last parameter is the return value of the property.

      Setting the value of a property is done similarly using IUIFramework::SetUICommandProperty

      In the following example we show the previous concepts by handling the "Checked Changed" event of a toggle button. We get the Boolean value of the toggle button, negate it and set it as the Enable property of the checkbox:

      STDMETHODIMP CCommandHandler::Execute(
          UINT nCmdID,
          UI_EXECUTIONVERB verb,
          const PROPERTYKEY* key,
          const PROPVARIANT* ppropvarValue,
          IUISimplePropertySet* pCommandExecutionProperties)
      {
          HRESULT hr;
          HWND hwnd = GetForegroundWindow();

          switch (nCmdID)
          {
          case ID_CMD_TOGGLE_BUTTON:
              BOOL boolValue;
              PROPVARIANT var, varNew;

              hr = g_pFramework->GetUICommandProperty(ID_CMD_TOGGLE_BUTTON,
                                                             UI_PKEY_BooleanValue, &var);
              if (FAILED(hr))
              {
                  return hr;
              }

              hr = PropVariantToBoolean(var, &boolValue);
              if (FAILED(hr))
              {
                  return hr;
              }

              boolValue = !boolValue;
              hr = UIInitPropertyFromBoolean(UI_PKEY_Enabled, boolValue, &varNew);
              if (FAILED(hr))
              {
                  return hr;
              }

              hr = g_pFramework->SetUICommandProperty(ID_CMD_CHECK_BOX,
                          UI_PKEY_Enabled, varNew);
              if (FAILED(hr))
              {
                  return hr;
              }

              break;
          }

          return S_OK;
      }

      The UIInitPropertyFromBoolean is just a helper function, defined in UIRibbonPropertyHelpers.h, which sets a PROPVARIANT variable with a Boolean value and does a compile time check, on the way, to make sure the property is of Boolean type.

      Implementing UpdateProperty

      On the previous section we saw that to set the value of properties we can use the function IUIFramework::SetUICommandProperty. Actually this only works for part of the properties. Other properties are set in a different way, by implementing IUICommandHandler::UpdateProperty, which we shall review now.
      The details of which properties is can be changed using SetUICommandProperty and which can be changed only using UpdateProperty are part of the MSDN documentation of each ribbon UI control.

      The second way for updating properties is a two steps process:

      • First, call IUIFramework::InvalidateUICommand, passing the command id and the property id which should be invalidated.
      • Second, implement IUICommandHandler::UpdateProperty. This function will get as parameters the command id and property id which is needed by the framework and you should return its value.

      Note that the function IUICommandHandler::UpdateProperty might not get called immediately after calling IUIFramework::InvalidateUICommand. It will be called only when the ribbon framework will actually need the property value.

      In the following example we show first how to call the InvalidateUICommand function and how to implement UpdateProperty so that the text of the checkbox changes according to the state of the toggle button:

       

      STDMETHODIMP CCommandHandler::Execute(
          UINT nCmdID,
          UI_EXECUTIONVERB verb,
          const PROPERTYKEY* key,
          const PROPVARIANT* ppropvarValue,
          IUISimplePropertySet* pCommandExecutionProperties)
      {
          ...

          // invalidate checkbox label
          hr = g_pFramework->InvalidateUICommand(ID_CMD_CHECK_BOX,
                                                 UI_INVALIDATIONS_PROPERTY,
                                                 &UI_PKEY_Label);
          ...

          return S_OK;
      }

      STDMETHODIMP CCommandHandler::UpdateProperty(
          UINT nCmdID,
          REFPROPERTYKEY key,
          const PROPVARIANT* ppropvarCurrentValue,
          PROPVARIANT* ppropvarNewValue)
      {
          HRESULT hr = E_FAIL;

          if (key == UI_PKEY_Label)
          {
              // update the Label of the toggle button
              if (nCmdID == ID_CMD_CHECK_BOX)
              {
                  BOOL boolValue;
                  PROPVARIANT var;

                  // get boolean value from toggle button
                  hr = g_pFramework->GetUICommandProperty(ID_CMD_TOGGLE_BUTTON,
                                             UI_PKEY_BooleanValue, &var);
                  if (FAILED(hr))
                  {
                      return hr;
                  }

                  hr = PropVariantToBoolean(var, &boolValue);
                  if (FAILED(hr))
                  {
                      return hr;
                  }

                  if (boolValue)
                  {
                      hr = UIInitPropertyFromString(UI_PKEY_Label,
                                                  L"Checkbox Disabled",
                                                  ppropvarNewValue);
                  }
                  else
                  {
                      hr = UIInitPropertyFromString(UI_PKEY_Label,
                                                  L"Checkbox Enabled",
                                                  ppropvarNewValue);
                  }
                }
            }

         return hr;
      }

      You can find the full code of the sample application used in this post here.

      clip_image005

      Figure 5: Sample application for this post

      In this post we have learned about the commands and views sections in the markup. We've reviewed what different types of buttons are provided by the ribbon framework, and how to use them. Finally, we saw how to get and set properties values of ribbon UI controls.

      That's it for now,
      Arik Poznanski.

      Posted: Jun 13 2011, 01:57 AM by arik | with 9 comment(s) |
      תגים:, , , ,

      Spelling and Grammar Checking Plugin for Windows Live Writer

      Introduction

      In my previous post I’ve presented “After the Deadline”, a spelling and grammar checking web service and my .NET wrapper library. This library allows you to integrate spell and grammar checking in your .NET application. The library was written in C# using .NET 4.

      Also, back in this post, I’ve presented how one can use a .NET 4 DLL from a .NET 2 executable.

      All of this was just preparations for writing my own grammar checker plugin for Windows Live Writer.

      Now, I know what you’re thinking.. “Doesn’t WLW already have a spell checker?”
      Answer: it does, but its grammar checking abilities are quite limited.

      Obviously, I’ve used my “After the Deadline” wrapper library for the grammar checking. And since Windows Live Writer plugins must be written in .NET 2, I’ve used the same techniques mentioned in my previous article mentioned above.

      Where can I get this awesome plugin?

      Well, both the source code and an MSI installer can be downloaded from the downloads section in the new CodePlex project I’ve created.

       

      Using the spelling and grammar checker plugin

      Step 1: Select the text you want to check

      image

      Step 2: Go to the “Insert” tab and select “Grammar Checker” from the listed plugins

      image

      Step 3: Correct the presented errors using the “Spelling and Grammar” dialog

      image

      Step 4: Repeat step 3 until a completed message appears

      image

       

      P.S.

      Somehow, merely 2 days after I've created the CodePlex project there were three blog posts about it. WOW. I guess this plugin was needed more than I thought.

      That’s it for now,
      Arik Poznanski.

      C# Library for Grammar and Spell Checking

      Introduction

      I recently had the idea to create a plug-in for Windows Live Writer that will provide grammar checks in addition to the built-in spell checks.

      As I’ve showed before, creating plug-ins for Windows Live Writer is easy, the problem was to get the code for doing the grammar checking.

      I’ve found this wonderful site named “After the Deadline” that provides a web based API for both grammar and spell checking, free for non-commercial use!

      The site also provides several wrapper libraries for using these APIs. Unfortunately, C# (or any other .NET language) is not among them. Until now.

      I present you a C# wrapper library for easily using the “After the Deadline” APIs from any .NET application.
      I’ve uploaded the C# wrapper to CodePlex and I’ll try to publish it also on the official AtD site.

       

      Features

        • Check both grammar and spelling of a given document
        • Check only grammar of a given document (faster)
        • Get extra information (in HTML format) about specific errors
        • Get general statistics on a given document

       

      APIs

      These previously mentioned features are exposed by the following simple interface:

      /// <summary>
      /// Initializes the After the Deadline service
      /// </summary>
      /// <param name="applicationKey">The application key.</param>
      /// <param name="userKey">The user key.</param>
      public static void InitService(string applicationKey, string userKey);

      /// <summary>
      /// Checks a document and returns errors and suggestions
      /// </summary>
      /// <param name="data">The data to check</param>
      /// <returns>Enumerable of error objects</returns>
      public static IEnumerable<Error> CheckDocument(string data);

      /// <summary>
      /// Checks a document (sans spelling) returns errors and suggestions
      /// </summary>
      /// <param name="data">The data to check</param>
      /// <returns>Enumerable of error objects</returns>
      public static IEnumerable<Error> CheckGrammar(string data);

      /// <summary>
      /// Returns HTML describing an error
      /// </summary>
      /// <param name="text">The text that triggered an error</param>
      /// <returns>The HTML response</returns>
      public static string Info(string text);

      /// <summary>
      /// Returns statistics about the writing quality of a document
      /// </summary>
      /// <param name="data">The data to check</param>
      public static IEnumerable<Metric> Stats(string data);

      The InitService method just sets an application key and user key you should generate according to the following instructions.

      The most useful method is CheckDocument which accepts the text to check and returns a collection of error objects.

      Since this is simply a wrapper around the original REST API, I strongly suggest you check out the original API documentation to get more details about the parameters and return values.

       

      Can you provide some details about the implementation?

      Sure. The API which is exposes by “After the Deadline” site is based on REST and XML responses.

      I simply use WebClient’s DownloadString method to get access to the REST interface and then parse the XML using LINQ to XML. Nice and easy.

       

      What's next?

      On my next post I'll show you a cool implementation of a plugin for Windows Live Writer that uses this library to provide grammar checking.

      That’s it for now,
      Arik Poznanski.

      Ribbon with C++, Part 2: First Ribbon Enabled Application

      In this post we continue our review of the Windows Ribbon Framework feature brought to us in Windows 7. For more information on the ribbon feature in general and Windows Ribbon Framework in particular, make sure you read Part 1.

      Today we will see how to create a ribbon enabled application in C++ using the Windows Ribbon Framework. To show it we will build a small application with a ribbon that will contain two tabs, three groups and several buttons.

      As mentioned in the previous post, there are four steps we need to follow in order to create a ribbon enabled application. Let's dive into the details of these steps.

      One last note before we start, this post requires knowledge in both Win32 and COM development. Also, if you wish to compile the sample application attached to this post, make sure you have Windows 7 SDK installed.

      Step 1: Define the Ribbon UI

      The first thing to do is to declare the ribbon user interface. This is done by creating an XML file that will contain the ribbon UI definition using a XAML-based syntax.

      For our demo application, let's create a file named RibbonMarkup.xml (the XML suffix is not mandatory but is still recommended), with the following content:

      <?xml version='1.0' encoding='utf-8'?>
      <Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
        <Application.Commands>
          
          <Command Name="cmdButtonNew"
                   Symbol="ID_CMD_NEW"
                   LabelTitle="New"
                   LabelDescription="New Description"
                   TooltipTitle="New (Ctrl+N)"
                   TooltipDescription="Create a new image.">
            <Command.LargeImages>
              <Image>Res/New32.bmp</Image>
            </Command.LargeImages>
          </Command>
          
          <Command Name="cmdButtonOpen"
                   Symbol="ID_CMD_OPEN"
                   LabelTitle="Open"
                   LabelDescription="Open Description"
                   TooltipTitle="Open (Ctrl+O)"
                   TooltipDescription="Open an existing image.">
            <Command.LargeImages>
              <Image>Res/Open32.bmp</Image>
            </Command.LargeImages>
          </Command>

          <Command Name="cmdButtonSave"
                   Symbol="ID_CMD_SAVE"
                   LabelTitle="Save"
                   LabelDescription="Save Description"
                   TooltipTitle="Save (Ctrl+S)"
                   TooltipDescription="Save the current image.">
            <Command.LargeImages>
              <Image>Res/Save32.bmp</Image>
            </Command.LargeImages>
          </Command>

          <Command Name="cmdButtonExit"
                   Symbol="ID_CMD_EXIT"
                   LabelTitle="Exit"
                   LabelDescription="Exit Description"
                   TooltipTitle="Exit (Ctrl+X)"
                   TooltipDescription="Exit application.">
            <Command.LargeImages>
              <Image>Res/Exit32.bmp</Image>
            </Command.LargeImages>
          </Command>

          <Command Name="cmdButtonMoreA"
                   Symbol="ID_CMD_MORE_A"
                   LabelTitle="More A"
                   LabelDescription="Sub button A">
            <Command.LargeImages>
              <Image>Res/MoreA32.bmp</Image>
            </Command.LargeImages>
          </Command>

          <Command Name="cmdButtonMoreB"
                   Symbol="ID_CMD_MORE_B"
                   LabelTitle="More B"
                   LabelDescription="Sub button B">
            <Command.LargeImages>
              <Image>Res/MoreB32.bmp</Image>
            </Command.LargeImages>
          </Command>

          <Command Name="cmdButtonMoreC"
                   Symbol="ID_CMD_MORE_C"
                   LabelTitle="More C"
                   LabelDescription="Sub button C">
            <Command.LargeImages>
              <Image>Res/MoreC32.bmp</Image>
            </Command.LargeImages>
          </Command>

          <Command Name="cmdTabMain"
                   Symbol="ID_CMD_TAB_MAIN"
                   LabelTitle="Main">
          </Command>

          <Command Name="cmdTabMore"
                   Symbol="ID_CMD_TAB_MORE"
                   LabelTitle="More">
          </Command>

          <Command Name="cmdGroupFileActions"
                   Symbol="ID_CMD_GROUP_FILE"
                   LabelTitle="File Actions">
          </Command>

          <Command Name="cmdGroupExit"
                   Symbol="ID_CMD_GROUP_EXIT"
                   LabelTitle="">
          </Command>

          <Command Name="cmdGroupMore"
                   Symbol="ID_CMD_MORE"
                   LabelTitle="">
          </Command>
        </Application.Commands>

        <Application.Views>
          <Ribbon>
            <Ribbon.Tabs>
              
              <Tab CommandName="cmdTabMain">
                
                <Group CommandName="cmdGroupFileActions" SizeDefinition="ThreeButtons">
                  <Button CommandName="cmdButtonNew" />
                  <Button CommandName="cmdButtonOpen" />
                  <Button CommandName="cmdButtonSave" />
                </Group>
              
                <Group CommandName="cmdGroupExit" SizeDefinition="OneButton">
                  <Button CommandName="cmdButtonExit" />
                </Group>
                
              </Tab>
              
              <Tab CommandName ="cmdTabMore">
                <Group CommandName="cmdGroupMore" SizeDefinition="ThreeButtons">
                  <Button CommandName="cmdButtonMoreA" />
                  <Button CommandName="cmdButtonMoreB" />
                  <Button CommandName="cmdButtonMoreC" />
                </Group>
              </Tab>
              
            </Ribbon.Tabs>
          </Ribbon>
        </Application.Views>
      </Application>

      Ok, this may look intimidating at first glance, but it is rather easy to understand.
      The ribbon UI definition file has two major sections, Commands and Views.

      For now, suffice to say that the Commands section defines the different actions a user can invoke using the ribbon UI controls. Each such command is defined with its required resources (strings and images). Later, we will write command handlers in the application code.

      The Views section defines the UI controls we want to use, and their layout in the ribbon. Each UI control is bound to a command and thus will trigger it when the UI control executes (e.g. button clicked).

      More details on the Commands and Views sections will be reviewed on the next post.

      A look on the Views section reveals that in our demo application the ribbon has two tabs; the first tab has two groups and the second tab contains one group. Each group contains some buttons. In other words:

      clip_image001Figure 1: First tab

      clip_image002

      Figure 2: Second tab

      If you try to follow the steps yourself, make sure the images you use are bitmaps (BMP format) that have 32 bits per pixel (32BPP). This is a mandatory need for all images used with the Windows Ribbon Framework.

      Step 2: Compile Ribbon UI

      In this step we will see how to use the Ribbon Markup Compiler, provided with Windows 7 SDK, to compile the ribbon markup that we wrote in the previous step, into a compact binary representation of the ribbon UI.

      The compiler executable name is UICC.exe and it can be found at:

      %ProgramFiles%\Microsoft SDKs\Windows\v7.0\Bin\UICC.exe

      To manually compile the markup, open the Windows SDK "CMD Shell" and run:

      UICC.exe RibbonMarkup.xml RibbonUI.bml /header:RibbonIDs.h /res:RibbonResource.rc

      UICC does the following upon run:

      1. Validates the ribbon markup syntax.
      2. Generates a compressed binary representation of the markup along with a RC file that describes it.
        In our demo, these are the files RibbonUI.bml and RibbonResource.rc respectively.
      3. Generates a C++ header file containing constants for the ribbon identifiers. This will be proved useful when we we'll implement the command handlers.
        In our demo, it is the file RibbonIDs.h.

      Note that since our ribbon markup is rather light, the compiler will generate warnings about some missing markup elements. These warnings are not important at this point and we can safely ignore them.

      Later, in step 4, we will setup the ribbon markup compilation as a custom build event in our project.

      Step 3: Write Command Handlers Code

      In this step we will see how to write code that initialize the Windows Ribbon Framework, loads the previously compiled ribbon UI and responds to events generated by the ribbon UI controls.

      Before we dive into the code, let's get to know the main players participating in a ribbon enabled application, namely: UIRibbonFramework, IUIApplication and IUICommandHandler.

      UIRibbonFramework Class

      UIRibbonFramework is a COM class provided by the Windows Ribbon Framework, which implements IUIFramework interface.
      This class is the entry point to the Windows Ribbon Framework. It provides functions for both initializing and destroying the ribbon framework within your application as well as other functions to control the ribbon behavior.

      Its most important functions are:

      • Initialize(HWND topWindow, IUIApplication* application)
        This function initialize the Windows Ribbon Framework within your application.
        It receives an IUIApplication interface which we should implement to supply callbacks that the ribbon framework will invoke. More on this interface later.
      • LoadUI (HINSTANCE instance, LPCWSTR resourceName)
        This function loads the ribbon UI resource. After this function gets called, the ribbon control should be visible.
      • Destroy()
        This function releases all the object references held by the Windows Ribbon Framework.

        IUIApplication Interface

        As mentioned before, IUIApplication is an interface that our application should implement. It provides three callbacks that the ribbon framework will invoke when needed.

        • OnCreateUICommand(UINT32 commandId, UI_COMMANDTYPE typeId, IUICommandHandler** commandHandler)
          This function is called by the ribbon framework when a command, defined in the ribbon markup, should bind to a command handler. The IUICommandHandler is yet another interface we should implement to handle commands execution. More on this interface later.
        • OnDestroyUICommand(UINT32 commandId, UI_COMMANDTYPE typeId, IUICommandHandler* commandHandler)
          This function is called by the ribbon framework when the application window gets destroyed, for each command defined in the ribbon markup.
        • OnViewChanged(UINT32 viewId, UI_VIEWTYPE typeId, IUnknown* view, UI_VIEWVERB verb, INT32 uReasonCode)
          This function is called by the ribbon framework when the ribbon view has changed. For example, when the ribbon is resized, created or destroyed.

        IUICommandHandler Interface

        The IUICommandHandler interface should also be implemented by our application. It is used to execute our code in responds to user actions on the ribbon UI controls. You can think of it as the place to write your "OnButtonClicked" method.

        This interface provides two callbacks that the ribbon framework will invoke when needed.

        • Execute(UINT32 commandId, UI_EXECUTIONVERB verb, const PROPERTYKEY* key, const PROPVARIANT* currentValue, IUISimplePropertySet* commandExecutionProperties)
          This function is called by the ribbon framework when the user performs an action on a UI control which is bound to the command identified by commandId parameter. An example for such an action is clicking a button or selecting an item in a combobox.
        • UpdateProperty(UINT32 commandId, REFPROPERTYKEY key, const PROPVARIANT* currentValue, PROPVARIANT* newValue)
          This function is called by the ribbon framework when it needs to know the value of a property of a UI control which is bound to the command identified by commandId parameter. This can be used to update properties that changes dynamically, like the items list in a combobox control, or the enabled state of a button.

          Initializing the Ribbon

          Now that we are familiar with the main players we can better understand the flow of a ribbon enabled application.

          To initialize the ribbon in your application do the following:

          1. On application load, call CoCreateInstance with CLSID_UIRibbonFramework. The UIRibbonFramework class implements IUIFramework interface.
          2. Call IUIFramework::Initialize and pass it a reference to your implementation of the IUIApplication interface along with the HWND of your application window.
          3. Call IUIFramework::LoadUI which loads the pre-compiled resource and shows the real ribbon.

          The following code shows how to initialize the ribbon framework; it should be called when the application loads. A good place would be when handling the message WM_CREATE:

          Note: error handling code was removed for clarity.

          // Here we instantiate the ribbon framework object.
          CoCreateInstance(CLSID_UIRibbonFramework,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_PPV_ARGS(&g_pFramework));

          // Next, we create the application object (IUIApplication) and call the framework
          // Initialize method, passing the application object and the host HWND
          CApplication::CreateInstance(&g_pApplication);
          g_pFramework->Initialize(hWnd, g_pApplication);

          // Finally, we load the binary markup. This will initiate callbacks to the  
          // IUIApplication object that was provided to the framework earlier, allowing command
          // handlers to be bound to individual commands.
          g_pFramework->LoadUI(GetModuleHandle(NULL), L"APPLICATION_RIBBON");

          The class CApplication implements IUIApplication. The important part of it is to supply implementation of IUICommandHandler when asked by the ribbon framework.
          This is done by implementing IUIApplication::OnCreateUICommand as follows:

          //  Called by the Ribbon framework for each command specified in markup, to allow
          //  the host application to bind a command handler to that command.
          STDMETHODIMP CApplication::OnCreateUICommand(
              UINT nCmdID,
              UI_COMMANDTYPE typeID,
              IUICommandHandler** ppCommandHandler)
          {
              if (NULL == m_pCommandHandler)
              {
                  CCommandHandler::CreateInstance(&m_pCommandHandler);
              }

              return m_pCommandHandler->QueryInterface(IID_PPV_ARGS(ppCommandHandler));
          }

          Note that our implementation of IUIApplication returns the same CCommandHandler object regardless of the command id. Since the IUICommandHandler::Execute function receives the executing command id, we can avoid creating a separate command handler class for each command.

          The following diagram (from MSDN) shows the interactions between the different components when initializing a ribbon enabled application:

          clip_image004

          Figure 3: Initializing a ribbon enabled application


          Implementing Command Handlers

          In order to respond to the user actions on the ribbon we must implement IUICommandHandler::Execute:

          // Called by the Ribbon framework when a command is executed by the user.  
          // For example, when a button is pressed.
          STDMETHODIMP CCommandHandler::Execute(
              UINT nCmdID,
              UI_EXECUTIONVERB verb,
              const PROPERTYKEY* key,
              const PROPVARIANT* ppropvarValue,
              IUISimplePropertySet* pCommandExecutionProperties)
          {
              HWND hwnd = GetForegroundWindow();
              switch (nCmdID)
              {
              case ID_CMD_NEW:
                  MessageBox(hwnd, L"New button was clicked", L"New Clicked", 0);
                  break;

              case ID_CMD_EXIT:
                  PostMessage(hwnd, WM_CLOSE, NULL, NULL);
                  break;
              }

              return S_OK;
          }

          In this example we respond to the "New" button click event and present a message box. We respond to the "Exit" button click event by posting the WM_CLOSE message.

          You might be asking yourself who declared the ID_CMD_NEW, ID_CMD_EXIT constants (and if not, you should!), well, if you recall, in step 2, one of the products of the ribbon markup compiler was a RibbonIDs.h file. This file contains exactly those constants. The name of the constants is what we have defined in the Symbol attribute of the command element, in the ribbon markup. The value of the constant is auto-generated, but can be manually specified by using the Id attribute in the ribbon markup.

          Note that it is critical to use PostMessage and not SendMessage, otherwise the application will crash when closing using this exit command.
          This is a classic case of cutting the branch you sit on. The reason for the crash when using SendMessage is that the handling of WM_CLOSE invokes IUIFramework::Destroy() which releases all the COM objects used by the ribbon framework, including CCommandHandler. Since the CCommandHandler is still in use (we called SendMessage from CCommandHandler::Execute), we get a memory corruption.

          The following diagram (from MSDN) shows the interactions between the different components when the user interacts with the ribbon control:

          clip_image005

          Figure 4: Ribbon framework interaction with command handler

          Step 4: Compile Entire Application

          There is only one addition to the normal compilation process of our Win32 application.
          We need to add a custom build step that runs the ribbon markup compiler and we need to add the generated resource to the application.

          To have your project automatically compile the ribbon markup xml file do the following:

          1. First, add the RibbonMarkup.xml file to the project.
          2. Right click the added file in the Solution Explorer and select Properties, Custom Build Step.
          3. Fill the fields according to the following values:

            Command Line:

            "%ProgramFiles%\Microsoft SDKs\Windows\v7.0\Bin\UICC.exe" RibbonMarkup.xml $(IntDir)\RibbonUI.bml /header:RibbonIDs.h /res:RibbonResource.rc

            Note, on 64 bit operating systems the "%ProgramFiles% environment variable should be replaced with %ProgramW6432%. So the command line should be:

            "%ProgramW6432%\Microsoft SDKs\Windows\v7.0\Bin\UICC.exe" RibbonMarkup.xml $(IntDir)\RibbonUI.bml /header:RibbonIDs.h /res:RibbonResource.rc

            Description: Compiling Ribbon UI Markup

            Outputs
            : RibbonUI.bml;RibbonIds.h;RibbonResource.rc

            Now that we've done these steps we need to compile the application at least once so that the RibbonResource.rc file gets generated.

            Now we add RibbonResource.rc to the project. This will cause the compiled binary representation of the ribbon UI to be embedded as a resource in the application executable.

            Finally, don't forget to add the images you used in to the ribbon markup to project folder. Make sure you use the same relative location as specified in the markup file.

            Now sit back and enjoy your first ribbon enabled application.

            clip_image006

            Figure 5: First ribbon enabled application

            In this post we have seen in details the necessary steps to create an application that uses the Windows Ribbon Framework.

            A working demo of the code presented in this post can be found here.

            That's it for now,
            Arik Poznanski.

            Posted: Jun 06 2011, 01:51 PM by arik | with 12 comment(s) |
            תגים:, , , ,

            Ribbon with C++, Part 1: Introduction to the Windows Ribbon Framework

            Due to popular demand I’ve decided to use the knowledge I’ve gain while creating the Windows Ribbon for WinForms project and write a series of posts about working with the Windows Ribbon Framework with Win32 C++.

            In this post we will learn the basics of the Windows Ribbon Framework.

            What Is a Ribbon?

            Definition (from MSDN): “The Windows Ribbon framework is a rich command presentation system that provides a modern alternative to the layered menus, toolbars, and task panes of traditional Windows applications."

            Put another way, it is the upper part of most office 2007 applications:

            clip_image002

            Figure 1: Microsoft Word 2007 Ribbon

            The ribbon is an innovative way to expose functionality to the user. You can see from the image that the ribbon is composed from tabs, where each tab has groups with buttons, check-boxes, combo-boxes, image galleries, etc.
            It may look like just another toolbar layout, but it’s so much more than that.

            First, the ribbon exposes all the application functions. No more endless menu items hiding your needed feature in a deep sub-menu you can never find.

            Second, the UI is consistent. The ribbon is the only place to look for

            a feature. You no longer need to search through menus, toolbars and dialogs.

            If you have Windows 7 installed and you want to see a live example of the Windows Ribbon Framework check out both Paint and WordPad applications.
            Another application that uses this ribbon is Microsoft Movie Maker, which is part of Windows Live Essentials.

            clip_image004

            Figure 2: Microsoft Paint in Windows 7

             

             

            Why Was It Developed In The First Place?

            Back in August 2003, when Office 2003 came out, the general consensus was that office was done, in a sense that all the required features were finished. On a closer inspection people have admitted that office is very powerful but they don't know how to take advantage of it. The conclusion the office team reached was that the user interface was failing their users.

            To better understand why the UI was failing the users, consider this:

            Word 1.0, released back in 1989, had 2 toolbar and less than 50 menu items. That much UI is easily mastered by any user.

            By the time Word 2003 came out it had 31 toolbars (each consists of many buttons), 19 task panes (just another place to look for commands) and over 250 distinct menu items.

            With so much UI functionality, people didn't even know where to look for a feature.

            In fact, one obvious way to deduce there was a problem with the office UI was that people kept asking for features that already existed!

            So, to rectify the situation Microsoft did an extensive study on what bothered office users the most. In addition they have collected over 3,000,000,000 (yep, that’s 3 billion) office sessions to research how users actually use office.

            After getting all this information they began redesigning the Office UI to better answer the user's needs. And so, after making usability tests on many innovative user interfaces, they came up with the ribbon.

            The ribbon is the single place where the user should look for functionality. The goal was to keep the user's focus on their content, cut the number of choices presented at any given time and above all, be consistent.

            Ribbon APIs And Their Intended Audience

            Since the office ribbon turned out to be a major success, it was not long before many users started to request the ribbon feature in other third-party applications.
            In order to meet public demands Microsoft provided several implementations of the ribbon, each consistent with a different programming model and intended for different audience.

            Note that the ribbon user experience remains the same regardless of the implementation.

            Following are the Ribbon APIs available to date:

            • Windows Ribbon Framework, the subject of this post, available in Windows 7 and Windows Vista with platform update, exposes a COM-based API, to be used by native Win32 developers.
            • MFC Ribbon, available in Visual C++ 2008 Feature Pack, intended to be used by native MFC developers.
            • WPF Ribbon, Preview Version, available in WPF toolkit for .Net 3.5 SP1, to be used by managed WPF developers.
            • Visual Studio Tools for Office Ribbon, available with VSTO, to be used by office add-ins developers.
            • SharePoint Ribbon, available in SharePoint 2010, to be used by SharePoint developers.

            Note: WinForms developers can use Windows Ribbon for WinForms, which is a COM-Interop based wrapper around Windows Ribbon Framework.

            Windows Ribbon Framework Overview

            Let's review what are the included features in the Windows Ribbon Framework.
            We will elaborate on some of these features in future posts.

            • Promotes separation of the view (UI controls) and commands (actions that the UI controls trigger).
            • Provides a full set of UI controls to represent our commands:
              • Different kinds of buttons: Button, HelpButton, SplitButton and DropButton.
                The first two are used to represent a single command, whereas the last two each represent a collection of commands.

              clip_image006

              Figure 3: Three buttons

               

               

               

              • CheckBox and ToggleButton are two UI representations of a single command with a Boolean state.
              • Spinner is a UI representation of a numerical value along with up / down buttons that allows the user to change it.

                clip_image008

                Figure 4: Spinner Control

              • ComboBox represents a list of text items that one of them can be selected.
              • A gallery represents a dynamically populated list of image items that one of them can be selected.
                Galleries also give the live preview feature which enable users to see the results of selecting an item before actually selecting it.
                Galleries come in three variants: DropDownGallery, SplitButtonGallery and InRibbonGallery.

                clip_image010

                Figure 5: InRibbonGallery used in Microsoft Paint

              • FontControl is a composite UI control that encapsulates the needed UI to control font properties like font family, font size, bold, etc.

              clip_image012

              Figure 6: Font Control

              • DropDownColorPicker is a split button that drops down to a full-sized color picker control.

                clip_image014

                Figure 7: Drop Down Color Picker

            • The UI controls can be layout in tabs and groups or application menu.
              The group layout changes automatically according to the available space on screen and the layout definition.
              The group layout definition can be chosen from a predefined list of layouts or can be customized according to the user needs.
            • Support for changing the ribbon structure according to current application mode.
            • Contextual tabs allows you to add temporary tabs when a certain context is available (like showing image tools only when an image is selected).
            • Provides Quick Access Toolbar (QAT), a place for commands that the user selected for quick access.
            • Allows controlling the ribbon colors and visibility properties.
            • Provides an enhanced context popup to go with the ribbon.

              clip_image016

              Figure 8: Ribbon Context Popup

            • Provides highly accessible UI by implementing Microsoft Active Accessibility.
            • Provides support for High DPI and High Contrast settings.

            Windows Ribbon Framework Requirements

            Although Windows Ribbon Framework came out with Windows 7, it was made available to Windows Vista using the platform update mechanism.

            The full list of Windows Ribbon Framework supported platforms is as follows:

            • Windows 7
            • Windows Vista with Service Pack 2 (SP2) and Platform Update for Windows Vista
            • Windows Server 2008 R2
            • Windows Server 2008 with SP2 and Platform Update for Windows Server 2008

            Note that Windows XP is not supported.

            In addition, to develop ribbon enabled applications you must install the Windows 7 SDK.

            Using the Windows Ribbon Framework

            Writing a ribbon-enabled application is a four steps process:

            Step 1: Define the Ribbon UI

            The Ribbon UI is defined in an XML file, using XAML-based syntax.
            In the file you declare what controls to use and how to layout them the ribbon surface.

            Step 2: Compile Ribbon UI

            Using a special compiler, named UICC.exe, you compile the ribbon UI definition into a binary resource file.

            Step 3: Write handler code

            In this step you write the code that runs in responds to user action on the UI, e.g. pressing a button.

            Step 4: Compile entire application

            In this last step you need to compile the code from step 3 and link with the binary resource output from step 2.

            The following diagram (taken from MSDN) illustrates these steps:

            clip_image017

            In this post we have seen what is the ribbon, why was it developed and what ribbon API exist. We also reviewed the features provided by Windows Ribbon Framework and the basic steps for writing a ribbon enabled application.
            On future posts we will dive into the details of creating ribbon enabled applications and see how to use its different features.

            That's it for now,
            Arik Poznanski.