Windows 7 Ribbon – 第 2 部分 – 如何处理 Ribbon 控件事件?
在本部分中,让我们看看如何处理 Windows 7 原生 ribbon 控件的事件。
在本部分中,让我们看看如何处理 ribbon 控件的事件。 我强烈建议您阅读之前关于 ribbon 基础知识的文章,了解它的创建方式。 这篇文章是 前一篇文章 的延续。
为了处理事件,应用程序实现了 IUICommandHandler 接口,并定义了框架事件的 Command handler 方法。 必须在派生类中实现以下函数。
- Execute
执行或预览绑定到 Command handler 的命令。 - UpdateProperty
为绑定的 Command 设置属性值,例如,根据 View 的状态将 Command 设置为启用或禁用。
对于 View 中的每个 Command(XML 文件中的 Application.Views
),Ribbon 框架需要在宿主应用程序中有一个相应的 Command handler。 必须通过 IUIApplication::OnCreateUICommand 通知方法将新的 handler 或现有的 handler 绑定到 Command。 当 UI 组件创建时,将执行此方法。 可以通过查询 IID_PPV_ARGS
接口来创建新的 command handler。 任意数量的 Commands 可以绑定到一个 Command handler。
Command handler 有两个作用。 首先,它可以更新其绑定的任何命令的属性值,例如将命令设置为启用或禁用。 其次,它可以执行或预览与其绑定的任何命令。
在上一部分中,我们看到了 CRibbonImplementer
类。 因此,在这里,我们将修改该类。 我们将创建 handler。
步骤 1
将包含控件 ID 的生成的 .h 文件包含到 CRibbonImplementer
的实现 .h/.cpp 文件中
步骤 2 & 3
从 IUICommandHandler
派生 ribbon 实现者类,并将接口添加到 COM Map
步骤 4
修改 OnCreateUICommand
函数,并在创建控件时添加 UI Handler。
步骤 5
添加 Execute handler 以在单击按钮时获得通知。 这就像一个 Win32 消息循环系统的普通消息循环。
最后一步 (6)
有必要实现 IUICommandHandler::UpdateProperty
,因为基类没有提供任何实现。 我们可以将这个 interface
保持为未实现。
完整的源代码如下所示。 源代码的其他部分没有变化。
#include "stdafx.h"
#include <atlbase.h>
#include <atlcom.h>
#include <initguid.h>
#include <uiribbon.h>
// Step 1: Include menu ribbon resource.h
#include "MenuRibbonRes.h"
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;
}
};