Click here to Skip to main content
Click here to Skip to main content
Technical Blog

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

, 24 Sep 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
In this installment, let’s see how to handle the events of Windows 7 native ribbon control.

In this instalment, let’s see how to handle the events of the ribbon control. I strongly recommend you to read the previous post on the basics of ribbon about 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 handler.
  • 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 to create a new command handler by querying IID_PPV_ARGS interface. 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 the CRibbonImplementer class. So here we will be modifying the class. We'll be creating the handler.

Step 1 – Include the generated .h file that 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 the source code.

#include <span class="code-string">"stdafx.h"
</span>

#include <span class="code-keyword"><atlbase.h>
</span>

#include <span class="code-keyword"><atlcom.h>
</span>

#include <span class="code-keyword"><initguid.h>
</span>

#include <span class="code-keyword"><uiribbon.h>
</span>

// Step 1: Include menu ribbon resource.h
#include <span class="code-string">"MenuRibbonRes.h"
</span>


class CRibbonImplementer:
	public CComObjectRootEx<CComMultiThreadModel>,
	public IUIApplication,
	// Step 2: derive from IUICommandHandler
	public IUICommandHandler
{
public:
	BEGIN_COM_MAP(CRibbonImplementer)
		COM_INTERFACE_ENTRY(IUIApplication)
		// Step 3: IUICommandHandler add in the 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;
	}
};

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sarath C
Technical Lead
India India
Software Developer
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 2 PinmemberFranz Brunner23-Jan-10 1:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 25 Sep 2010
Article Copyright 2009 by Sarath C
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid