Chapter 1. Tool Bar and Dialog Bar
3
1) Call CToolBar::SetBarStyle(…) to set the attributes of the tool bar. For example, by setting different
flags, we can let the tool bar have fixed or dynamic size. Besides this, we can also enable tool tips and
flybys for tool bar buttons.
1) To make the tool bar dockable, we need to call function CToolBar::EnableDocking(…) and pass
appropriate flags to it indicating which borders the tool bar could be docked (We can make the tool bar
dockable to all four borders, or only top border, bottom border, etc.)
1) To dock the tool bar, we need to call function CMainFrame::DockControlBar(…). If we have more than
one tool bar or dialog bar, this function should be called for each of them.
We need above five steps to implement a tool bar and set its attributes.
Message Mapping
Since tool bars are used to provide an alternate way of executing commands, we need to implement
message mapping for the controls contained in a tool bar. This will allow the message handlers to be called
automatically as the user clicks a tool bar button. The procedure of implementing message mapping for a
tool bar control is exactly the same with that of a menu item. In MFC, this is done through declaring an
afx_msg type member function and adding macros such as ON_COMMAND and ON_UPDATE_COMMAND_UI.
The message mapping could be implemented in any of the four default classes derived from CWinApp,
CFrameWnd, CView and CDocument. Throughout this book, we will implement most of the message
mappings in document. This is because for document/view structure, document is the center of the
application and should be used to store data. By executing commands within the document, we don’t bother
to obtain data from other classes from time to time.
The following lists necessary steps of implementing message mapping:
1) Declare afx_msg type member functions.
1) Implement these member functions for message handling.
1) Add message mapping macros between BEGIN_MESSAGE_MAP and END_MESSAGE_MAP (which are
generated by Application Wizard). We need to use ON_COMMAND macro to map WM_COMMAND message,
and use ON_UPDATE_COMMAND_UI macro to implement user interface updating. The message mapping
should have the following format:
BEGIN_MESSAGE_MAP(class name, base class name)
//{{AFX_MSG_MAP(class name)
ON_COMMAND(command ID, member function name)
ON_UPDATE_COMMAND_UI(command ID, member function name)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
Most of the time message mapping could be implemented through using Class Wizard. In this case we
only need to select a command ID and confirm the name of message handler. Although Class Wizard does
an excellent job in implementing message mapping, sometimes we still need to add it manually because
Class Wizard is not powerful enough to handle all cases.
Adding New Tool Bar Resource
Now that we understand how the default tool bar is implemented, it is easy for us to add extra tool
bars. We can declare CToolBar type variables in class CMainFrame, create tool bars and set their styles in
function CMainFrame::OnCreate(…). Then we can map tool bar command IDs to member functions so that
the commands can be executed by mouse clicking.
Sample 1.1-1\Bar and 1.1-2\Bar demonstrate the above procedure. In the two applications, apart from
the default tool bar, an extra tool bar that has four different buttons is added. Each button is painted with a
different color: red, green, blue and yellow. If we click on one of them, a message box will pop up telling
us the color of the button.
First we need to use Application Wizard to create a standard SDI application named “Bar”, leaving all
the settings as default. This will generate an application with a mainframe menu, a dockable tool bar and a
status bar. The default four class names are CBarApp, CMainFrame, CBarDoc, CBarView.