Adding a Status Bar and a Toolbar

[Previous] [Next]

At this point, our application looks pretty plain, so we'll add a toolbar and a status bar to spruce it up. To gain access to the Microsoft Windows common controls, link to the common controls DLL and then add an InitCommonControls call to WinMain. You can link to the controls using the following pragma in the main .cpp file:

 #pragma comment(lib, "comctl32.lib") 

ATL ships thin wrappers for most of the standard Windows controls as part of the ATLCON sample. If you haven't seen these control classes, definitely take a few minutes to browse the sample.

As of this writing, the classes in atlcontrols.h are not documented and are not supported by Microsoft.

To use the control classes, we need to include atlcontrols.h from the ATLCON sample and use the ATLControls namespace. To do this, copy atlcontrols.h into your project directory or set up an include path to the ATLCON sample directory in the Microsoft Visual C++ options. Include atlcontrols.h in mainframe.h and add the using statement for the new namespace right after the include statement, like this:

 #include "atlcontrols.h" using namespace ATLControls; 

The status bar class is implemented in CStatusBarCtrlT<base>. The class is designed to use CWindow as the base class, so atlcontrols.h provides a typedef for that common case, as shown here:

 typedef CStatusBarCtrlT<CWindow>    CStatusBarCtrl; 

We'll use the typedef and add a CStatusBarCtrl data member to CMainFrame. To create the status bar, add a WM_CREATE handler to CMainFrame by using the Wizard Bar. Click the Wizard Bar drop-down button, and choose Add Windows Message Handler. Adding a handler for WM_CREATE generates an empty OnCreate handler function, which we'll modify to create the status bar, as shown here:

 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam,     BOOL& bHandled) {     m_wndStatusBar.Create(m_hWnd, NULL, NULL, WS_CHILD |         WS_VISIBLE, ID_STATUS);     ATLASSERT(m_wndStatusBar.IsWindow());     m_wndStatusBar.SetSimple();     m_wndStatusBar.SetText(255, _T("Simple Status Bar"));     return 0; } 

We must position the status bar at the bottom of the frame window and resize the status bar whenever the frame is resized, so we'll add a WM_SIZE handler to CMainFrame. The code in OnSize simply needs to tell the status bar control to resize itself, which a status bar does by default when it gets a WM_SIZE message. The OnSize handler is shown here:

 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam,     BOOL& bHandled) {     m_wndStatusBar.SendMessage(WM_SIZE);     return 0; } 

The code for adding a toolbar is pretty much like straight SDK code. You have to build an array of TBBUTTON structures and add them to the toolbar control. In the ATL Scribble sample, we use one of the system toolbar bitmaps by calling LoadStdImages(IDB_STD_SMALL_COLOR). We map command IDs to toolbar buttons for ID_FILE_OPEN, ID_FILE_NEW, and ID_APP_ABOUT, which are handled in CMainFrame just like the menu commands. Toolbars automatically forward WM_COMMAND messages to their parent, so we get that for free. We'll add three toolbar buttons using the InitToolBar function shown here, which is called from CMainFrame::OnCreate:

 void InitToolbar() {     m_wndToolBar.Create(m_hWnd, NULL, NULL, WS_CHILD |         TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, ID_TOOLBAR);     m_wndToolBar.SetButtonStructSize(sizeof(TBBUTTON));     m_wndToolBar.LoadStdImages(IDB_STD_SMALL_COLOR);     TBBUTTON tbb[3];     ::ZeroMemory(tbb, sizeof(tbb));     tbb[0].iBitmap = STD_FILEOPEN;      tbb[0].idCommand = ID_FILE_OPEN;      tbb[0].fsState = TBSTATE_ENABLED;      tbb[0].fsStyle = TBSTYLE_BUTTON;     tbb[1].iBitmap = STD_FILENEW;      tbb[1].idCommand = ID_FILE_NEW;      tbb[1].fsState = TBSTATE_ENABLED;      tbb[1].fsStyle = TBSTYLE_BUTTON;     tbb[2].iBitmap = STD_HELP;      tbb[2].idCommand = ID_APP_ABOUT;      tbb[2].fsState = TBSTATE_ENABLED;      tbb[2].fsStyle = TBSTYLE_BUTTON;     m_wndToolBar.AddButtons(3, tbb);     m_wndToolBar.ShowWindow(SW_SHOW); } 

We also added matching menu commands for the File New and About buttons, and WM_COMMAND handlers for these buttons to the CMainFrame message map.

We'll want to provide ToolTips for our toolbar buttons as well, so we need to handle TTN_GETDISPINFO and supply ToolTip text in the handler. The message-map entry and handler are listed below.

 NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnTipInfo) LRESULT OnTipInfo(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) {     LPNMTTDISPINFO ptti = (LPNMTTDISPINFO)pnmh;     if(!(ptti->uFlags & TTF_IDISHWND))     {         ptti->hinst = _Module.GetResourceInstance();         ptti->lpszText = MAKEINTRESOURCE(ptti->hdr.idFrom);     }     return 0; } 

The handler assumes a string resource exists for each command ID on the toolbar.

Inside Atl
Inside ATL (Programming Languages/C)
ISBN: 1572318589
EAN: 2147483647
Year: 1998
Pages: 127 © 2008-2017.
If you may any questions please contact us: