In this example, you will replace the standard application framework Edit Cut, Copy, and Paste toolbar buttons with three special-purpose buttons that control drawing in the view window. You will also construct a Draw menu with three corresponding menu items, as follows.
Menu Item | 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 options force the user to alternate between drawing circles and squares. After the user draws a circle, the Circle menu item and toolbar button are disabled; after the user draws a square, the Square menu item and toolbar button are disabled.
On the application's Draw menu, the Pattern menu item 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 14-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 14-2. The EX14A program in action.
The EX14A example introduces the resource editor for toolbars. You'll need to do very little C++ coding. Simply follow these steps:
Use the following command IDs for your new menu items.
Menu | Caption | Command ID |
Draw | Circle | ID_DRAW_CIRCLE |
Draw | Square | ID_DRAW_SQUARE |
Draw | Pattern | ID_DRAW_PATTERN |
When you're in the Menu Item Properties dialog, add some appropriate prompt strings and ToolTips (following a newline character). The string for ID_DRAW_CIRCLE might be "Draw a circle\nCircle."
You'll be erasing the Edit Cut, Copy, and Paste tiles (fourth, fifth, and sixth from the left) and replacing them with new tiles. The toolbar editor is fairly intuitive. You simply move the buttons around with the mouse. The Delete key erases a button's pixels. If you want to eliminate a button entirely, just drag it off the toolbar. Use the rectangle and ellipse tools from the graphics toolbar. Experiment with different line widths. Save the resource file when you're donejust in case.
Assign the IDs ID_DRAW_CIRCLE, ID_DRAW_SQUARE, and ID_DRAW_PATTERN to the three new buttons.
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 |
private: CRect m_rect; BOOL m_bCircle; BOOL m_bPattern;
CEx14aView::CEx14aView() : 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 CEx14aView::OnDraw(CDC* pDC) { 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 CEx14aView::OnDrawCircle() { m_bCircle = TRUE; m_rect += CPoint(25, 25); InvalidateRect(m_rect); } void CEx14aView::OnDrawSquare() { m_bCircle = FALSE; m_rect += CPoint(25, 25); InvalidateRect(m_rect); }
The following two update command UI functions alternately enable and disable the Circle and Square buttons and corresponding menu items. Only one item can be enabled at a time.
void CEx14aView::OnUpdateDrawCircle(CCmdUI* pCmdUI) { pCmdUI->Enable(!m_bCircle); } void CEx14aView::OnUpdateDrawSquare(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bCircle); }
The OnDrawPattern function toggles the state of the m_bPattern flag.
void CEx14aView::OnDrawPattern() { m_bPattern ^= 1; }
The OnUpdateDrawPattern function updates the Pattern button and menu item according to the state of the m_bPattern flag. The toolbar button appears to move in and out, and the menu item check mark appears and disappears.
void CEx14aView::OnUpdateDrawPattern(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bPattern); }