演练:更新 MFC 随意画图应用程序(第 2 部分)
本演练的第 1 部分演示了如何将 Office Fluent 功能区添加到经典的“随意画图”应用程序。 本部分演示如何添加用户可使用的功能区面板和控件,而不是菜单和命令。
先决条件
章节
该演练部分包含下列内容:
向功能区添加新面板
这些步骤演示如何添加“视图”面板和“窗口”面板,前者包含两个复选框来控制工具栏和状态栏的可见性,后者包含一个垂直方向的拆分按钮来控制多文档界面 (MDI) 窗口的创建和排列。
向功能区栏添加“视图”面板和“窗口”面板
创建一个名为
View
的面板,其中包含两个复选框,它们分别用于切换状态栏和工具栏。从“工具箱”中,将“面板”拖动到“开始”类别。 然后,将两个复选框拖动到面板。
单击面板来修改其属性。 将“标题栏”更改为
View
。单击第一个复选框来修改其属性。 将“ID”更改为
ID_VIEW_TOOLBAR
,将“标题栏”更改为Toolbar
。单击第二个复选框来修改其属性。 将“ID”更改为
ID_VIEW_STATUS_BAR
,将“标题栏”更改为Status Bar
。
创建一个名为
Window
且带有拆分按钮的面板。 当用户单击拆分按钮时,快捷菜单会显示三个已在“随意画图”应用程序中定义的命令。从“工具箱”中,将“面板”拖动到“开始”类别。 然后,将按钮拖动到面板。
单击面板来修改其属性。 将“标题栏”更改为
Window
。单击“”按钮。 将“标题栏”更改为
Windows
,将“键”更改为w
,将“大型图像索引”更改为1
,并将“拆分模式”更改为False
。 然后,单击“菜单项”旁边的省略号 (...) 打开“项编辑器”对话框。单击“添加”三次,添加三个按钮。
单击第一个按钮,然后将“标题栏”更改为
New Window
,将“ID”更改为ID_WINDOW_NEW
。单击第二个按钮,然后将“标题栏”更改为
Cascade
,将“ID”更改为ID_WINDOW_CASCADE
。单击第三个按钮,然后将“标题栏”更改为
Tile
,将“ID”更改为ID_WINDOW_TILE_HORZ
。
保存更改,然后生成并运行应用程序。 此时应会显示“视图”面板和“窗口”面板。 单击这些按钮,确认它们正常运行。
向功能区添加帮助面板
现在,可将“随意画图”应用程序中定义的两个菜单项分配给名为“帮助主题”和“关于随意画图”的功能区按钮。 这些按钮会添加到一个名为“帮助”的新面板中。
添加帮助面板
从“工具箱”中,将“面板”拖动到“开始”类别。 然后,将两个按钮拖动到面板上。
单击面板来修改其属性。 将“标题栏”更改为
Help
。单击第一个按钮。 将“标题栏”更改为
Help Topics
,将“ID”更改为ID_HELP_FINDER
。单击第二个按钮。 将“标题栏”更改为
About Scribble...
,将“ID”更改为ID_APP_ABOUT
。保存更改,然后生成并运行应用程序。 此时应会显示包含两个功能区按钮的帮助面板。
重要
单击“帮助主题”按钮时,“随意画图”应用程序会打开已压缩的名为 your_project_name.chm 的 HTML 帮助文件 (.chm)。 因此,如果项目未命名为 Scribble,必须将帮助文件重命名为你的项目名称。
向功能区添加笔面板
现在,添加一个面板来显示用于控制笔粗细和颜色的按钮。 此面板包含一个复选框,用于在粗笔和细笔之间切换。 其功能类似于“随意画图”应用程序中“粗线”菜单项的功能。
在原始“随意画图”应用程序中,用户可从其单击菜单上的“笔宽”时显示的对话框中选择笔宽。 功能区栏具有足够的空间来放置新控件,因此可使用功能区上的两个组合框替换该对话框。 一个组合框用于调整细笔的宽度,另一个组合框用于调整粗笔的宽度。
向功能区添加笔面板和组合框
从“工具箱”中,将“面板”拖动到“开始”类别。 然后,将复选框和两个组合框拖动到面板上。
单击面板来修改其属性。 将“标题栏”更改为
Pen
。单击此复选框。 将“标题栏”更改为
Use Thick
,将“ID”更改为ID_PEN_THICK_OR_THIN
。单击第一个组合框。 将“标题栏”更改为
Thin Pen
,将“ID”更改为ID_PEN_THIN_WIDTH
,将“类型”更改为Drop List
将“数据”更改为1;2;3;4;5;6;7;8;9;
,并将“文本”更改为2
。单击第二个组合框。 将“标题栏”更改为
Thick Pen
,将“ID”更改为ID_PEN_THICK_WIDTH
,将“类型”更改为Drop List
将“数据”更改为5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;
,并将“文本”更改为5
。新的组合框与任何现有菜单项均不对应,因此必须为每个笔选项创建一个菜单项。
在“资源视图”窗口中,打开 IDR_SCRIBBTYPE 菜单资源。
单击“笔”以打开笔菜单。 然后,单击“在此处键入”并键入
Thi&n Pen
。右键单击键入的文本来打开“属性”窗口,然后将 ID 属性更改为
ID_PEN_THIN_WIDTH
。为每个笔菜单项创建一个事件处理程序。 右键单击创建的“细笔”菜单项,然后单击“添加事件处理程序”。 此时会显示事件处理程序向导。
在向导的“类列表”框中,选择“CScribbleDoc”,然后单击“添加并编辑”。 此命令创建一个名为
CScribbleDoc::OnPenThinWidth
的事件处理程序。将以下代码添加到
CScribbleDoc::OnPenThinWidth
。// Get a pointer to the ribbon bar CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar(); ASSERT_VALID(pRibbon); // Get a pointer to the Thin Width combo box CMFCRibbonComboBox* pThinComboBox = DYNAMIC_DOWNCAST( CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THIN_WIDTH)); //Get the selected value int nCurSel = pThinComboBox->GetCurSel(); if (nCurSel>= 0) { m_nThinWidth = atoi(CStringA(pThinComboBox->GetItem(nCurSel))); } // Create a new pen using the selected width ReplacePen();
接下来,为粗笔创建菜单项和事件处理程序。
在“资源视图”窗口中,打开 IDR_SCRIBBTYPE 菜单资源。
单击“笔”以打开笔菜单。 然后,单击“在此处键入”并键入
Thic&k Pen
。右键单击键入的文本以显示“属性”窗口。 将 ID 属性更改为
ID_PEN_THICK_WIDTH
。右键单击创建的“粗笔”菜单项,然后单击“添加事件处理程序”。 此时会显示事件处理程序向导。
在向导的“类列表”框中,选择“CScribbleDoc”,然后单击“添加并编辑”。 此命令创建一个名为
CScribbleDoc::OnPenThickWidth
的事件处理程序。将以下代码添加到
CScribbleDoc::OnPenThickWidth
。// Get a pointer to the ribbon bar CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx *) AfxGetMainWnd())->GetRibbonBar(); ASSERT_VALID(pRibbon); CMFCRibbonComboBox* pThickComboBox = DYNAMIC_DOWNCAST( CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THICK_WIDTH)); // Get the selected value int nCurSel = pThickComboBox->GetCurSel(); if (nCurSel>= 0) { m_nThickWidth = atoi(CStringA(pThickComboBox->GetItem(nCurSel))); } // Create a new pen using the selected width ReplacePen();
保存更改,然后生成并运行应用程序。 此时会显示新的按钮和组合框。 尝试使用不同的笔宽随意画图。
向笔面板添加颜色按钮
接下来,添加一个 CMFCRibbonColorButton 对象,用户可通过它用颜色随意画图。
向笔面板添加颜色按钮
在添加颜色按钮之前,先为其创建一个菜单项。 在“资源视图”窗口中,打开 IDR_SCRIBBTYPE 菜单资源。 单击“笔”菜单项以打开笔菜单。 然后,单击“在此处键入”并键入
&Color
。 右键单击键入的文本以显示“属性”窗口。 将 ID 更改为ID_PEN_COLOR
。现在,添加颜色按钮。 从“工具箱”中,将“颜色按钮”拖动到“笔”面板中。
单击颜色按钮。 将“标题栏”更改为
Color
,将“ID”更改为ID_PEN_COLOR
,将“简单查找”添加为True
,将“大型图像索引”更改为1
,并将“拆分模式”更改为False
。保存更改,然后生成并运行应用程序。 新的颜色按钮会显示在“笔”面板上。 但是,无法使用它,因为它还没有事件处理程序。 后续步骤将演示如何为颜色按钮添加事件处理程序。
将颜色成员添加到文档类
原始“随意画图”应用程序没有颜色笔,因此必须为其编写实现。 要存储文档的笔颜色,请将新成员添加到文档类 CscribbleDoc
。
将颜色成员添加到文档类
在 scribdoc.h 中的
CScribbleDoc
中,找到// Attributes
节。 在m_nThickWidth
数据成员的定义后面添加以下代码行。// Current pen color COLORREF m_penColor;
每个文档都包含用户已绘制的笔划列表。 每个笔划由
CStroke
对象定义。CStroke
类不包含笔颜色的相关信息,因此必须修改该类。 在 scribdoc.h 中的CStroke
类中,在m_nPenWidth
数据成员的定义后面添加以下代码行。// Pen color for the stroke COLORREF m_penColor;
在 scribdoc.h 中,添加一个新的
CStroke
构造函数,其参数指定宽度和颜色。 在CStroke(UINT nPenWidth);
语句后面添加以下代码行。CStroke(UINT nPenWidth, COLORREF penColor);
在 scribdoc.cpp 中,添加新的
CStroke
构造函数的实现。 在CStroke::CStroke(UINT nPenWidth)
构造函数的实现后面添加以下代码。// Constructor that uses the document's current width and color CStroke::CStroke(UINT nPenWidth, COLORREF penColor) { m_nPenWidth = nPenWidth; m_penColor = penColor; m_rectBounding.SetRectEmpty(); }
更改
CStroke::DrawStroke
方法的第二行,如下所示。if (!penStroke.CreatePen(PS_SOLID, m_nPenWidth, m_penColor))
设置文档类的默认笔颜色。 在 scribdoc.cpp 中,将以下行添加至
CScribbleDoc::InitDocument
,放在m_nThickWidth = 5;
语句后面。// default pen color is black m_penColor = RGB(0, 0, 0);
在 scribdoc.cpp 中,将
CScribbleDoc::NewStroke
方法的第一行更改为以下内容。CStroke* pStrokeItem = new CStroke(m_nPenWidth, m_penColor);
将
CScribbleDoc::ReplacePen
方法的最后一行更改为以下内容。m_penCur.CreatePen(PS_SOLID, m_nPenWidth, m_penColor);
你在上一步中添加了
m_penColor
成员。 现在,为颜色按钮创建一个用于设置成员的事件处理程序。在“资源视图”窗口中,打开 IDR_SCRIBBTYPE 菜单资源。
右键单击“颜色”菜单项,然后单击“添加事件处理程序”。 此时会显示事件处理程序向导。
在向导的“类列表”框中,选择“CScribbleDoc”,然后单击“添加并编辑”按钮。 该命令创建
CScribbleDoc::OnPenColor
事件处理程序存根。
将
CScribbleDoc::OnPenColor
事件处理程序的存根替换为以下代码。void CScribbleDoc::OnPenColor() { // Change pen color to reflect color button's current selection CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar(); ASSERT_VALID(pRibbon); CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST( CMFCRibbonColorButton, pRibbon->FindByID(ID_PEN_COLOR)); m_penColor = pColorBtn->GetColor(); // Create new pen using the selected color ReplacePen(); }
保存更改,然后生成并运行应用程序。 现在,可按下颜色按钮并更改笔的颜色。
初始化笔并保存首选项
接下来,初始化笔的颜色和宽度。 最后,保存并加载文件中的颜色绘图。
初始化功能区栏上的控件
初始化功能区栏上的笔。
在
CScribbleDoc::InitDocument
中向 scribdoc.cpp 添加以下代码,放在m_sizeDoc = CSize(200,200)
语句后面。// Reset the ribbon UI to its initial values CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar(); ASSERT_VALID(pRibbon); CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST( CMFCRibbonColorButton, pRibbon->FindByID(ID_PEN_COLOR)); // Set ColorButton to black pColorBtn->SetColor(RGB(0, 0, 0)); CMFCRibbonComboBox* pThinComboBox = DYNAMIC_DOWNCAST( CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THIN_WIDTH)); // Set Thin pen combobox to 2 pThinComboBox->SelectItem(1); CMFCRibbonComboBox* pThickComboBox = DYNAMIC_DOWNCAST( CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THICK_WIDTH)); // Set Thick pen combobox to 5 pThickComboBox->SelectItem(0);
将颜色绘图保存到文件中。 在
CStroke::Serialize
中向 scribdoc.cpp 添加以下语句,放在ar << (WORD)m_nPenWidth;
语句后面。ar << (COLORREF)m_penColor;
最后,加载文件中的颜色绘图。 在
CStroke::Serialize
方法中添加以下代码行,放在m_nPenWidth = w;
语句后面。ar >> m_penColor;
现在,用颜色随意画图,然后将绘图保存到文件中。
结论
你已经更新了 MFC“随意画图”应用程序。 修改现有应用程序时,请使用本演练作为指南。