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

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

WTL-Ribbon 类似office 工具条的使用方法_第1张图片

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.实现效果:

WTL-Ribbon 类似office 工具条的使用方法_第2张图片

你可能感兴趣的:(UI,command,user,Office,工具,interface)