These are the steps required to do get your application ribbon enabled.
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>
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
#include <UIRibbon.h>
#include <UIRibbonPropertyHelpers.h>
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"
::CoCreateInstance(CLSID_UIRibbonFramework, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_spIUIFramework));
and
m_spIUIFramework->Destroy();
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);
};
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
//Load the ribbon
hr = spIUIFramework->LoadUI(GetModuleHandle(NULL) , "myapp_ribbon");
}
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.
, public IUICommandHandler
COM_INTERFACE_ENTRY(IUICommandHandler)
*ppCommandHandler = this; // Register the command handler class as the same class
AddRef();
return S_OK;
// 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