Walkthrough: Updating the MFC Scribble Application (Part 2)
Part 1 of this walkthrough showed how to add an Office Fluent Ribbon to the classic Scribble application. This part shows how to add ribbon panels and controls that users can use instead of menus and commands.
Prerequisites
Sections
This part of the walkthrough has the following sections:
Adding New Panels to the Ribbon
These steps show how to add a View panel that contains two check boxes that control the visibility of the toolbar and the status bar, and also a Window panel that contains a vertically oriented split button that controls the creation and arrangement of multiple-document interface (MDI) windows.
To add a View panel and Window panel to the ribbon bar
Create a panel named
View
, which has two check boxes that toggle the status bar and toolbar.From the Toolbox, drag a Panel to the Home category. Then drag two Check Boxes to the panel.
Click the panel to modify its properties. Change Caption to
View
.Click the first check box to modify its properties. Change ID to
ID_VIEW_TOOLBAR
and Caption toToolbar
.Click the second check box to modify its properties. Change ID to
ID_VIEW_STATUS_BAR
and Caption toStatus Bar
.
Create a panel named
Window
that has a split button. When a user clicks the split button, a shortcut menu displays three commands that are already defined in the Scribble application.From the Toolbox, drag a Panel to the Home category. Then drag a Button to the panel.
Click the panel to modify its properties. Change Caption to
Window
.Click the button. Change Caption to
Windows
, Keys tow
, Large Image Index to1
, and Split Mode toFalse
. Then click the ellipsis (...) next to Menu Items to open the Items Editor dialog box.Click Add three times to add three buttons.
Click the first button and then change Caption to
New Window
, and ID toID_WINDOW_NEW
.Click the second button and then change Caption to
Cascade
, and ID toID_WINDOW_CASCADE
.Click the third button and then change Caption to
Tile
, and ID toID_WINDOW_TILE_HORZ
.
Save the changes, and then build and run the application. The View and Window panels should be displayed. Click the buttons to confirm that they function correctly.
Adding a Help Panel to the Ribbon
Now, you can assign two menu items that are defined in the Scribble application to ribbon buttons that are named Help Topics and About Scribble. The buttons are added to a new panel named Help.
To add a Help panel
From the Toolbox, drag a Panel to the Home category. Then drag two Buttons to the panel.
Click the panel to modify its properties. Change Caption to
Help
.Click the first button. Change Caption to
Help Topics
, and ID toID_HELP_FINDER
.Click the second button. Change Caption to
About Scribble...
, and ID toID_APP_ABOUT
.Save the changes, and then build and run the application. A Help panel that contains two ribbon buttons should be displayed.
Important
When you click the Help Topics button, the Scribble application opens a compressed HTML (.chm) help file named your_project_name.chm. Consequently, if your project is not named Scribble, you must rename the help file to your project name.
Adding a Pen Panel to the Ribbon
Now, add a panel to display buttons that control the thickness and the color of the pen. This panel contains a check box that toggles between thick and thin pens. Its functionality resembles that of the Thick Line menu item in the Scribble application.
The original Scribble application lets the user select pen widths from a dialog box that appears when the user clicks Pen Widths on the menu. Because the ribbon bar has ample room for new controls, you can replace the dialog box by using two combo boxes on the ribbon. One combo box adjusts the width of the thin pen and the other combo box adjusts the width of the thick pen.
To add a Pen panel and combo boxes to the ribbon
From the Toolbox, drag a Panel to the Home category. Then drag a Check Box and two Combo Boxes to the panel.
Click the panel to modify its properties. Change Caption to
Pen
.Click the check box. Change Caption to
Use Thick
, and ID toID_PEN_THICK_OR_THIN
.Click the first combo box. Change Caption to
Thin Pen
, ID toID_PEN_THIN_WIDTH
, Type toDrop List
, Data to1;2;3;4;5;6;7;8;9;
, and Text to2
.Click the second combo box. Change Caption to
Thick Pen
, ID toID_PEN_THICK_WIDTH
, Type toDrop List
, Data to5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;
, and Text to5
.The new combo boxes don't correspond to any existing menu items, so you must create a menu item for every pen option.
In the Resource View window, open the IDR_SCRIBBTYPE menu resource.
Click Pen to open the pen menu. Then click Type Here and type
Thi&n Pen
.Right-click the text that you typed to open the Properties window, and then change the ID property to
ID_PEN_THIN_WIDTH
.Create an event handler for every pen menu item. Right-click the Thi&n Pen menu item that you created and then click Add Event Handler. The Event Handler Wizard is displayed.
In the Class list box in the wizard, select CScribbleDoc and then click Add and Edit. The command creates an event handler named
CScribbleDoc::OnPenThinWidth
.Add the following code to
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();
Next, create a menu item and event handlers for the thick pen.
In the Resource View window, open the IDR_SCRIBBTYPE menu resource.
Click Pen to open the pen menu. Then click Type Here and type
Thic&k Pen
.Right-click the text that you typed to display the Properties window. Change the ID property to
ID_PEN_THICK_WIDTH
.Right-click the Thick Pen menu item that you created and then click Add Event Handler. The Event Handler Wizard is displayed.
In the Class list box of the wizard, select CScribbleDoc and then click Add and Edit. The command creates an event handler named
CScribbleDoc::OnPenThickWidth
.Add the following code to
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();
Save the changes, and then build and run the application. New buttons and combo boxes should be displayed. Try using different pen widths to scribble.
Adding a Color Button to the Pen Panel
Next, add a CMFCRibbonColorButton object that lets the user scribble in color.
To add a color button to the Pen panel
Before you add the color button, create a menu item for it. In the Resource View window, open the IDR_SCRIBBTYPE menu resource. Click the Pen menu item to open the pen menu. Then click Type Here and type
&Color
. Right-click the text that you typed to display the Properties window. Change the ID toID_PEN_COLOR
.Now add the color button. From the Toolbox, drag a Color Button to the Pen panel.
Click the color button. Change Caption to
Color
, ID toID_PEN_COLOR
, Simple Look toTrue
, Large Image Index to1
, and Split Mode toFalse
.Save the changes, and then build and run the application. The new color button should be displayed on the Pen panel. However, it can't be used because it doesn't yet have an event handler. The next steps show how to add an event handler for the color button.
Adding a Color Member to the Document Class
Because the original Scribble application doesn't have color pens, you must write an implementation for them. To store the pen color of the document, add a new member to the document class, CscribbleDoc
.
To add a color member to the document class
In scribdoc.h, in the
CScribbleDoc
class, find the// Attributes
section. Add the following lines of code after the definition of them_nThickWidth
data member.// Current pen color COLORREF m_penColor;
Every document contains a list of stokes that the user has already drawn. Every stroke is defined by a
CStroke
object. TheCStroke
class doesn't include information about pen color, so you must modify the class. In scribdoc.h, in theCStroke
class, add the following lines of code after the definition of them_nPenWidth
data member.// Pen color for the stroke COLORREF m_penColor;
In scribdoc.h, add a new
CStroke
constructor whose parameters specify a width and color. Add the following line of code after theCStroke(UINT nPenWidth);
statement.CStroke(UINT nPenWidth, COLORREF penColor);
In scribdoc.cpp, add the implementation of the new
CStroke
constructor. Add the following code after the implementation of theCStroke::CStroke(UINT nPenWidth)
constructor.// 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(); }
Change the second line of the
CStroke::DrawStroke
method as follows.if (!penStroke.CreatePen(PS_SOLID, m_nPenWidth, m_penColor))
Set the default pen color for the document class. In scribdoc.cpp, add the following lines to
CScribbleDoc::InitDocument
, after them_nThickWidth = 5;
statement.// default pen color is black m_penColor = RGB(0, 0, 0);
In scribdoc.cpp, change the first line of the
CScribbleDoc::NewStroke
method to the following.CStroke* pStrokeItem = new CStroke(m_nPenWidth, m_penColor);
Change the last line of the
CScribbleDoc::ReplacePen
method to the following.m_penCur.CreatePen(PS_SOLID, m_nPenWidth, m_penColor);
You added the
m_penColor
member in a previous step. Now, create an event handler for the color button that sets the member.In the Resource View window, open the IDR_SCRIBBTYPE menu resource.
Right-click the Color menu item and click Add Event Handler. The Event Handler Wizard appears.
In the Class list box in the wizard, select CScribbleDoc and then click the Add and Edit button. The command creates the
CScribbleDoc::OnPenColor
event handler stub.
Replace the stub for the
CScribbleDoc::OnPenColor
event handler with the following code.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(); }
Save the changes and then build and run the application. You can now press the color button and change the pen's color.
Initializing Pens and Saving Preferences
Next, initialize the color and width of the pens. Finally, save and load a color drawing from a file.
To initialize controls on the ribbon bar
Initialize the pens on the ribbon bar.
Add the following code to scribdoc.cpp, in the
CScribbleDoc::InitDocument
method, after them_sizeDoc = CSize(200,200)
statement.// 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);
Save a color drawing to a file. Add the following statement to scribdoc.cpp, in the
CStroke::Serialize
method, after thear << (WORD)m_nPenWidth;
statement.ar << (COLORREF)m_penColor;
Finally, load a color drawing from a file. Add the following line of code, in the
CStroke::Serialize
method, after them_nPenWidth = w;
statement.ar >> m_penColor;
Now scribble in color and save your drawing to a file.
Conclusion
You've updated the MFC Scribble application. Use this walkthrough as a guide when you modify your existing applications.
See also
Walkthroughs
Walkthrough: Updating the MFC Scribble Application (Part 1)