Home Index  | Back

New Page 1
Lesson 1 -Building Your First Windows Application

1.1 : Creating a Windows Application

1.2 : Creating a Dialog-Based Application

1.3 : Creating DLLs, Console Applications, and More

1.4 : Changing Your AppWizard Decisions
 1.5 : Understanding AppWizard’s Code
 1.6 : Understanding a MDI Application
 1.7 : Understanding the Components of a Dialog-Based Application

Lesson 2 - Dialogs and Controls

2.1 : Understanding Dialog Boxes

2.2 : Creating a Dialog Box Resource

 2.3 : Writing a Dialog Box Class
 2.4 : Using the Dialog Box Class
Lesson 3 - Messages and Commands

3.1 : Understanding Message Routing

3.2 : Understanding Message Loops

 3.3 : Reading Message Maps
 3.4 : Learning How ClassWizard Helps You Catch Messages
 3.5 : Recognizing Messages
 3.6 : Understanding Commands
 3.7 : Understanding Command Updates
 3.8 : Learning How ClassWizard Helps You Catch Commands and Command Updates

Lesson 4 - Documents and Views

4.1 : Understanding the Document Class

4.2 : Understanding the View Class

4.3 : Creating the Rectangles Application

 4.4 : Other View Classes

4.5 : Document Templates, Views, and Frame Windows

Lesson 5 - Drawing on the Screen

5.1 :Understanding Device Contexts

 5.2 : Introducing the Paint1 Application
 5.3 : Building the Paint1 Application
 5.4 : Scrolling Windows
 5.5 : Building the Scroll Application
Lesson 6 - Building a Complete Application: ShowString

6.1 : Building an Application That Displays a String

 6.2 : Building the ShowString Menus
 6.3 : Building the ShowString Dialog Boxes
 6.4 : Making the Menu Work
 6.5 : Making the Dialog Box Work
 6.6 : Adding Appearance Options to the Options Dialog Box
Lesson 7 -  Status Bars and Toolbars

7.1 : Working with Toolbars

 7.2 : Working with Status Bars
Lesson 8 - Common Controls

8.1 : The Progress Bar Control

 8.2 : The Up-Down Control
 8.3 : The Image List Control
 8.4 : The List View Control
 8.5 : The Tree View Control
 8.6 : The Rich Edit Control
 8.7 : The Date Picker Control
 8.8 : Month Calendar Control
 8.9 : Scrolling the View
Lesson 9 - Property Pages and Sheets

9.1 : Introducing Property Sheets

 9.2 : Creating the Property Sheet Demo Application
 9.3 : Running the Property Sheet Demo Application
Lesson 10 - ActiveX Concepts

10.1 : The Purpose of ActiveX

10.2 : Object Linking

10.3 : Object Embedding

 10.4 : Containers and Servers
 10.5 : Toward a More Intuitive User Interface
 10.6 : The Component Object Model  

10.7 : Automation

 10.8 : ActiveX Controls

Lesson 11 -  Building an ActiveX Control

11.1 : Creating a Rolling-Die Control

11.2 : Displaying the Current Value

11.3 : Reacting to a Mouse Click and Rolling the Die 

 11.4 : Creating a Better User Interface
 11.5 : Generating Property Sheets
Lesson 12 - Database Access

12.1 : Understanding Database Concepts

12.2 : Creating an ODBC Database Program

 12.3 : Choosing Between ODBC and DAO
 12.4 : OLE DB

Lesson -7:Status Bars and Toolbars

7.2- Working with Status Bars

Status bars are mostly benign objects that sit at the bottom of your application’s window, doing whatever MFC instructs them to do. This consists of displaying command descriptions and the status of various keys on the keyboard, including the Caps Lock and Scroll Lock keys. In fact, status bars are so mundane from the programmer’s point of view (at least they are in an AppWizard application) that they aren’t even represented by a resource that you can edit like a toolbar. When you tell AppWizard to incorporate a status bar into your application, there’s not much left for you to do.

Or is there? A status bar, just like a toolbar, must reflect the interface needs of your specific application. For that reason, the CStatusBar class features a set of methods with which you can customize the status bar’s appearance and operation. Table 7.2 lists the methods along with brief descriptions.

Table 7.2 Methods of the CStatusBar Class

Method  Description
CommandToIndex()

Obtains an indicator’s index, given its ID

Create()

Creates the status bar

GetItemID() Obtains an indicator’s ID, given its index
GetItemRect() Obtains an item’s display rectangle, given its index
GetPaneInfo()

Obtains information about an indicator.

GetPaneStyle() Obtains an indicator’s style.
GetPaneText() Obtains an indicator’s text
GetStatusBarCtrl()

Obtains a reference to the CStatusBarCtrl object represented by the CStatusBar object.

SetIndicators()

Sets the indicators’ IDs.

SetPaneInfo() Sets the indicators’ IDs, widths, and styles.
SetPaneStyle()

Sets an indicator’s style.

SetPaneText()

Sets an indicator’s text.

When you create a status bar as part of an AppWizard application, you see a window similar to that shown in Figure 7.9. (To make your own, create a project called Status and accept all the defaults, as you did for the Tool application.) The status bar has several parts, called panes, that display certain information about the status of the application and the system. These panes, which are marked in Figure 7.10, include indicators for the Caps Lock, Num Lock, and Scroll Lock keys, as well as a message area for showing status text and command descriptions. To see a command description, place your mouse pointer over a button on the toolbar (see Figure 7.10).

The most common way to customize a status bar is to add new panes. To add a pane to a status bar, complete these steps:

1. Create a command ID for the new pane.

2. Create a default string for the pane.

3. Add the pane’s command ID to the status bar’s indicators array.

4. Create a command-update handler for the pane.

The following sections cover these steps in detail.


FIG. 7.9 The default MFC status bar contains a number of informative panes.


FIG. 7.10 The message area is mainly used for command descriptions.

7.2.1 Creating a New Command ID

This step is easy, thanks to Visual C++’s symbol browser. To add the command ID, start by choosing View, Resource Symbols. When you do, you see the Resource Symbols dialog box (see Figure 7.11), which displays the currently defined symbols for your application’s resources. Click the New button, and the New Symbol dialog box appears. Type the new ID, ID_MYNEWPANE, into the Name box (see Figure 7.12). Usually, you can accept the value that MFC suggests for the ID.

FIG. 7.11 Use the Resource Symbols dialog box to add new command IDs to your application.


FIG. 7.12 Type the new ID’s name and value into the New Symbol dialog box.

Click the OK and Close buttons to finalize your selections, and your new command ID is defined.

7.2.2 Creating the Default String

You have now defined a resource ID, but it isn’t being used. To represent a status bar pane, the ID must have a default string defined for it. To define the string, first go to the ResourceView window (by clicking the ResourceView tab in the workspace pane) and double-click the String Table resource to open it in the string table editor, as shown in Figure 7.13.

Now, choose Insert, New String to open the String Properties dialog box. Type the new pane’s command ID ID_MYNEWPANE into the ID box (or choose it from the drop-down list) and the default string (Default string in this case) into the Caption box (see Figure 7.14).

7.2.3 Adding the ID to the Indicators Array

When MFC constructs your status bar, it uses an array of IDs to determine which panes to display and where to display them. This array of IDs is passed as an argument to the status bar’s SetIndicators() member function, which is called in the CMainFrame class’s OnCreate() function. You find this array of IDs, shown in Listing 7.3, near the top of the MainFrm.cpp file. One way to reach these lines in the source code editor is to switch to ClassView, expand CMainFrame, double-click OnCreate(), and scroll up one page. Alternatively, you could use FileView to open MainFrm.cpp and scroll down to this code.


FIG. 7.13 Define the new pane’s default string in the string table.


FIG. 7.14 Use the String Properties dialog box to define the new pane’s default string.

Listing 7.3 MainFrm.cpp—The Indicator Array

static UINT indicators[] =

{

ID_SEPARATOR, // status line indicator

ID_INDICATOR_CAPS,

ID_INDICATOR_NUM,

ID_INDICATOR_SCRL,

};

To add your new pane to the array, type the pane’s ID into the array at the position in which you want it to appear in the status bar, followed by a comma. (The first pane, ID_SEPARATOR, should always remain in the first position.) Listing 7.4 shows the indicator array with the new pane added.

Listing 7.4 MainFrm.cpp—The Expanded Indicator Array

static UINT indicators[] =

{

ID_SEPARATOR, // status line indicator

ID_MYNEWPANE,

ID_INDICATOR_CAPS,

ID_INDICATOR_NUM,

ID_INDICATOR_SCRL,

};

7.2.3 Creating the Pane’s Command-Update Handler

MFC doesn’t automatically enable new panes when it creates the status bar. Instead, you must create a command-update handler for the new pane and enable the pane yourself. Also, for most applications, the string displayed in the pane is calculated on-the-fly—the default string you defined in an earlier step is only a placeholder.

Normally, you use ClassWizard to arrange for messages to be caught, but ClassWizard doesn’t help you catch status bar messages. You must add the handler entries to the message map yourself and then add the code for the handler. You add entries to the message map in the header file and the map in the source file, and you add them outside the special AFX_MSG_MAP comments used by ClassWizard.

Double-click CMainFrame in ClassView to open the header file, and scroll to the bottom. Edit the message map so that it resembles Listing 7.5. When you write your own applications, you will use a variety of function names to update status bar panes, but the rest of the declaration will always be the same.

Listing 7.5 MainFrm.h—Message Map

// Generated message map functions

protected:

//{{AFX_MSG(CMainFrame)

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG

afx_msg void OnUpdateMyNewPane(CCmdUI *pCmdUI);

DECLARE_MESSAGE_MAP()

Next, you add the handler to the source message map to associate the command ID with the handler. Open any CMainFrame function and scroll upwards until you find the message map; then edit it so that it looks like Listing 7.6.

Listing 7.6 MainFrm.cpp—Message Map

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

//{{AFX_MSG_MAP(CMainFrame)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code !

ON_WM_CREATE()

//}}AFX_MSG_MAP

ON_UPDATE_COMMAND_UI(ID_MYNEWPANE, OnUpdateMyNewPane)

END_MESSAGE_MAP()

You have now arranged for the CMainFrame member function OnUpdateMyNewPane() to be called whenever the status bar pane ID_MYNEWPANE needs to be updated.

Now you’re ready to write the new command-update handler. In the handler, you will enable the new pane and set its contents. Listing 7.7 shows the command-update handler for the new pane; add this code to mainfrm.cpp. As you can see, it uses a member variable called m_paneString. Update handlers should be very quick—the job of making sure that m_paneString holds the right string should be tackled in a function that is called less often.

Listing 7.7 CMainFrame::OnUpdateMyNewPane()

void CMainFrame::OnUpdateMyNewPane(CCmdUI *pCmdUI)

{

pCmdUI->Enable();

pCmdUI->SetText(m_paneString);

}

7.2.4 Setting the Status Bar’s Appearance

To add the last touch to your status bar demonstration application, you will want a way to set m_paneString. To initialize it, double-click on the CMainFrame constructor to edit it, and add this line:

m_paneString = "Default string";

The value you entered in the string table is only to assure Visual Studio that the resource ID you created is in use. Right-click CMainFrame in ClassView and choose Add Member Variable to add m_paneString as a private member variable. The type should be CString.

To set up the status bar for the first time, add these lines to CMainFrame::OnCreate(), just before the return statement:

CClientDC dc(this);

SIZE size = dc.GetTextExtent(m_paneString);

int index = m_wndStatusBar.CommandToIndex(ID_MYNEWPANE);

m_wndStatusBar.SetPaneInfo(index,ID_MYNEWPANE, SBPS_POPOUT, size.cx);

These lines set the text string and the size of the pane. You set the size of the pane with a call to SetPaneInfo(), which needs the index of the pane and the new size. CommandToIndex() obtains the index of the pane, and GetTextExtent() obtains the size. As a nice touch, the call to SetPaneInfo() uses the SBPS_POPOUT style to create a pane that seems to stick out from the status bar, rather than be indented.

The user will change the string by making a menu selection. Open the IDR_STATUSTYPE menu in the resource editor and add a Change String item to the File menu. Let Developer Studio assign it the resource ID ID_FILE_CHANGESTRING.

Open ClassWizard and add a handler for this command; it should be caught by CMainFrame because that’s where the m_paneString variable is kept. ClassWizard offers to call the handler OnFileChangestring(), and you should accept this name. Click OK twice to close ClassWizard.

Insert a new dialog box into the application and call it IDD_PANEDLG. The title should be Change Pane String. Add a single edit box, stretched the full width of the dialog box, and leave the ID as IDC_EDIT1. Add a static text item just above the edit box with the caption New String:. With the dialog box open in the resource editor, open ClassWizard. Create a new class for the dialog box called CPaneDlg, and associate the edit control, IDC_EDIT1, with a CString member variable of the dialog class called m_paneString.

Switch to ClassView, expand CMainFrame, and double-click OnFileChangeString() to edit it. Add the code shown in Listing 7.8.

Listing 7.8 CMainFrame::OnFileChangestring()

void CMainFrame::OnFileChangestring()

{

CPaneDlg dialog(this);

dialog.m_paneString = m_paneString;

int result = dialog.DoModal();

if (result == IDOK)

{

m_paneString = dialog.m_paneString;

CClientDC dc(this);

SIZE size = dc.GetTextExtent(m_paneString);

int index = m_wndStatusBar.CommandToIndex(ID_MYNEWPANE);

m_wndStatusBar.SetPaneInfo(index,

ID_MYNEWPANE, SBPS_POPOUT, size.cx);

}

}

This code displays the dialog box, and, if the user exits the dialog box by clicking OK, changes the text string and resets the size of the pane. The code is very similar to the lines you added to OnCreate(). Scroll up to the top of MainFrm.cpp and add this line:

#include "panedlg.h"

This tells the compiler what the CPaneDlg class is. Build and run the Status application, and you should see the window shown in Figure 7.16. As you can see, the status bar contains an extra panel displaying the text Default string. If you choose File, Change String, a dialog box appears into which you can type a new string for the panel. When you exit the dialog box via the OK button, the text appears in the new panel, and the panel resizes itself to accommodate the new string (see Figure 7.17).


FIG. 7.15 The Status Bar Demo application shows how to add and manage a status bar panel.

 

Next>>
 
© Dewsoft Overseas