Visual C++ 6 Unleashed

Visual C++ 6 Unleashed

By MICKEY WILLIAMS and David Bennett

Working with Frames

Up to this point, you have learned that frames will contain your view windows, but you really haven't looked at what else frames can do. They can do quite a lot for your application. As you will see, frame windows provide the capability to use status bars, toolbars, and splitters. This applies to frame windows in general, regardless of whether you are using the document view architecture, although how this fits with the document view framework is mentioned where appropriate.

Status Bars

Many Windows applications provide useful information about the current state of the application in a status bar at the bottom of the application window. In this section, you will see how you can add this functionality to your own applications.

First, you need an object derived from the CStatusBar class. If you have created an MDI or SDI app using the MFC AppWizard, you should notice that m_wndStatusBar already has been added as a member of your main frame class. This is a good place to put the status bar object, because it needs to be around as long as the frame window is and should go away when the frame does. Your declaration should look something like this:

CStatusBar m_wndStatusBar;

Now that you have a CStatusBar object, creating the status bar window is a snap. You simply call the Create() function of CStatusBar, as in this example from the CMainFrame::OnCreate() implementation created by the MFC AppWizard:

        if (!m_wndStatusBar.Create(this) ||
                !m_wndStatusBar.SetIndicators(indicators,
                  sizeof(indicators)/sizeof(UINT)))
        {
            TRACE0("Failed to create status bar\n");
            return -1;      // fail to create
    }

The Create() function of CStatusBar takes a parent window parameter. Because Create() is called in the OnCreate() member of the frame, this is this. If the call to Create() is successful, SetIndicators() is called to load the text that will be used in the indicators on the right side of the status bar. This takes a pointer to an array of IDs (UINTs) and the number of elements in the array. The indicators array used in the example is defined like this:

static UINT indicators[] =
{
    ID_SEPARATOR,           // status line indicator
    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
    ID_INDICATOR_SCRL,
} ;

Each of the values in this array is the resource ID of a string resource that contains the text to be placed in the indicator box when it is toggled on. The first value, ID_SEPARATOR, is a special case. This is used to indicate that you want to use the first pane of the status bar for text—namely, the fly-by help strings that you define when creating menu items and toolbars.

Customizing the Status Bar

You can customize the status bar to display whatever information you want. To do this, begin by adding an entry in the indicators array that is passed to SetIndicators(). If you use 0 for the resource ID, no string will be found, and MFC will create an empty pane with which you can work.

Now you most likely will want to size the pane to fit the data you intend to put into it. To do this, first get some information about the current state of the status bar, then change the areas you care about, and update the status bar with the new settings:

m_wndStatusBar.GetPaneInfo(1, nID, nStyle, cxWidth);
m_wndStatusBar.SetPaneInfo(1, nID, nStyle, 50);

In this example, the first parameter is the index (0-based) of the pane. Here, a pane is added between the text area and the three indicators used by default. In addition, nID returns the resource ID of a string resource holding the text for the pane, nStyle returns the style bit settings of the pane, and cxWidth returns the width of the pane. You can modify any or all of these before calling SetPaneInfo(). In this case, you simply set the width to a size that is close to what you want. You now can add whatever text you want by using the following:

m_wndStatusBar.SetPaneText(1, "Hello");

In a real application, taking a guess at the size you want is probably not the best method. You might want to do something like the following example to set the size to exactly what you will need:

m_wndStatusBar.GetPaneInfo(1, nID, nStyle, nWidth);
pDC = m_wndStatusBar.GetDC();
pDC->SelectObject(m_wndStatusBar.GetFont());
pDC->DrawText(_T("Hello"), -1, myRect, DT_CALCRECT);
m_wndStatusBar.ReleaseDC(pDC);
m_wndStatusBar.SetPaneInfo(1, nID, nStyle, myRect.Width());
							

Adding a Toolbar

Chapter 1, "The Visual C++ 6.0 Environment," discusses how to create a toolbar resource. Now you will see how to make it work. First, you need an object derived from class CToolBar. If you asked for it, the MFC AppWizard has already created one for you (as well as the rest of the code you will see here); if not, you just need to add the following line to the declaration of your main frame class:

CToolBar m_wndToolBar;

The toolbar window is created by code like this from CMainFrame::OnCreate():

if (!m_wndToolBar.Create(this) ||
    !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
    TRACE0("Failed to create toolbar\n");
    return -1;      // fail to create
}

The call to LoadToolBar() takes the resource ID of a toolbar resource that you created in the Resource Editor (or that the MFC AppWizard created for you).

The Create() call also can take a DWORD with additional style information for the toolbar. This defaults to WS_CHILD|WS_VISIBLE|CBRS_TOP. You may add any of the styles listed in Table 4.2 to affect how your toolbar works.

Table 4.2. Toolbar Styles

Style Effect
CBRS_TOP Position toolbar at top of window.
CBRS_BOTTOM Position toolbar at bottom of window.
CBRS_NOALIGN Control bar is not repositioned when parent is resized.
CBRS_TOOLTIPS Enable ToolTips.
CBRS_SIZE_DYNAMIC Make control bar sizeable.
CBRS_SIZE_FIXED Make control bar a fixed size.
CBRS_FLOATING Create a floating toolbar.
CBRS_FLYBY Show fly-by help in the status bar.
CBRS_HIDE_INPLACE Toolbar is not displayed.
CBRS_BORDER_TOP Create a border for the toolbar on the top.
CBRS_BORDER_LEFT Create a border for the toolbar on the left.
CBRS_BORDER_RIGHT Create a border for the toolbar on the right.
CBRS_BORDER_BOTTOM Create a border for the toolbar on the bottom.

You also can modify these settings later with SetBarStyle(). This can be useful particularly if you want to add a certain feature, such as ToolTips or status bar fly-by help, as in this example, generated by the MFC AppWizard:

m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
    CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_DYNAMIC);

You should notice that neither ToolTips nor status bar fly-by help is included in the defaults for Create(). The strings for fly-by help and ToolTips are defined in a string resource with the same ID as the command generated by the button—fly-by text first, separated by a newline (\n):

"Recall last transaction\nRecall"

In addition, you can work with the styles of individual buttons with SetButtonStyle() and GetButtonStyle(), which use the styles in Table 4.3.

Table 4.3. Toolbar Button Styles

Style Effect
TBBS_CHECKED The button is down (checked).
TBBS_INDETERMINATE The button state is undetermined.
TBBS_DISABLED The button is disabled.
TBBS_PRESSED The button is pressed.
TBBS_CHECKBOX The button will be a toggle.

Floating and Docking Toolbars

If you want a floating toolbar, you can use the CFrameWnd::FloatControlBar() function, which requires a pointer to the toolbar, and a CPoint that dictates where the toolbar will float. In this example, the toolbar floats in the top-left corner:

FloatControlBar( &m_wndToolBar, CPoint(0,0));

Optionally, you can specify one of the following alignment styles as a third parameter to dictate the orientation of the toolbar.

If you want to dock your toolbar to the edges of the frame, you can use something like the following example generated by the MFC AppWizard:

m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);

Note that you must call EnableDocking() for both the toolbar and the frame window. You can enable docking only on certain edges of the frame by using a combination of the following docking flags:

The toolbar will dock only to those edges that are enabled for both the toolbar and the frame.

The DockControlBar() call tells the toolbar to dock itself. By default, the toolbar tries to dock to the top, left, bottom, and right sides of the frame, in that order. You can specify one of the following as a second parameter to dictate where the toolbar will dock:

Share ThisShare This

Informit Network