Windows 7 Ribbon – Part 2 – How handle ribbon control events?

 

In this installement, let’s see how to handle the events of the ribbon control. I strongly reconmmend you to read the previous post on the basics of ribbon the way it’s being created. This is a continuation of the previous post.

To handle the events, the IUICommandHandler interface is implemented by the application and defines the Command handler methods for framework events.  The following function has to be implemented in the derived class.

Execute
Executes or previews the Commands bound to the Command hand`ler.

UpdateProperty
Sets a property value for a bound Command, for example, setting a Command to enabled or disabled depending on the state of a View.

For each Command in a View(Application.Views in the XML file), the Ribbon framework requires a corresponding Command handler in the host application. A new handler or an existing handler must be bound to the Command through the IUIApplication::OnCreateUICommand notification method.  This method is executed when the UI component is created. It’s possible create new command handler by querying IID_PPV_ARGS intefac. Any number of Commands can be bound to a Command handler.

The Command handler serves two purposes. First, it can update the values of properties for any command to which it is bound, such as setting a command to enabled or disabled. Second, it can execute or preview any commands to which it is bound.

In the previous instalment we’ve seen CRibbonImplementer class. So here we will be modifying the class. We’ll be creating the the handler

Step 1 – Include the generated .h file contains control IDs to the implementation .h/.cpp file of CRibbonImplementer

b1

Step 2 & 3 – Derive ribbon implementer class from IUICommandHandler and add the interface to COM Map

b2

Step 4 – Modify OnCreateUICommand function and add UI Handler on creating the control.

b3

Step 5 -  Add Execute handler to get notification when the button is clicked. This is like the normal message loop of a Win32 message loop system.b4

The final Step (6 ) – It’s necessary to implement IUICommandHandler::UpdateProperty as the base class doesn’t provide any implementations. We can leave this interface as unimplemented.

b5

The full Source code is given below. There’s no change in the other part of source code.

[sourcecode language='cpp']
#include “stdafx.h”
#include
#include
#include
#include
// Step 1: Include menu ribbon resource.h
#include “MenuRibbonRes.h”

class CRibbonImplementer:
public CComObjectRootEx,
public IUIApplication,
// Step 2: derive fromm IUICommandHandler
public IUICommandHandler
{
public:
BEGIN_COM_MAP(CRibbonImplementer)
COM_INTERFACE_ENTRY(IUIApplication)
// Step 3: IUICommandHandler add in teh COM Map
COM_INTERFACE_ENTRY(IUICommandHandler)
END_COM_MAP()

STDMETHOD(OnCreateUICommand)(UINT32 nCmdID, __in UI_COMMANDTYPE typeID, __deref_out IUICommandHandler** ppCommandHandler)
{
// Step 4: IUICommandHandler
// if my button is being created, the handler is created and attached
if (nCmdID == cmdMyButton)
{
return QueryInterface(IID_PPV_ARGS(ppCommandHandler));
}
return E_NOTIMPL;
}

/* Step 5: Implement execute function.
This function will be called on clicking
the controls attached to command handler */
STDMETHODIMP Execute(UINT nCmdID,
UI_EXECUTIONVERB verb,
__in_opt const PROPERTYKEY* key,
__in_opt const PROPVARIANT* ppropvarValue,
__in_opt IUISimplePropertySet* pCommandExecutionProperties)
{
HRESULT hr = S_OK;
switch (verb)
{
case UI_EXECUTIONVERB_EXECUTE:
if (nCmdID == cmdMyButton)
{
MessageBox(NULL, _T( “Clicked on My Button!” ),
_T(“My Button Execute”), MB_OK);
}
break;
}

return hr;

}

// unimplemented methods
// Step 6: Implement Update Property interface as well
STDMETHODIMP UpdateProperty(UINT nCmdID,
__in REFPROPERTYKEY key,
__in_opt const PROPVARIANT* ppropvarCurrentValue,
__out PROPVARIANT* ppropvarNewValue)
{
return E_NOTIMPL;
}

STDMETHOD(OnViewChanged)(UINT32 nViewID, __in UI_VIEWTYPE typeID, __in IUnknown* pView, UI_VIEWVERB verb, INT32 uReasonCode)
{
return E_NOTIMPL;
}

STDMETHOD(OnDestroyUICommand)(UINT32 commandId,
__in UI_COMMANDTYPE typeID,
__in_opt IUICommandHandler* pCommandHandler)
{
return E_NOTIMPL;
}

STDMETHODIMP UpdateProperty(UINT nCmdID,
__in REFPROPERTYKEY key,
__in_opt const PROPVARIANT* ppropvarCurrentValue,
__out PROPVARIANT* ppropvarNewValue)
{
return E_NOTIMPL;
}
};
[/sourcecode]

 
This entry was posted in Uncategorized. Bookmark the permalink.
  • Wael Salman

    Hi,

    I made a huge research in order to make sure that Visual Studio 2010 Beta has Ribbon Framework, and especially in .Net and C#. Some people say that they will provide it , and some others say they will not.

    What can you tell me about that ??
    How can we use this Ribbon using C# .Net , Drag and drop into the designer??

  • http://codereflect.com/ Sarat

    Windows API Code Pack wont support ribbon in their current release. May be in future.

  • Wael Salman

    Thanx

  • Donald Bracewell

    Hello, I belive I have implemented all the code you talk about in this post for my single document MFC application. However, I face the problem that the ribbon does not show up after the application start. I have to resize the window to make the ribbon appear. The ribbon even flashes like if some update UI event is missing or something. Do somebody elese has such problem? Or could you suggest what’s going wrong in my app? I did not try your code for dialog based MFC, so there may be someting elese to do with SDI/MDI apps, maybe… ? Thanks.

  • Matt Seemon

    The Ribbon is designed to appear only if the form of a certain minimum size. The Default form size in Visual Studio is too small to display it. You will notice this behavior in Paint and Wordpad, which have the ribbon implemented.

  • Matt Seemon
  • Matt Seemon
  • Donald Bracewell

    Hello again, I managed to run a ribbon inside of SDI Application. I had to suppress some initialization that VC2008 wizard generated automatically in CMainFrm::OnCreate and Application::InitInstance functions. I also faced the problem when trying to play with “htmledit” sample from Windows 7 SDK. My CScrollView class could not give aditional room for the ribbon – so it covered all the window frame until I made my CFrameWndEx class a CFrameWnd and until I implemented RibbonBar class as well (see SDK). I found that difficult to find any article covering my problems while implementing ribbon, except this forum, so I’m willing to share my code if there is interest. I would appreciate any further tips.