WTL-Ribbon 类似office 工具条的使用方法

    技术2025-08-04  17

    WTL-Ribbon

    1.在WTL项目中添加Ribbon的布局定义文件:RibbonMarkup.xml

    < Application xmlns ="http://schemas.microsoft.com/windows/2009/Ribbon" > < Application.Commands > < Command Name ="TabHome" Symbol ="IDC_TabHome" Id ="30000" LabelTitle ="Home" /> < Command Name ="GroupMain" Symbol ="IDC_GroupMain" Id ="30001" LabelTitle ="Main" /> < Command Name ="Toggle" Symbol ="IDC_TOGGLE" Id ="30002" LabelTitle ="Toggle" > < Command.TooltipTitle > Toggle button</ Command.TooltipTitle > < Command.TooltipDescription > Click on Toggle SayHello Button.</ Command.TooltipDescription > < Command.LargeImages > < Image Source ="Button_Image.bmp" /> </ Command.LargeImages > </ Command > < Command Name ="SayHello" Symbol ="IDC_SAY_HELLO" Id ="30003" LabelTitle ="Say hello" > < Command.TooltipTitle > SayHello button</ Command.TooltipTitle > < Command.TooltipDescription > Say hello to me!</ Command.TooltipDescription > < Command.LargeImages > < Image Source ="Button_Image.bmp" /> </ Command.LargeImages > </ Command > </ Application.Commands > < Application.Views > < Ribbon > < Ribbon.Tabs > < Tab CommandName ="TabHome" > < Group CommandName ="GroupMain" SizeDefinition ="TwoButtons" > < ToggleButton CommandName ="Toggle" /> < Button CommandName ="SayHello" /> </ Group > </ Tab > </ Ribbon.Tabs > </ Ribbon > </ Application.Views > </ Application >

    2.选中RibbonMarkup.xml,右键点击Properties,在Property Pages对话框中修改属性:

    Command Line : uicc.exe  RibbonMarkup.xml RibbonMarkup.bml /header:RibbonRes.h /res:RibbonRes.rc

    Outputs: RibbonMarkup.bml;RibbonRes.rc;RibbonRes.h

    3.编译项目,已生成资源文件和符号定义头文件

    4.Ribbon的实现:

    #pragma once #include < atlbase.h > #include < atlcom.h > #include < InitGuid.h > #include < UIRibbon.h > #include < UIRibbonPropertyHelpers.h > #pragma comment(lib,"propsys.lib") #include "RibbonRes.h" CComPtr< IUIApplication > g_spIUIApplication; CComPtr< IUIFramework > g_spIUIFramework; enum { WM_USER_RIBBON_RESIZE = WM_USER+1, WM_USER_RIBBON_COMMAND }; // //User defined message crack // // void OnRibbonResize(UINT height) #define MSG_WM_USER_RIBBONRESIZE(func) / if (uMsg == WM_USER_RIBBON_RESIZE) / { / SetMsgHandled(TRUE); / func((UINT)wParam); / lResult = 0; / if(IsMsgHandled()) / return TRUE; / } // void OnRibbonCommand(UINT cmdID) #define MSG_WM_USER_COMMAND(func) / if (uMsg == WM_USER_RIBBON_COMMAND) / { / SetMsgHandled(TRUE); / func((UINT)wParam); / lResult = 0; / if(IsMsgHandled()) / return TRUE; / } [uuid("6760F7D7-2B58-481E-BB35-D701B8C9576E")] __interface IRibbonNotifyWindow : public IUnknown { HRESULT __stdcall SetNotifyWindow(HWND hNotifyWindow); }; class CRibbonApp : public CComObjectRootEx< CComMultiThreadModel > , public CComCoClass< CRibbonApp > , public IRibbonNotifyWindow, public IUIApplication, public IUICommandHandler { public: BEGIN_COM_MAP(CRibbonApp) COM_INTERFACE_ENTRY(IUIApplication) COM_INTERFACE_ENTRY(IUICommandHandler) COM_INTERFACE_ENTRY(IRibbonNotifyWindow) END_COM_MAP() // //IRibbonNotifyWindow methods // STDMETHOD(SetNotifyWindow)(HWND hNotifyWindow) { m_NotifyWindow = hNotifyWindow; return S_OK; } // //IUIApplication methods // STDMETHOD(OnViewChanged)( UINT32 viewId, UI_VIEWTYPE typeID, __in IUnknown *pView, UI_VIEWVERB verb, INT32 /*uReasonCode*/) { HRESULT hr = E_NOTIMPL; if (typeID == UI_VIEWTYPE_RIBBON) { switch(verb) { case UI_VIEWVERB_CREATE: hr = S_OK; break; case UI_VIEWVERB_SIZE: { CComPtr< IUIRibbon > spUIRibbon; hr = pView->QueryInterface(IID_PPV_ARGS(&spUIRibbon)); CHECKHR(hr); UINT32 height; spUIRibbon->GetHeight(&height); m_NotifyWindow.PostMessage(WM_USER_RIBBON_RESIZE,height); } break; case UI_VIEWVERB_DESTROY: hr = S_OK; break; } } return hr; } STDMETHOD(OnCreateUICommand)( UINT32 nCmdID, UI_COMMANDTYPE typeID, __out IUICommandHandler** ppCommandHandler) { if ((nCmdID==IDC_TOGGLE) || (nCmdID==IDC_SAY_HELLO)) { return QueryInterface(IID_PPV_ARGS(ppCommandHandler)); } return E_NOTIMPL; } STDMETHOD(OnDestroyUICommand)( UINT32 commandId, UI_COMMANDTYPE typeID, __in IUICommandHandler* pCommandHandler) { return E_NOTIMPL; } // //IUICommandHandler methods // 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 == IDC_SAY_HELLO) { m_NotifyWindow.PostMessage(WM_USER_RIBBON_COMMAND,IDC_SAY_HELLO); } else if (nCmdID == IDC_TOGGLE) { PROPVARIANT var, varNew; hr = g_spIUIFramework->GetUICommandProperty(IDC_SAY_HELLO, UI_PKEY_Enabled, &var); CHECKHR(hr); hr = PropVariantToBoolean(var, &m_IsSayHelloEnabled); CHECKHR(hr); m_IsSayHelloEnabled = !m_IsSayHelloEnabled; hr = UIInitPropertyFromBoolean(UI_PKEY_Enabled, m_IsSayHelloEnabled, &varNew); CHECKHR(hr); hr = g_spIUIFramework->SetUICommandProperty(IDC_SAY_HELLO, UI_PKEY_Enabled, varNew); CHECKHR(hr); hr = g_spIUIFramework->InvalidateUICommand(IDC_TOGGLE, UI_INVALIDATIONS_PROPERTY, &UI_PKEY_Label); CHECKHR(hr); } break; } return hr; } STDMETHODIMP UpdateProperty( UINT nCmdID, __in REFPROPERTYKEY key, __in_opt const PROPVARIANT* ppropvarCurrentValue, __out PROPVARIANT* pPropvarNewValue) { HRESULT hr = E_FAIL; if (key == UI_PKEY_Label) { // Update the Label of ToggleButton control if (nCmdID == IDC_TOGGLE) { if (m_IsSayHelloEnabled) { hr = UIInitPropertyFromString(UI_PKEY_Label, L"Disable", pPropvarNewValue); } else { hr = UIInitPropertyFromString(UI_PKEY_Label, L"Enable", pPropvarNewValue); } } } return hr; } private: CWindow m_NotifyWindow; BOOL m_IsSayHelloEnabled; }; //Create and initialize ribbon HRESULT CreateRibbon(HWND hMainWnd) { ATLASSERT(::IsWindow(hMainWnd)); HRESULT hr = CRibbonApp::CreateInstance(&g_spIUIApplication); CHECKHR(hr); CComPtr< IRibbonNotifyWindow > spINotifyWindow; g_spIUIApplication.QueryInterface(&spINotifyWindow); ATLASSERT(spINotifyWindow != NULL); spINotifyWindow->SetNotifyWindow(hMainWnd); hr = g_spIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework); CHECKHR(hr); hr = g_spIUIFramework->Initialize(hMainWnd, g_spIUIApplication); CHECKHR(hr); hr = g_spIUIFramework->LoadUI(::GetModuleHandle(NULL),_T("APPLICATION_RIBBON")); CHECKHR(hr); return hr; } //Destroy ribbon void DestroyRibbon() { g_spIUIFramework->Destroy(); g_spIUIFramework = NULL; g_spIUIApplication = NULL; } //Get the height of ribbon control UINT32 GetRibbonHeight() { ATLASSERT(g_spIUIFramework != NULL); CComPtr< IUIRibbon > spIUIRibbon; g_spIUIFramework->GetView(0,IID_PPV_ARGS(&spIUIRibbon)); ATLASSERT(spIUIRibbon); UINT32 height; spIUIRibbon->GetHeight(&height); return height; }

    5.在主窗口中使用Ribbon:

    #pragma once #include "MyView.h" #include "Ribbon.h" typedef CWinTraits< WS _OVERLAPPEDWINDOW |WS_CLIPCHILDREN > CMyWindowTraits; class CMyWindow : public CWindowImpl< CMyWindow , CWindow , CMyWindowTraits > { public: CMyWindow() { CWndClassInfo& wci = GetWndClassInfo(); if (!wci.m_atom) { wci.m_wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); } } public: DECLARE_WND_CLASS(_T("My WTL main window")) BEGIN_MSG_MAP_EX(CMyWindow) MSG_WM_CREATE(OnCreate) MSG_WM_DESTROY(OnDestroy) MSG_WM_SIZE(OnSize) //Ribbon message MSG_WM_USER_RIBBONRESIZE(OnRibbonResize) MSG_WM_USER_COMMAND(OnRibbonCommand) END_MSG_MAP() int OnCreate(LPCREATESTRUCT /*lpCreateStruct*/) { //Create and initialize ribbon HRESULT hr = CreateRibbon(m_hWnd); CHECKHR(hr); //Create view window CRect rc; GetClientRect(&rc); rc.top += GetRibbonHeight(); m_View.Create(m_hWnd,rc,NULL,WS_CHILD|WS_VISIBLE); return 0; } void OnSize(UINT /*nType*/, CSize /*size*/) { if (m_View.m_hWnd) { CRect rc; GetClientRect(&rc); rc.top += GetRibbonHeight(); m_View.SetWindowPos(m_hWnd,&rc,SWP_NOZORDER | SWP_NOACTIVATE); } } void OnRibbonResize(UINT height) { CRect rc; GetClientRect(&rc); rc.top += height; m_View.SetWindowPos(m_hWnd,&rc,SWP_NOZORDER | SWP_NOACTIVATE); } void OnRibbonCommand(UINT cmdID) { if (cmdID == IDC_SAY_HELLO) { MessageBox(_T("MyButton button is clicked!"),_T("WTL ribbon message")); } } void OnDestroy() { //Destroy ribbon DestroyRibbon(); PostQuitMessage(0); } private: CMyView m_View; };

    6.实现效果:

    最新回复(0)