The Ex13a Example: Using Toolbars
In this example, we'll add three special-purpose buttons that control drawing in the view window. We'll also construct a Draw menu with three commands, as follows:
Command | Function |
---|---|
Circle | Draws a circle in the view window |
Square | Draws a square in the view window |
Pattern | Toggles a diagonal line fill pattern for new squares and circles |
The menu and toolbar choices force the user to alternate between drawing circles and squares. After the user draws a circle, the Circle command and toolbar button are disabled; after the user draws a square, the Square command and toolbar button are disabled.On the application's Draw menu, the Pattern command gets a check mark when pattern fill is active. On the toolbar, the corresponding button is a check box button that is down when pattern fill is active and up when it is not active.Figure 13-2 shows the application in action. The user has just drawn a square with pattern fill. Notice the states of the three drawing buttons.

Figure 13-2: The Ex13a program in action.
The Ex13a example introduces the resource editor for toolbars. You'll need to do very little C++ coding. Simply follow these steps:
Run the MFC Application Wizard to generate a project named Ex13a. Choose New Project from Visual Studio's File menu. In the New Project dialog box, select the MFC Application template, type the name Ex13a, and click OK. In the MFC Application Wizard, accept all the defaults but two: On the Application Type page, select Single Document, and on the Advanced Features page, deselect Printing And Print Preview.
Use the resource editor to edit the application's main menu. In Resource View, double-click on IDR_MAINFRAME under Menu. Edit the IDR_MAINFRAME menu resource to create a new Draw menu that looks like the following. To reposition a menu, you can just drag the menu.
In the Properties window, verify that the following properties are set for your new Draw menu commands:
Caption
ID
Prompt
&Circle
ID_DRAW_CIRCLE
Draw a circle\nCircle
&Square
ID_DRAW_SQUARE
Draw a square\nSquare
&Pattern
ID_DRAW_PATTERN
Change the pattern\nPattern
Use the resource editor to update the application's toolbar. Edit the IDR_MAINFRAME toolbar resource to create a group of three new buttons that looks like this:
The toolbar editor is fairly intuitive. You add new buttons by editing the blank button at the far right of the toolbar. Use the Ellipsis, Rectangle, and Line tools on the Image Editor toolbar to draw on a button. You can move buttons around by dragging them with the mouse. To add a separator between buttons, drag the button where the separator should appear slightly to the right or left and the buttons will be nudged over. The Delete key erases a button's pixels. If you want to eliminate a button entirely, just drag it off the toolbar.In the Properties window, set the ID property for the new buttons to ID_DRAW_CIRCLE, ID_DRAW_SQUARE, and ID_DRAW_PATTERN.
Add the CEx13aView class message handlers. Select the CEx13aView class in Class View, click the Events button in the Properties window, and add message handlers for the following command and update command user interface messages:
Object ID
Message
Member Function
ID_DRAW_CIRCLE
COMMAND
OnDrawCircle
ID_DRAW_CIRCLE
UPDATE_COMMAND_UI
OnUpdateDrawCircle
ID_DRAW_PATTERN
COMMAND
OnDrawPattern
ID_DRAW_PATTERN
UPDATE_COMMAND_UI
OnUpdateDrawPattern
ID_DRAW_SQUARE
COMMAND
OnDrawSquare
ID_DRAW_SQUARE
UPDATE_COMMAND_UI
OnUpdateDrawSquare
Add three data members to the CEx13aView class. Add the following code toEx13aView.h :
protected:
CRect m_rect;
BOOL m_bCircle;
BOOL m_bPattern;
Edit theEx13aView.cpp file. The CEx13aView constructor simply initializes the class data members. Add the following boldface code:
CEx13aView::CEx13aView() : m_rect(0, 0, 100, 100)
{
m_bCircle = TRUE;
m_bPattern = FALSE;
}
The OnDraw function draws an ellipse or a rectangle, depending on the value of the m_bCircle flag. The brush is plain white or a diagonal pattern, depending on the value of m_bPattern.void CEx13aView::OnDraw(CDC* pDC)
{
Cex13aDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CBrush brush(HS_BDIAGONAL, 0L); // brush with diagonal pattern
if (m_bPattern) {
pDC->SelectObject(&brush);
}
else {
pDC->SelectStockObject(WHITE_BRUSH);
}
if (m_bCircle) {
pDC->Ellipse(m_rect);
}
else {
pDC->Rectangle(m_rect);
}
pDC->SelectStockObject(WHITE_BRUSH); // Deselects brush
// if selected
}
The OnDrawCircle function handles the ID_DRAW_CIRCLE command message, and the OnDrawSquare function handles the ID_DRAW_SQUARE command message. These two functions move the drawing rectangle down and to the right, and then they invalidate the rectangle, causing the OnDraw function to redraw it. The effect of this invalidation strategy is a diagonal cascading of alternating squares and circles. Also, the display is not buffered, so when the window is hidden or minimized, previously drawn items are not redisplayed.void CEx13aView::OnDrawCircle()
{
m_bCircle = TRUE;
m_rect += CPoint(25, 25);
InvalidateRect(m_rect);
}
void CEx13aView::OnDrawSquare()
{
m_bCircle = FALSE;
m_rect += CPoint(25, 25);
InvalidateRect(m_rect);
}
The following two update command user interface functions alternately enable and disable the Circle and Square buttons and corresponding menu commands. Only one item can be enabled at a time.void CEx13aView::OnUpdateDrawCircle(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!m_bCircle);
}
void CEx13aView::OnUpdateDrawSquare(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bCircle);
}
The OnDrawPattern function toggles the state of the m_bPattern flag.void CEx13aView::OnDrawPattern()
{
m_bPattern ^= 1;
}
The OnUpdateDrawPattern function updates the Pattern button and menu command according to the state of the m_bPattern flag. The toolbar button appears to move in and out, and the command check mark appears and disappears.void CEx13aView::OnUpdateDrawPattern(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_bPattern);
}
Build and test the Ex13a application. Notice the behavior of the toolbar buttons. Try the corresponding menu commands, and notice that they too are enabled, disabled, and checked as the application's state changes. Observe the ToolTip and the prompt in the status bar when you stop the mouse pointer on one of the new toolbar buttons.