Visual C++ 2010创建Ribbon界面(下)

来源:互联网 发布:java thread run start 编辑:程序博客网 时间:2024/05/21 16:58
上回我们介绍了Windows 7中对Ribbon界面的广泛应用,随着今天Windows 7 Beta1的公开测试,我们也逐渐感觉到Ribbon界面离我们越来越近了。作为程序员,我们做好了迎接Ribbon界面的准备了吗?
  在上回中,我们简单地介绍了开发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)
CMFCRibbonPanel *pTestPanel= pRibbonUICategory->AddPanel(_T("RibbonUI Panel"),              

  ? 元素(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!”

原创粉丝点击