Windows Ribbon markup – all about Ribbon UI (part 1)

by Francis 27. May 2009 01:11

In Why Windows Ribbon I have touched up on the Authoring and implementation [Designer vs. Developer] aspect of the Window Ribbon. I will try to get into some details about the authoring part of the Ribbon development.

The outer skeleton of the Windows Ribbon markup look like this,

<Application xmlns=http://schemas.microsoft.com/windows/2009/Ribbon>
    <Application.Commands>
        <Command Name="cmdFileNew" Symbol="cmdFileNew">
        . . .
        </Command>
        . . .
    </Application.Commands>
    <Application.Views>
        <Ribbon Name="MyApp">
            <Ribbon.ApplicationMenu>
                <ApplicationMenu CommandName="cmdAppMenu">
                    . . .
                </ApplicationMenu>
            </Ribbon.ApplicationMenu>
            <Ribbon.Tabs>
                <Tab CommandName="cmdTabHome">
                    <Tab.ScalingPolicy>
                        . . .
                    </Tab.ScalingPolicy>
                    <Group CommandName=". . ." SizeDefinition=". . .">
                        . . .
                    </Group>
                </Tab>
                . . .
            </Ribbon.Tabs>
            . . .
        </Ribbon>
    </Application.Views>
</Application>

Here in the above markup a command will be specified in the Application.Commands section. eg.

<Command Name="cmdFileNew" Symbol="cmdFileNew">
    <Command.LabelTitle>
        <String>New</String>
    </Command.LabelTitle>
    <Command.LargeImages>
        <Image MinDPI="96">res\\new_32.bmp</Image>
        <Image MinDPI="120">res\\new_40.bmp</Image>
        <Image MinDPI="144">res\\new_48.bmp</Image>
        <Image MinDPI="192">res\\new_64.bmp</Image>
    </Command.LargeImages>
    <Command.SmallImages>
        <Image MinDPI="96">res\\new_16.bmp</Image>
        <Image MinDPI="120">res\\new_20.bmp</Image>
        <Image MinDPI="144">res\\new_24.bmp</Image>
        <Image MinDPI="192">res\\new_32.bmp</Image>
    </Command.SmallImages>
    <Command.TooltipTitle>
        <String>New (Ctrl+N)</String>
    </Command.TooltipTitle>
    <Command.TooltipDescription>
        <String>Create a new document</String>
    </Command.TooltipDescription>
    <Command.Keytip>
        <String>N</String>
    </Command.Keytip>
</Command

In the above definition of a concept ‘New’, we are specifying,

  1. Name of concept
  2. Big images for all main DPIs (say big button in a group)
  3. Small images for all main DPIs (say for QAT or a small button in a group)
  4. Tooltip
  5. Tooltip description
  6. Key tip (Keyboard accessibility)

It is not mandatory to specify all DPI images in your resource, but it is advice to provide the same so that we can avoid the data loss happened because of the compression or stretching.

More details Command Element

In the next blog I will touch up on the Standard group templates and Custom templates. Also will see how we can customize Ribbon with respect layout and resize logic.

Tags: ,

Windows 7 | Windows Ribbon

Implementing Windows Ribbon

by Francis 20. May 2009 15:43

These are the steps required to do get your application ribbon enabled.

  • Create a 'myapp.ribbon.xml' which has the layout definition of the Ribbon.

    A sample ribbon markup 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 Name="MyApp">

<Ribbon.ApplicationMenu>

<ApplicationMenu CommandName="cmdAppMenu">

. . .

</ApplicationMenu>

</Ribbon.ApplicationMenu>

<Ribbon.Tabs>

<Tab CommandName="cmdTabHome">

<Tab.ScalingPolicy>

. . .

</Tab.ScalingPolicy>

<Group CommandName="cmdChunkClipboard" SizeDefinition="BigButtonsAndSmallButtonsOrInputs">

. . .

</Group>

</Tab>

. . .

</Ribbon.Tabs>

. . .

</Ribbon>

</Application.Views>

</Application>

     

  • Setup Visual file and uicc.exe

    We should create a custom build step for the markup file

uicc.exe /b myapp.ribbon.xml myapp.ribbonb /header:ids.h /res:myapp_ribbon.rc /name:myapp

  • Add the following files as common includes

#include <UIRibbon.h>

#include <UIRibbonPropertyHelpers.h>

     

  • Resource inclusion

    The generated resource file 'myapp_ribbon.rc' should be included in the application resource file( say myapp.rc)

#include "ids.h"

#include "myapp_ribbon.rc"

       

  • Initialization and un-initialization of the Ribbon framework in the App constructor and destructor respectively?

           

::CoCreateInstance(CLSID_UIRibbonFramework, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_spIUIFramework));

and

m_spIUIFramework->Destroy();

       

  • Implement IUIApplication, which receives the application level notification from ribbon

class CApplication

: public CComObjectRootEx<CComMultiThreadModel>

, public IUIApplication

{

public:

BEGIN_COM_MAP(CApplication)

COM_INTERFACE_ENTRY(IUIApplication)

END_COM_MAP()

       

STDMETHOD(OnViewChanged)(UINT viewId, __in UI_VIEWTYPE typeID, __in IUnknown* pView, UI_VIEWVERB verb, INT uReasonCode);

     

STDMETHOD(OnCreateUICommand)(UINT32 nCmdID,

__in UI_COMMANDTYPE typeID,

__deref_out IUICommandHandler** ppCommandHandler);

STDMETHOD(Activate)(BOOL fInputActive);

     

STDMETHOD(OnDestroyUICommand)(UINT32 commandId, __in UI_COMMANDTYPE typeID, __in_opt IUICommandHandler* commandHandler);

};

       

  • Initialize the Ribbon

    Call the following initialization code by passing HWND of the parent frame and pointer to IUIFramework which will get the initial call backs from the ribbon

CComObject<CApplication> *pApplication;

hr = CComObject<CApplication>::CreateInstance(&pApplication);

if (SUCCEEDED(hr))

{

CComPtr<IUIFramework> m_spIUIFramework;

HRESULT hr = spIUIFramework->Initialize(*pFrame, pApplication); //Here *pFrame - HWND of framewnd

if (SUCCEEDED(hr))

{

//Load the ribbon

hr = spIUIFramework->LoadUI(GetModuleHandle(NULL) , "myapp_ribbon");

}

}

       

  • Implement handler class (here I am creating a generic handler class) which implements IUICommandHandler

    This class receives execute command when we press a ribbon concept. In addition this class is responsible for providing the ribbon with dynamic information of the concepts like enabled, checked etc.

    Here for simplicity I am reusing CApplication class for this purpose.      

class CApplication

: public CComObjectRootEx<CComMultiThreadModel>

, public IUIApplication

, public IUICommandHandler

{

public:

BEGIN_COM_MAP(CApplication)

COM_INTERFACE_ENTRY(IUIApplication)

COM_INTERFACE_ENTRY(IUICommandHandler)

END_COM_MAP()

       

STDMETHOD(OnViewChanged)(UINT viewId, __in UI_VIEWTYPE typeID, __in IUnknown* pView, UI_VIEWVERB verb, INT uReasonCode);

     

STDMETHOD(OnCreateUICommand)(UINT32 nCmdID,

__in UI_COMMANDTYPE typeID,

__deref_out IUICommandHandler** ppCommandHandler);

{

*ppCommandHandler = this; // Register the command handler class as the same class

AddRef();

return S_OK;

}

       

STDMETHOD(Activate)(BOOL fInputActive);

     

STDMETHOD(OnDestroyUICommand)(UINT32 commandId, __in UI_COMMANDTYPE typeID, __in_opt IUICommandHandler* commandHandler);

       

// User action callback, with transient execution parameters

STDMETHOD(Execute)(UINT nCmdID,

UI_EXECUTIONVERB verb,

__in_opt const PROPERTYKEY* key,

__in_opt const PROPVARIANT* ppropvarValue,

__in_opt IUISimplePropertySet* pCommandExecutionProperties)

{

MessageBox(NULL, L"Got the event", L"Action message", MB_OK); //Recieves messages for any action on ribbon buttons

}

       

// Asks the application for a specific property value

STDMETHOD(UpdateProperty)(UINT nCmdID,

__in REFPROPERTYKEY key,

__in_opt const PROPVARIANT* ppropvarCurrentValue,

__out PROPVARIANT* ppropvarNewValue);

};

 

 

The following image represents how the messages are passed between Ribbon Framework and the application.

 

More information on Ribbon Markup, Windows Ribbon Framework Developer Guides

Tags: , ,

Windows 7 | Windows Ribbon

Why Windows Ribbon

by Francis 19. May 2009 15:25
  1. Authoring and implementation [Designer vs. Developer]

    Ribbon provides great authoring story by abstracting the behaviors from specific controls keeping the dynamic nature (look at dynamic gallery, App Mode, Contextual Tabs). The static portion of the UI is defined in the xml markup, and certain interface represents the dynamic nature.

  2. Consistent experience provided by platform and automatically chosen based on location

Ribbon UX

  • QAT, Tab, Application Menu, Chunks, Contextual Tabs
  • Application Modes

    Application Mode provides the easy way to specify a different mode of the applications like Print preview mode. Here you can completely hide the groups/tabs which are not relevant.

  • Inbuilt complex controls - Font Chunk, Color Chunk

    Ribbon platform provides these complex controls which supports live preview (See the above picture for the look and feel of these controls)

  • Custom Template

    Using custom template, you can define your own custom layout and resize story of a chunk.

    Please note that Ribbon ships with predefined sets of standard template

  • Live Preview

    Live preview helps preview the effect of an action before applying it. This is similar to the live preview available with Office 2007 application.

  • Gallery

  • Hi DPI and Hi Contrast Support (ability to specify the images for different contrast in the xml)
  • Accessibility (Ribbon control implement IAccessible interface)
  • Resize Rules (Automatically adjust groups when the window is resized) 

For more details refer: Introducing the Windows Ribbon Framework

Coming up next: How to make a simple Windows Ribbon application

Tags: ,

Windows 7 | Windows Ribbon

About Me

Francis Abraham working with Microsoft originally from Allappuzha, the backwater hub of 'Gods own Country', Kerala.

My website www.franish.com

RecentPosts