经典MFC界面和Ribbon界面框架对比(单文档为例)
IDE为:VS2008+SP1
A为经典MFC单文档界面:
B为Ribbon风格的MFC单文档界面:
在生成A和B的基础框架代码之后,通过对比工具,发现这两种不同风格的界面主要在MainFrame类中存在一些差异。
应用程序类(CXXXApp)的InitInstance()函数中,B风格在调用InitContextMenuManager()之后,执行了InitShellManager()的初始化。
该句代码主要是为CMFCShellTreeCtrl(文件目录树)和CMFCShellListCtrl(文件列表)的使用做一些Shell的初始化工作。
+++++++++++++++++++++++++++++++++++++++++++++
MainFrm.h数据成员变量存在一定的对应关系
A
CMFCToolBar m_wndToolBar; // 工具栏 CMFCToolBarImages m_UserImages; // 工具栏使用的图片资源 CMFCMenuBar m_wndMenuBar; // 菜单栏 CMFCStatusBar m_wndStatusBar; // 状态栏
B 无菜单栏
CMFCRibbonBar m_wndRibbonBar; // Ribbon工具条 CMFCToolBarImages m_PanelImages; // 工具栏使用的图片资源 CMFCRibbonApplicationButton m_MainButton; // 左上角按钮 CMFCRibbonStatusBar m_wndStatusBar; // 状态栏
MainFrm.cpp中的主要差异代码还是体现在OnCreate()函数中
A
// 创建并初始化主界面上的各个控件 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWndEx::OnCreate(lpCreateStruct) == -1) return -1; BOOL bNameValid; // set the visual manager and style based on persisted value OnApplicationLook(theApp.m_nAppLook); if (!m_wndMenuBar.Create(this)) { TRACE0("Failed to create menubar\n"); return -1; // fail to create } m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY); // prevent the menu bar from taking the focus on activation CMFCPopupMenu::SetForceMenuFocus(FALSE); if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } CString strToolBarName; bNameValid = strToolBarName.LoadString(IDS_TOOLBAR_STANDARD); ASSERT(bNameValid); m_wndToolBar.SetWindowText(strToolBarName); CString strCustomize; bNameValid = strCustomize.LoadString(IDS_TOOLBAR_CUSTOMIZE); ASSERT(bNameValid); m_wndToolBar.EnableCustomizeButton(TRUE, ID_VIEW_CUSTOMIZE, strCustomize); // Allow user-defined toolbars operations: InitUserToolbars(NULL, uiFirstUserToolBarId, uiLastUserToolBarId); if (!m_wndStatusBar.Create(this)) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)); // TODO: Delete these five lines if you don't want the toolbar and menubar to be dockable m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY); m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockPane(&m_wndMenuBar); DockPane(&m_wndToolBar); // enable Visual Studio 2005 style docking window behavior CDockingManager::SetDockingMode(DT_SMART); // enable Visual Studio 2005 style docking window auto-hide behavior EnableAutoHidePanes(CBRS_ALIGN_ANY); // Enable toolbar and docking window menu replacement EnablePaneMenu(TRUE, ID_VIEW_CUSTOMIZE, strCustomize, ID_VIEW_TOOLBAR); // enable quick (Alt+drag) toolbar customization CMFCToolBar::EnableQuickCustomization(); return 0; }
B OnCreate()中调用InitializeRibbon()完成Ribbon工具条的初始化工作
// 创建并初始化主界面上的各个控件 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWndEx::OnCreate(lpCreateStruct) == -1) return -1; BOOL bNameValid; // set the visual manager and style based on persisted value OnApplicationLook(theApp.m_nAppLook); m_wndRibbonBar.Create(this); InitializeRibbon(); if (!m_wndStatusBar.Create(this)) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } CString strTitlePane1; CString strTitlePane2; bNameValid = strTitlePane1.LoadString(IDS_STATUS_PANE1); ASSERT(bNameValid); bNameValid = strTitlePane2.LoadString(IDS_STATUS_PANE2); ASSERT(bNameValid); m_wndStatusBar.AddElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE1, strTitlePane1, TRUE), strTitlePane1); m_wndStatusBar.AddExtendedElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE2, strTitlePane2, TRUE), strTitlePane2); // enable Visual Studio 2005 style docking window behavior CDockingManager::SetDockingMode(DT_SMART); // enable Visual Studio 2005 style docking window auto-hide behavior EnableAutoHidePanes(CBRS_ALIGN_ANY); // Navigation pane will be created at left, so temporary disable docking at the left side: EnableDocking(CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM | CBRS_ALIGN_RIGHT); // Outlook bar is created and docking on the left side should be allowed. EnableDocking(CBRS_ALIGN_LEFT); EnableAutoHidePanes(CBRS_ALIGN_RIGHT); return 0; } // 初始化Ribbion工具条 void CMainFrame::InitializeRibbon() { BOOL bNameValid; CString strTemp; // Load panel images: m_PanelImages.SetImageSize(CSize(16, 16)); m_PanelImages.Load(IDB_BUTTONS); // Init main button: m_MainButton.SetImage(IDB_MAIN); m_MainButton.SetText(_T("\nf")); m_MainButton.SetToolTipText(strTemp); m_wndRibbonBar.SetApplicationButton(&m_MainButton, CSize (45, 45)); // Add "Home" category with "Clipboard" panel: bNameValid = strTemp.LoadString(IDS_RIBBON_HOME); ASSERT(bNameValid); CMFCRibbonCategory* pCategoryHome = m_wndRibbonBar.AddCategory(strTemp, IDB_WRITESMALL, IDB_WRITELARGE); // Create and add a "View" panel: bNameValid = strTemp.LoadString(IDS_RIBBON_VIEW); ASSERT(bNameValid); CMFCRibbonPanel* pPanelView = pCategoryHome->AddPanel(strTemp, m_PanelImages.ExtractIcon (7)); bNameValid = strTemp.LoadString(IDS_RIBBON_STATUSBAR); ASSERT(bNameValid); CMFCRibbonButton* pBtnStatusBar = new CMFCRibbonCheckBox(ID_VIEW_STATUS_BAR, strTemp); pPanelView->Add(pBtnStatusBar); // Add elements to the right side of tabs: bNameValid = strTemp.LoadString(IDS_RIBBON_STYLE); ASSERT(bNameValid); CMFCRibbonButton* pVisualStyleButton = new CMFCRibbonButton(-1, strTemp, -1, -1); pVisualStyleButton->SetMenu(IDR_THEME_MENU, FALSE /* No default command */, TRUE /* Right align */); bNameValid = strTemp.LoadString(IDS_RIBBON_STYLE_TIP); ASSERT(bNameValid); pVisualStyleButton->SetToolTipText(strTemp); bNameValid = strTemp.LoadString(IDS_RIBBON_STYLE_DESC); ASSERT(bNameValid); pVisualStyleButton->SetDescription(strTemp); m_wndRibbonBar.AddToTabs(pVisualStyleButton); }
PS: CXXXApp不再由CWinApp派生,而是由CWinAppEx派生
CMainFrame不再由CFrameWnd派生,而是由CFrameWndEx派生
下载RibbonMFC框架示例代码: RibbonMFC.rar