创建MFC应用程序项目
实际上,Ribbon界面(Office 2007风格的界面)的开发早在2008年就随着Visual C++ Feature Pack被引入到Visual Studio 2008中。在即将到来的Visual Studio 2010中,Ribbon界面的开发更是得到了原生的支持,使得Ribbon界面的开发更加简便高效。
首先,我们启动Visual Studio 2010,创建一个基于MFC的应用程序,项目模板我们选择“MFC Application”:
图2 创建MFC应用程序
在接下来的“MFC应用程序向导”中,我们就可以对项目的可视化风格进行选择和配置。Visual Studio 2010支持MFC风格、标准的Windows风格,Visual Studio 2005风格和Office 2007风格。而这里的Office 2007风格,就是我们要创建的Ribbon界面:
图3 设置Ribbon界面风格
在接下来的向导页中,我们可以选择命令栏(工具栏。菜单栏)的样式,这里我们当然选择“Use a ribbon”了。当然,为了跟旧有的系统保持兼容,Visual Studio 2010也支持传统的命令式界面,如果你的用户比较保守,想继续使用传统的菜单式界面,我们可以选择“Use a menu bar and toolbar”:
图4 选择命令栏的风格
为了支持丰富的Office 2007界面风格,MFC默认情况下为MFC文档应用程序添加了类似Outlook风格的导航面板(Navigation pane)和标题条(Caption bar)。这两者并不是我们关注的重点,为了更好的展示Ribbon界面,我们这里就去掉这两个多余的面板:
图5 去掉多余的界面元素
到这里,针对新项目的设置就完成了,点击“Finish”按钮关闭应用程序向导,Visual Studio 2010就会按照我们的设置创建相应的MFC应用程序解决方案。编译运行这个解决方案,我们就得到了第一个具有Ribbon界面的应用程序。
图6 第一个Ribbon界面应用程序
Ribbon界面的构成
为了支持新的界面风格的开发,MFC提供了很多新的、经过扩展过后的应用程序类,界面类等。例如在我们的实例程序中用到的 CRibbonApp,CMainFrame就是分别从CWinAppEx,CMDIFrameWndEx派生的。而CWinAppEx和 CMDIFrameWndEx又是从传统的CWinApp和CMDIFrameWnd派生,在原有类的基础上,添加了对新的界面风格的支持。
图7 支持新的界面风格的框架类
熟悉MFC界面开发的朋友都知道,应用程序的CMainFrame类负责整个主框架界面的创建和管理,在传统的菜单式界面下,它负责创建和管理菜单栏,状态栏,工具栏等。同样的,在Ribbon界面下,它同样负责Ribbon界面的创建和管理。
class CMainFrame : public CMDIFrameWndEx
{
DECLARE_DYNAMIC(CMainFrame)
public :
CMainFrame();
// Attributes
public :
// Operations
public :
// Overrides
public :
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
// Implementation
public :
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const ;
virtual void Dump(CDumpContext& dc) const ;
#endif
protected : // control bar embedded members
CMFCRibbonBar m_wndRibbonBar;
CMFCRibbonApplicationButton m_MainButton;
CMFCToolBarImages m_PanelImages;
CMFCRibbonStatusBar m_wndStatusBar;
// Generated message map functions
protected :
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnWindowManager();
afx_msg void OnApplicationLook(UINT id);
afx_msg void OnUpdateApplicationLook(CCmdUI* pCmdUI);
DECLARE_MESSAGE_MAP()
void InitializeRibbon();
};
从上面的代码中我们可以看到,在Ribbon界面下,CMainFrame类包含了三个成员变量:m_wndRibbonBar、 m_MainButton、m_wndStatusBar,分别用于控制Ribbon界面的命令面板,应用程序按钮和状态栏。清楚了各个变量对应的 Ribbon界面元素后,我们就可以操作相应的成员变量,在Ribbon界面上添加我们需要的内容。
图8 Ribbon界面的构成
处理菜单资源和消息响应函数
Ribbon界面相对于传统的菜单式界面,最大的差别就是用新的Ribbon Bar代替了传统的菜单栏。我们可以看到,在默认情况下,Ribbon Bar已经拥有了一个名为“Home”的命令分组(Category),其中又包含了多个面板(Panel),每个面板中有一个或者多个命令按钮 (Ribbon Button)。下面我们就来看看如何在Ribbon Bar上添加一个新的命令分组,然后在其中添加新的命令按钮以执行相应的功能。
按照传统的菜单式界面的开发流程,我们总是先编辑菜单资源,然后再创建相应的菜单命令消息响应函数,最后再实现这个消息响应函数,完成相应的任务。在新的 Ribbon界面中,我们还是先要按照这样的流程,完成菜单资源的编辑,实现消息响应函数等。所以,我们先打开Visual Studio 2010的资源编辑器,在IDR_RibbonUITYPE菜单资源中添加两个新的菜单项。
图9 编辑菜单资源
然后,我们分别为这两个菜单项添加相应的消息响应函数:
图10 添加消息响应函数
这里,我们只是演示Ribbon界面的创建,所以我们将这两个消息响应函数简单地实现如下:
// CRibbonUIView message handlers
void CRibbonUIView::OnEditSayhello()
{
// TODO: Add your command handler code here
AfxMessageBox(_T( " Hello RibbonUI! " ));
}
void CRibbonUIView::OnEditSaygoodbye()
{
// TODO: Add your command handler code here
AfxMessageBox(_T( " Goodbye RibbonUI! " ));
}
添加Ribbon按钮
到现在为止,我们已经按照菜单式界面的开发流程,完成了资源的编辑和消息函数的实现。如果这时我们编译运行解决方案,我们在程序界面上看不到任何变化,因 为我们还没有把这些命令绑定到Ribbon Bar的命令按钮上。在CMainFrame类中,它提供了一个专门的函数CMainFrame::InitializeRibbon()来完成 Ribbon界面的初始化工作,所以,我们在这个函数中添加如下代码,创建新的命令分组,然后将命令按钮映射到我们刚刚创建的菜单项。
void CMainFrame::InitializeRibbon()
{
BOOL bNameValid;
/// …
//////////////////////////////////////////////////////////// //
// 添加一个命令分组(Category)“RibbonUI Category”
CMFCRibbonCategory * pRibbonUICategory =
m_wndRibbonBar.AddCategory(_T( " RibbonUI Category " ),
IDB_WRITESMALL, IDB_WRITELARGE);
// 添加一个面板(Panel)
CMFCRibbonPanel * pTestPanel = pRibbonUICategory -> AddPanel(_T( " RibbonUI Panel " ), m_PanelImages.ExtractIcon( 1 ));
// 在面板上添加Ribbon命令按钮(CMFCRibbonButton)
pTestPanel -> Add( new CMFCRibbonButton(ID_EDIT_SAYHELLO, _T( " Say Hello " ), 0 , 0 ));
pTestPanel -> Add( new CMFCRibbonButton(ID_EDIT_SAYHELLO, _T( " Say Hello " ), 1 ));
pTestPanel -> Add( new CMFCRibbonButton(ID_EDIT_SAYGOODBYE, _T( " Say Goodbye " ), 2 ));
//////////////////////////////////////////////////////////// //
/// …
}
在这段代码中,我们首先利用Ribbon Bar的AddCategory()函数,添加了一个新的命令分组(Category),也就是Ribbon Bar上的一个新的标签页。然后,我们在这个新创建的标签页中,添加了一个新的面板(Panel)。最后,我们创建了三个Ribbon命令按钮 (CMFCRibbonButton),并将它们放置到面板中。通过指定跟菜单资源中的菜单项相同的资源ID,我们将这些Ribbon命令按钮跟我们之前 创建的菜单项一一对应起来。当我们点击某个Ribbon命令按钮时,就会执行相应的菜单命令响应函数。这样,我们就实现了菜单命令在Ribbon Bar的绑定,同时在界面上也能看到我们刚刚添加的命令按钮了。
图11 新创建的命令按钮
在这里,我们只是简单地向大家介绍了Ribbon界面的基本概念和大致的开发流程,要想开发跟Office 2007一样专业的Ribbon界面,我们还有很长的一段路要走,敬请关注本系列文章,创建面向Windows 7的用户界面。
在上回中,我们简单地介绍了开发Ribbon界面的一般流程,同时演示了如何创建包含命令按钮(CMFCRibbonButton)的简单Ribbon界面,相信很多朋友都跃跃欲试,想为自己的软件 创 建专业的Ribbon界面。但是,仅仅使用命令按钮是远远不能满足软件界面的交互需求的,同时也没有完全发挥Ribbon界面的强大威力。为了支持 Ribbon界面,Visual Studio 2010为我们提供了很多控件,除了我们上回介绍的命令按钮(CMFCRibbonButton)之外,还有工具廊 (CMFCRibbonGallery),颜色按钮(CMFCRibbonColorButton),编辑框(CMFCRibbonEdit),进度条 (CMFCRibbonProgressBar)等等。合理地使用这些控件,我们可以创建丰富的Ribbon界面,增强软件的可用性。在这回中,我们就介 绍一下如何使用这些控件,创建更加复杂的Ribbon界面,完成更加复杂的交互任务。
为了更好地理解和创建Ribbon界面,在开始具体地介绍各种控件之前,我们先来了解一下Ribbon界面的结构层次。在上一回中,我们介绍了Ribbon界面主要由Ribbon面板(CMFCRibbonBar)构成,而Ribbon面板主要的主要分为三个层次:
• 分类(CMFCRibbonCategory)
图1 分类
很 明显,“分类”就是作用相近的一类命令的组合。例如在Word 2007的Ribbon界面中,微软将跟插入元素相关的命令都放在“Insert”这个页面中,当用户想在Word文档中插入其他元素时,只要切换到这一 页就可以找到他需要的命令。在形式上,“分类”表现为Ribbon面板上的一个Tab页面。我们可以使用函数AddCategory()在Ribbon面 板上添加一个新的“分类”:
// 添加一个命令分组(Category)“RibbonUI Category”
CMFCRibbonCategory * pRibbonUICategory =
m_wndRibbonBar.AddCategory(_T( " RibbonUI Category " ),
IDB_WRITESMALL, IDB_WRITELARGE);
• 面板(CMFCRibbonPanel)
图2 面板
“面板”是“分类”的下一个层次。它是联系更加紧密的一组命令的组合。面板总是被放置在某个“分类”中,被“分类”所包含。同时,“面板”又是一个容器,它包含着它的下一个层次“元素”。我们可以通过AddPanel()函数在“分类”中添加新的“面板”:
// 添加一个面板(Panel)
// 添加一个面板(Panel)
CMFCRibbonPanel *pTestPanel = pRibbonUICategory->AddPanel(_T("RibbonUI Panel" ),m_PanelImages.ExtractIcon(1));
• 元素(CMFCRibbonBaseElement)
图3 元素
“元素”就是我们通常意义上的控件、这些控件根据各自的功能,被分组放置在各个“面板”上,负责完成具体的交互任务。Visual Studio 2010提供的Ribbon界面“元素”主要包括命令按钮(CMFCRibbonButton)。工具廊(CMFCRibbonGallery)、颜色按 钮(CMFCRibbonColorButton)、编辑框(CMFCRibbonEdit)、进度条(CMFCRibbonProgressBar)等 等。这些类都派生自CMFCRibbonBaseElement。
图4 丰富的Ribbon控件
下面我们就来详细介绍各种Ribbon控件的使用。
命令按钮
命令按钮可以说是我们最常用的Ribbon控件了,我们通常都是通过命令按钮来发送某个命令,执行某个动作。它代替了过去的菜单命令,成为使用最频繁的 Ribbon控件。在Ribbon界面中,主要有三种形式的命令按钮:大图标按钮,小图标按钮以及表示选择的复选按钮(CheckBox)。
图5 命令按钮
按照上回我们介绍的Ribbon界面开发流程,我们需要先准备菜单资源,图标资源,实现消息响应函数等,这里我们就不再赘述这一过程,而把重点放在如何创建Ribbon界面。下面的代码分别演示了这三种按钮的创建过程:
// 创建一个新的面板,用于放置大图标按钮
CMFCRibbonPanel * pPanel1 = pCategory -> AddPanel(_T( " Large Buttons " ));
// 创建按钮
CMFCRibbonButton * pBtn1 = new CMFCRibbonButton(ID_RIBBON_BTN_1, _T( " Button " ), 0 , 0 );
// 指定使用大图标
pBtn1 -> SetAlwaysLargeImage();
// 将按钮添加到面板中
pPanel1 -> Add(pBtn1);
CMFCRibbonButton * pBtn2 = new CMFCRibbonButton(ID_RIBBON_BTN_2, _T( " Menu Button " ), 1 , 1 );
// 可以通过SetMenu()函数为按钮设置一个子菜单
pBtn2 -> SetMenu(IDR_RIBBON_MENU_1);
pBtn2 -> SetAlwaysLargeImage();
pPanel1 -> Add(pBtn2);
CMFCRibbonButton * pBtn3 = new CMFCRibbonButton(ID_RIBBON_BTN_3, _T( " Split Button " ), 2 , 2 );
pBtn3 -> SetMenu(IDR_RIBBON_MENU_1, TRUE);
pBtn3 -> SetAlwaysLargeImage();
// 可以通过RemoveSubItem()和AddSubItem()动态地改变按钮的子项目
pBtn3 -> RemoveSubItem( 0 );
pBtn3 -> AddSubItem( new CMFCRibbonButton(ID_RIBBON_MBTN_1, _T( " Item 1 " ), 2 ), 0 );
pPanel1 -> Add(pBtn3);
// 创建新的面板,用于放置小图标按钮
CMFCRibbonPanel * pPanel2 = pCategory -> AddPanel(_T( " Small " ));
// 创建小图标按钮
CMFCRibbonButton * pBtn4 = new CMFCRibbonButton(ID_RIBBON_BTN_4, _T( " Button " ), 3 );
pPanel2 -> Add(pBtn4);
CMFCRibbonButton * pBtn5 = new CMFCRibbonButton(ID_RIBBON_BTN_5, _T( " Menu Button " ), 4 );
pBtn5 -> SetMenu(IDR_RIBBON_MENU_1);
pPanel2 -> Add(pBtn5);
CMFCRibbonButton * pBtn6 = new CMFCRibbonButton(ID_RIBBON_BTN_6, _T( " Split Button " ), 5 );
pBtn6 -> SetMenu(IDR_RIBBON_MENU_1, TRUE);
pBtn6 -> SetAlwaysLargeImage();
pBtn6 -> RemoveSubItem( 1 );
pBtn6 -> AddSubItem( new CMFCRibbonButton(ID_RIBBON_MBTN_2, _T( " Item 2 " ), 5 ), 1 );
pPanel2 -> Add(pBtn6);
// 创建新的面板,用于放置复选按钮
CMFCRibbonPanel * pPanel3 = pCategory -> AddPanel(_T( " Check Boxes " ));
pPanel3 -> Add( new CMFCRibbonCheckBox(ID_RIBBON_BTN_7, _T( " Check Box 1 " )));
pPanel3 -> Add( new CMFCRibbonCheckBox(ID_RIBBON_BTN_8, _T( " Check Box 2 " )));
pPanel3 -> Add( new CMFCRibbonCheckBox(ID_RIBBON_BTN_9, _T( " Check Box 3 " )));
工具廊
Ribbon界面的一个重要革新,就是可以通过工具廊(CMFCRibbonGallery)控件,对命令的执行效果进行直观地预览。例如Word 2007的段落格式设置,就是通过工具廊直观地展示了格式的样子,这很大程度上减少了用户通过不断尝试各种参数找到合适格式的过程。
图6 工具廊
下面我们就来看看如何创建工具廊这种新的交互工具。如下的代码,演示了工具廊控件的创建过程:
CMFCRibbonPanel * pPanel1 = pCategory -> AddPanel(_T( " Standard " ));
// 创建一个标准的工具廊控件,其中IDB_RIBBON_PALETTE_1指定了
// 工具廊中的各个按钮的图标,通过这些图标对命令效果进行预览
pPanel1 -> Add( new CMFCRibbonGallery(ID_RIBBON_PBTN_1, _T( " Embedded " ), 0 , 0 , IDB_RIBBON_PALETTE_1, 64 ));
// 按钮模式的工具廊控件
// 按钮模式的工具廊控件可以减少对面板空间的占用
CMFCRibbonGallery * pBtn2 = new CMFCRibbonGallery(ID_RIBBON_PBTN_2, _T( " Button " ), 1 , 1 , IDB_RIBBON_PALETTE_1, 64 );
// 设置面板按钮为按钮模式,默认情况下为画廊(Gallery)模式
pBtn2 -> SetButtonMode();
pBtn2 -> SetAlwaysLargeImage();
pPanel1 -> Add(pBtn2);
CMFCRibbonPanel * pPanel2 = pCategory -> AddPanel(_T( " Extended " ));
// 对工具廊进行布局设置
CMFCRibbonGallery * pBtn3 = new CMFCRibbonGallery(ID_RIBBON_PBTN_3, _T( " Resize Vertical " ), 2 , 2 , IDB_RIBBON_PALETTE_1, 64 );
pBtn3 -> SetButtonMode();
// 设置按钮模式下,下拉命令按钮容器(Gallery)的列数
pBtn3 -> SetIconsInRow( 2 );
pBtn3 -> EnableMenuResize(TRUE, TRUE);
pPanel2 -> Add(pBtn3);
CMFCRibbonGallery * pBtn4 = new CMFCRibbonGallery(ID_RIBBON_PBTN_4, _T( " Resize Both " ), 3 , 3 , IDB_RIBBON_PALETTE_1, 64 );
pBtn4 -> SetButtonMode();
// 通过SetIconInRow()和EnableMenuResize()设置命令按钮的布局
pBtn4 -> SetIconsInRow( 4 );
pBtn4 -> EnableMenuResize(TRUE);
pPanel2 -> Add(pBtn4);
CMFCRibbonGallery * pBtn5 = new CMFCRibbonGallery(ID_RIBBON_PBTN_5, _T( " Groups && Subitems " ), 4 , 4 );
// 通过AddGroup()函数,对命令按钮进行分组
pBtn5 -> AddGroup(_T( " Group 1 " ), IDB_RIBBON_PALETTE_1, 64 );
pBtn5 -> AddGroup(_T( " Group 2 " ), IDB_RIBBON_PALETTE_2, 64 );
pBtn5 -> SetButtonMode();
pBtn5 -> SetIconsInRow( 4 );
pBtn5 -> EnableMenuResize(TRUE);
// 在按钮中添加子项目(按钮)
pBtn5 -> AddSubItem( new CMFCRibbonButton(ID_RIBBON_MENU_ITEM_1, _T( " Item 1 " )));
pBtn5 -> AddSubItem( new CMFCRibbonButton(ID_RIBBON_MENU_ITEM_2, _T( " Item 2 " )));
pBtn5 -> AddSubItem( new CMFCRibbonButton(ID_RIBBON_MENU_ITEM_3, _T( " Item 3 " )));
pPanel2 -> Add(pBtn5);
工具栏
在传统的菜单式界面中,工具栏作为菜单的有益补充,被广泛使用。我们通过将一些常用命令放置到工具栏上,可以让用户直观而快速地访问到常用功能,提高了效 率。在Ribbon界面中,工具栏得到了进一步的加强。除了具备原来的工具栏功能外,因为使用命令按钮实现,还使得工具栏具备了下拉菜单等扩展功能。
图7 工具栏
如下的代码演示了如何创建Ribbon界面中的工具栏控件:
CMFCRibbonPanel * pPanel1 = pCategory -> AddPanel(_T( " From Toolbar " ));
// 最简单的,通过AddToolBar()函数,指定一个工具栏资源而创建工具栏
pPanel1 -> AddToolBar(IDR_TOOLBAR);
// 手动创建工具栏
CMFCRibbonPanel * pPanel2 = pCategory -> AddPanel(_T( " Manual " ));
// 创建一个按钮组
CMFCRibbonButtonsGroup * pButtonsGroup1 = new CMFCRibbonButtonsGroup;
// 将新的按钮添加到按钮组中
pButtonsGroup1 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_1, _T( "" ), 0 ));
pButtonsGroup1 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_2, _T( "" ), 1 ));
// 创建一个编辑框控件
CMFCRibbonEdit * pEdit = new CMFCRibbonEdit(ID_RIBBON_GBTN_3, 65 );
// 设置默认文本
pEdit -> SetEditText(_T( " Edit " ));
pButtonsGroup1 -> AddButton(pEdit);
pButtonsGroup1 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_4, _T( "" ), 2 ));
pButtonsGroup1 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_5, _T( "" ), 3 ));
// 将按钮组添加到面板中
pPanel2 -> Add(pButtonsGroup1);
// 添加新的按钮组和按钮
CMFCRibbonButtonsGroup * pButtonsGroup2 = new CMFCRibbonButtonsGroup;
pButtonsGroup2 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_6, _T( "" ), 4 ));
pButtonsGroup2 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_7, _T( "" ), 5 ));
pButtonsGroup2 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_8, _T( "" ), 6 ));
pButtonsGroup2 -> AddButton( new CMFCRibbonButton(ID_RIBBON_GBTN_9, _T( "" ), 7 ));
pPanel2 -> Add(pButtonsGroup2);
CMFCRibbonButtonsGroup * pButtonsGroup3 = new CMFCRibbonButtonsGroup;
CMFCRibbonButton * pBtn10 = new CMFCRibbonButton(ID_RIBBON_GBTN_10, _T( "" ), 8 );
pBtn10 -> SetMenu(IDR_RIBBON_MENU_1);
pButtonsGroup3 -> AddButton(pBtn10);
CMFCRibbonButton * pBtn11 = new CMFCRibbonButton(ID_RIBBON_GBTN_11, _T( "" ), 9 );
// 为按钮指定一个子菜单
pBtn11 -> SetMenu(IDR_RIBBON_MENU_1, TRUE);
pButtonsGroup3 -> AddButton(pBtn11);
pPanel2 -> Add(pButtonsGroup3);
编辑框
在传统的软件 界面中,我们都是通过点击菜单项,或者工具栏上的按钮来简单执行某个命令。在新的Ribbon界面中,我们不仅可以点击按钮,还可以通过编辑框输入数据或者通过ComboBox快速地选择数据等等,完成更加复杂的交互。
图8 编辑框
如下的代码演示了Ribbon编辑框的创建过程:
CMFCRibbonPanel* pPanel1 = pCategory->AddPanel(_T(“Standard"));
// 创建简单编辑框
CMFCRibbonEdit* pBtn1 = new CMFCRibbonEdit(ID_RIBBON_EBTN_1, 90);
pBtn1->SetEditText(_T("Edit" ));
pPanel1->Add(pBtn1);
// 创建可调编辑框
CMFCRibbonEdit* pBtn2 = new CMFCRibbonEdit(ID_RIBBON_EBTN_2, 90);
pBtn2->EnableSpinButtons(0, 99);
pBtn2->SetEditText(_T("0" ));
pPanel1->Add(pBtn2);
// 创建ComboBox
CMFCRibbonComboBox* pBtn3 = new CMFCRibbonComboBox(ID_RIBBON_EBTN_3, TRUE, 74);
// 添加下拉选项
pBtn3->AddItem(_T("Combo Box" ));
for (i = 0; i < 20; i++)
{
CString str;
str.Format(_T("Item %d" ), i + 1);
pBtn3->AddItem(str);
}
pBtn3->SelectItem(0);
pPanel1->Add(pBtn3);
CMFCRibbonPanel* pPanel2 = pCategory->AddPanel(_T("With Icons and Labels" ));
// 创建带图标的编辑框
CMFCRibbonEdit* pBtn4 = new CMFCRibbonEdit(ID_RIBBON_EBTN_4, 90, _T("Label:" ), 0);
pBtn4->SetEditText(_T("Edit" ));
pPanel2->Add(pBtn4);
CMFCRibbonEdit* pBtn5 = new CMFCRibbonEdit(ID_RIBBON_EBTN_5, 90, _T("Label:" ), 1);
pBtn5->EnableSpinButtons(0, 99);
pBtn5->SetEditText(_T("0" ));
pPanel2->Add(pBtn5);
CMFCRibbonComboBox* pBtn6 = new CMFCRibbonComboBox(ID_RIBBON_EBTN_6, TRUE, 74, _T("Label:" ), 2);
pBtn6->AddItem(_T("Combo Box" ));
for (i = 0; i < 20; i++)
{
CString str;
str.Format(_T("Item %d" ), i + 1);
pBtn6->AddItem(str);
}
pBtn6->SelectItem(0);
pPanel2->Add(pBtn6);
CMFCRibbonPanel* pPanel3 = pCategory->AddPanel(_T("Font" ));
// 创建字体选择ComboBox
CMFCRibbonFontComboBox::m_bDrawUsingFont = TRUE;
CMFCRibbonFontComboBox* pBtn7 = new CMFCRibbonFontComboBox(ID_RIBBON_EBTN_7);
pBtn7->SelectItem(_T("Arial" ));
pPanel3->Add(pBtn7);
其他控件
除了前面我们介绍的按钮,工具栏,编辑框等基本控件外,为了支持现代软件 对丰厚的界面交互方式的要求,Visual Studio 2010还提供了很多其他的辅助控件,例如我们通常会用到的“上一步”按钮,标签文本,超链文本,滑动条,进度条等等。这些辅助控件,极大地丰富了Ribbon界面的表现力。
图9 其他控件
如下代码演示了其他各种控件的创建过程:
// 添加“上一步”按钮
CMFCRibbonPanel* pPanel1 = pCategory->AddPanel(_T("Undo" ));
CMFCRibbonUndoButton* pBtn1 = new CMFCRibbonUndoButton(ID_RIBBON_OBTN_1, _T("Undo" ), 0, 0);
// 为返回按钮添加可以返回的动作
for (int i = 0; i < 10; i++)
{
CString str;
str.Format(_T("Action %d" ), i + 1);
pBtn1->AddUndoAction(str);
}
pPanel1->Add(pBtn1);
// 添加文本标签
CMFCRibbonPanel* pPanel2 = pCategory->AddPanel(_T("Label" ));
pPanel2->Add(new CMFCRibbonLabel(_T("Label 1" )));
pPanel2->Add(new CMFCRibbonLabel(_T("Label 2" )));
pPanel2->Add(new CMFCRibbonLabel(_T("Label 3" )));
// 在面板中添加一个分隔符
pPanel2->Add(new CMFCRibbonSeparator());
// 多行文本标签
pPanel2->Add(new CMFCRibbonLabel(_T("This is a multi-line label" ), TRUE));
// 添加超链标签
CMFCRibbonPanel* pPanel3 = pCategory->AddPanel(_T("Hyperlink" ));
// 写mail给我啊
pPanel3->Add(new CMFCRibbonLinkCtrl(ID_RIBBON_OBTN_2, _T("Send e-mail" ), _T("mailto:chenlq@live.com" )));
// 欢迎访问我的blog
pPanel3->Add(new CMFCRibbonLinkCtrl(ID_RIBBON_OBTN_3, _T("Visit site" ), _T("http://space.itpub.net/17237043/" )));
pPanel3->Add(new CMFCRibbonLinkCtrl(ID_RIBBON_OBTN_4, _T("Launch Notepad" ), _T("notepad" )));
// 滑动条
CMFCRibbonPanel* pPanel4 = pCategory->AddPanel(_T("Sliders" ));
pPanel4->SetCenterColumnVert();
pPanel4->Add(new CMFCRibbonLabel(_T("Simple Slider:" )));
pPanel4->Add(new CMFCRibbonSlider(ID_RIBBON_OBTN_5, 70 /* Slider width */ ));
pPanel4->Add(new CMFCRibbonSeparator());
pPanel4->Add(new CMFCRibbonLabel(_T("Slider with Buttons:" )));
CMFCRibbonSlider* pBtn6 = new CMFCRibbonSlider(ID_RIBBON_OBTN_6, 70 /* Slider width */ );
// 设置缩放按钮
pBtn6->SetZoomButtons();
pBtn6->SetRange(0, 100);
pBtn6->SetPos(50);
pPanel4->Add(pBtn6);
// 进度条
CMFCRibbonPanel* pPanel5 = pCategory->AddPanel(_T("Progress Bars" ));
pPanel5->SetCenterColumnVert();
// 简单进度条
pPanel5->Add(new CMFCRibbonLabel(_T("Simple Progress:" )));
pPanel5->Add(new CMFCRibbonProgressBar(ID_RIBBON_OBTN_7, 100 /* Bar width */ ));
pPanel5->Add(new CMFCRibbonButton(ID_RIBBON_OBTN_8, _T("Show Progress 1" )));
pPanel5->Add(new CMFCRibbonSeparator());
pPanel5->Add(new CMFCRibbonLabel(_T("Infinite Progress:" )));
CMFCRibbonProgressBar* pBtn9 = new CMFCRibbonProgressBar(ID_RIBBON_OBTN_9, 100 /* Bar width */ );
// 设置为无限模式,表示动作在进行,但是没有明确的进度
pBtn9->SetInfiniteMode();
pPanel5->Add(pBtn9);
pPanel5->Add(new CMFCRibbonButton(ID_RIBBON_OBTN_10, _T("Show Progress 2" )));
到此为止,我们已经演练了Ribbon界面的大多数控件。通过这些实际代码的演练,我相信大家现在都可以自信地说:
“I can Ribbon now!”
上一篇QQ截图调用工具
下一篇CoolFormat源代码格式化工具
顶
0
踩
0
主题推荐c语言 2010
猜你在找
《C语言/C++学习指南》Qt界面开发篇《C语言/C++学习指南》Linux开发篇C++语言基础Part 1:基础语言-Cocos2d-x手机游戏开发必备C++语言基础JNI:Java与C++的美好结合
VC++ 2010 创建高级Ribbon界面详解2使用VC++ 2010创建Ribbon界面Visual C++ 2010 Express Tips 用 C 和 C++ 创建动态链接库Visual C++ 2010 Express Tips 用 C 和 C++ 创建动态链接库vs2010 MDI多文档ribbon界面添加背景图片
查看评论
19楼 小哼哼L 2015-02-14 14:47发表 [回复] 找了好久,网上动态创建ribbon的文章太少了,值得学习,很不错,太感谢了
18楼 love_zhangxd 2014-02-12 23:48发表 [回复] 这篇文章非常好,感谢作者分享。
最近在研究ribbon的时候,发现 主程序按钮旁边有个快速访问工具按钮,这个按钮怎么自定义,例如隐藏之类的操作,来通过什么实现?
17楼 Joseph-Growth 2013-10-16 09:35发表 [回复] Good Job!
16楼 心灵捕手3 2013-09-18 13:58发表 [回复] 风格是2007的,有没有office2013或者office2010的Re: 无幻 2013-09-18 20:54发表 [回复] 回复心灵捕手3:没有的
15楼 心灵捕手3 2013-09-02 13:33发表 [回复] 我看你只用了new不用delete么Re: 无幻 2013-09-03 09:19发表 [回复] 回复心灵捕手3:父控件会负责销毁Re: 心灵捕手3 2013-09-18 14:07发表 [回复] 回复无幻:恩,知道了,
14楼 marquess 2013-05-23 16:36发表 [回复] 好东西,尤其是里面的一下小功能。我还想问个问题,就是状态栏怎么固定大小?现在我是初始化给的字符串长度有多长,大小就固定了。Re: 无幻 2013-05-24 11:11发表 [回复] 回复marquess:看下源码,如果没有的话,就自己修改添加
13楼 u010385458 2013-05-23 14:27发表 [回复] 请问如何给按钮添加图片啊?添了半天也没添上。。。Re: 无幻 2013-05-23 15:51发表 [回复] 回复u010385458:得先关联图像列表
12楼 KuGames 2012-12-06 21:47发表 [回复] 想请教一下无幻大哥,VS2010中文版是不是有问题啊?比如使用CodeJock15.31向导不能建立Ribbon?没有Ribbon编辑器。是我VS版本的问题吗?英文版有着问题吗?请大哥帮我测试一下,如果英文版没问题就换成英文版吧。谢谢!Re: 无幻 2012-12-06 22:56发表 [回复] 回复KuGames:你不会是下载的Express版本吧?Re: KuGames 2012-12-07 08:43发表 [回复] 回复无幻:按软件界面写的版本是中文“旗舰版”。昨晚把BCG库装上去,向导有BCGPAppWizard但是点击创建连目录还没生成就显示“BCGPAppWizard1 创建失败”,使用说明上有这么一条“必须在运行向导BCGCBProIntegrationWizard.exe时已经编译静态库” 所以我把BCG目录下所有的10/100.sln都debug和Release一下也还是不行。这样做是不是叫作“编译静态库”?新手还不太懂,总结问题,希望大哥能抽空帮帮我,感谢!1.单独创建的MFC有“Ribbon编辑器”,用CodeJock向导就没显示“使用功能区”(也就是英文版写的“Use a Ribbon”)导致创建的界面和VC6创建的相同。2.总感觉我静态编译BCG库这步错了。不然就是中文版的问题。再不然我也想不出为什么了,求助无幻大哥!感谢!Re: 无幻 2012-12-07 09:20发表 [回复] 回复KuGames:1.CodeJock我没使用过,但应该是不能使用VS自带的Ribbon编辑器,你看下这个库的帮助说明;
2.BCG的话,不知道你使用的是哪个版本呢,较新的可以在这里下载http://download.csdn.net/detail/chen_chen_silence/4752728 安装包,比较方便Re: KuGames 2012-12-07 12:43发表 [回复] 回复无幻:我的BCG是12,又更新了?12的BCG装好连向导都用不了,直接创建失败~~非常感谢大哥的回复!!!我再去试试!
11楼 T800GHB 2012-07-17 11:04发表 [回复] 非常感谢楼主的解答,还想问一下CMainFrame::InitializeRibbon()
这个函数是在哪里被调用的?Re: 无幻 2012-07-17 22:31发表 [回复] 回复T800GHB:在CMainFrame::OnCreate里
10楼 T800GHB 2012-07-17 09:46发表 [回复] 请问一下 ,添加面板和按钮等控件是不是可以在资源中直接编辑,而不是用代码?Re: 无幻 2012-07-17 10:04发表 [回复] 回复T800GHB:VS2008SP1 不可以 2010及以上可以
9楼 ggqq123 2012-03-06 12:13发表 [回复] 谢谢,受益匪浅
8楼 w1244707281 2012-02-17 16:56发表 [回复] 很好的文章
7楼 xiaoshu163000 2011-11-05 18:35发表 [回复] 好东西啊,楼主好人~~~~~~~~~~~
6楼 cmaxiao 2011-09-18 14:09发表 [回复] 楼主为什么我找不到InitializeRibbon函数啊Re: 无幻 2011-09-19 20:20发表 [回复] 回复cmaxiao:VS2008SP1建立一个带ribbon的例程,这是自定义函数InitializeRibbon,用于一些初始化
5楼 meloncocoo 2011-07-05 14:07发表 [回复] 请问如何控制不同VIEW时, 不同菜单的显示?Re: 无幻 2011-07-05 14:31发表 [回复] 回复meloncocoo:可以参考MDI不同菜单项
4楼 buzzcut 2011-01-05 17:37发表 [回复] 请问一下,Ribbon里面的数字调整编辑控件你使用过没?怎样获得数字编辑框里面的数字呢?Re: 无幻 2011-01-05 18:26发表 [回复] 可以取控件变量,然后再读值,例如http://blog.csdn.net/akof1314/archive/2010/01/20/5216821.aspx
3楼 wangguang246 2010-07-30 16:27发表 [回复] 这篇文章的源码在什么地方,收录一下Re: 无幻 2010-07-30 16:39发表 [回复] 这是VC2008SP1的示例(ribbongadgets),可以参看工程源代码
2楼 洗洗睡去 2010-07-27 11:37发表 [回复] 好文章啊
1楼 anopos 2010-03-13 22:13发表 [回复] [e01]
很好的文章!