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 -12 : Database Access

12.2 - Creating an ODBC Database Program

Although creating a simple ODBC database program is easy with Visual C++, there are a number of steps you must complete:

1. Register the database with the system.

2. Use AppWizard to create the basic database application.

3. Add code to the basic application to implement features not automatically supported by AppWizard.

In the following sections, you will see how to perform these steps as you create the Employee application, which enables you to add, delete, update, sort, and view records in the Employees table of the sample Department Store database.

12.2.1 Registering the Database

Before you can create a database application, you must register the database that you want to access as a data source that you can access through the ODBC driver. Follow these steps to accomplish this important task:

1. Create a folder called Database on your hard disk and copy the file named DeptStore.mdb from this book’s Web site to the new Database folder. If you don’t have Web access, you can type the three tables into Microsoft Access. If you don’t have Access, you can use a different database program, but you will have to connect to the data source for that program.

The DeptStore.mdb file is a database created with Microsoft Access. You will use this database as the data source for the Employee application.

2. From the Windows Start menu, click Settings and then Control Panel. When the Control Panel dialog appears, double-click the 32-Bit ODBC icon. The ODBC Data Source Administrator dialog box appears, as shown in Figure 12.4.


FIG. 12.4 Connecting a data source to your application starts with the ODBC Data Source Administrator.

3. Click the Add button. The Create New Data Source dialog box appears. Select the Microsoft Access Driver from the list of drivers, as shown in Figure 12.5, and click Finish.

The Microsoft Access Driver is now the ODBC driver that will be associated with the data source you create for the Employee application.

FIG. 12.5 Creating a new data source is as simple as choosing Access from a list of drivers.

4. When the ODBC Microsoft Access 2000 Setup dialog box appears, enter Department Store in the Data Source Name text box and Department Store Sample in the Description text box, as shown in Figure 12.6.

The Data Source Name is a way of identifying the specific data source you’re creating. The Description field enables you to include more specific information about the data source.

FIG. 12.6 Name your data source whatever you like.

5. Click the Select button. The Select Database file selector appears. Use the selector to locate and select the DeptStore.mdb file (see Figure 12.7).


FIG. 12.7 Browse your way to the .mdb file that holds your data.

6. Click OK to finalize the database selection and then, in the ODBC Microsoft Access 2000 Setup dialog box, click OK to finalize the data-source creation process. Finally, click OK in the ODBC Data Source Administrator dialog box and close the Control Panel.

Your system is now set up to access the DeptStore.mdb database file with the Microsoft Access ODBC driver.

12.2.2 Creating the Basic Employee Application

Now that you have created and registered your data source, it’s time to create the basic Employee application. The steps that follow lead you through this process. After you complete these steps, you will have an application that can access and view the Employees table of the Department Store database:

1. Select File, New from Developer Studio’s menu bar. Click the Projects tab.

2. Select MFC AppWizard (exe) and type Employee in the Project Name box. The Step 1 dialog box appears.

3. Select Single Document to ensure that the Employee application doesn’t allow more than one window to be open at a time. Click Next.

4. Select the Database View Without File Support option, as shown in Figure 12.8, so that AppWizard will generate the classes you need in order to view the contents of a database. This application will not use any supplemental files besides the database, so it doesn’t need file (serializing) support. Click the Data Source button to connect the application to the data source you set up earlier.


FIG. 12.8 Arrange for a database view but no other file support.

5. In the Database Options dialog box, drop down the ODBC list and select the Department Store data source, as shown in Figure 12.9. Click OK.


FIG. 12.9 Choose the Department Store data source.

6. In the Select Database Tables dialog box, select the Employees table, as shown in Figure 12.10, and click OK. The Step 2 dialog box reappears, filled in as shown in Figure 12.11.

You’ve now associated the Employees table of the Department Store data source with the Employee application. Click Next to move to Step 3.

7. Accept the default (None) no compound document support and click Next. FIG. 12.10 Select which tables from the data source you want to use in this application.


FIG. 12.11 After selecting the data source, the Step 2 dialog box looks like this.

8. In the Step 4 dialog box, turn off the Printing and Print Preview option so that the dialog box resembles Figure 22.14. Click Next.


FIG. 12.12 Turn off print support.

9. Accept the defaults for Step 5 by clicking Next. In Step 6, click Finish to finalize your selections for the Employee application. Figure 12.13 shows the New Project Information dialog box that appears.

10. Click OK, and AppWizard creates the basic Employee application.

At this point, you can compile the application by clicking the Build button on Developer Studio’s toolbar, by selecting the Build, Build command from the menu bar, or by pressing F7 on your keyboard. After the program has compiled, select the Build, Execute command from the menu bar or press Ctrl+F5 to run the program. When you do, you see the window shown in Figure 12.14. You can use the database controls in the application’s toolbar to navigate from one record in the Employee table to another. However, nothing appears in the window because you’ve yet to associate controls with the fields in the table that you want to view. You will do that in the following section.

FIG. 12.13 The application summary mentions the data source as well as the usual information.


FIG. 12.14 The basic Employee application looks nice but doesn’t do much.

12.2.3 Creating the Database Display

The next step in creating the Employee database application is to modify the form that displays data in the application’s window. Because this form is just a special type of dialog box, it’s easy to modify with Developer Studio’s resource editor, as you will discover while completing the following steps:

1. In the workspace window, select the Resource View tab to display the application’s resources.

2. Open the resource tree by clicking + next to the Employee resources folder. Then, open the Dialog resource folder the same way. Double-click the IDD_EMPLOYEE_FORM dialog box ID to open the dialog box into the resource editor.

3. Click the static string in the center of the dialog box to select it, and then press the Delete key to remove the string from the dialog box.

4. Use the dialog box editor’s tools to create the dialog box, shown in Figure 12.16, by adding edit boxes and static labels. Give the edit boxes the following IDs: IDC_EMPLOYEE_ID, IDC_EMPLOYEE_NAME, IDC_EMPLOYEE_RATE, and IDC_EMPLOYEE_DEPT. Set the Read-Only style (found on the Styles page of the Edit Properties property sheet) of the IDC_EMPLOYEE_ID edit box.

Each of these edit boxes will represent a field of data in the database. The first edit box is read-only because it will hold the database’s primary key, which should never be modified.

5. Choose View, ClassWizard to open ClassWizard, and click the Member Variables tab.

6. With the IDC_EMPLOYEE_DEPT resource ID selected, click the Add Variable button. The Add Member Variable dialog box appears.

7. Click the arrow next to the Member Variable Name drop-down list and select m_pSet->m_DepartmentID, as shown in Figure 12.15. Leave the type as CString and click OK to add the variable.


FIG. 12.15 Connect the IDC_EMPLOYEE_DEPT control with the m_DepartmentID member variable of the recordset.

8. Associate other member variables (m_pSet->EmployeeID, m_pSet->EmployeeName, and m_pSet->salary with the edit controls in the same way. When you’re finished, the Member Variables page of the MFC ClassWizard property sheet will look like Figure 22.20.

By selecting member variables of the application’s CEmployeeSet class (derived from MFC’s CRecordset class) as member variables for the controls in Database view, you’re establishing a connection through which data can flow between the controls and the data source.

9. Click the OK button in the MFC ClassWizard property sheet to finalize your changes.

You’ve now created a data display form for the Employee application. Build and execute the program again, and you will see the window shown in Figure 12.16. Now the application displays the contents of records in the Employee database table. Use the database controls in the application’s toolbar to navigate from one record in the Employee table to another.

FIG. 12.16 The Employee application now displays data in its window.

After you’ve examined the database, try updating a record. To do this, simply change one of the record’s fields (except the employee ID, which is the table’s primary key and can’t be edited). When you move to another record, the application automatically updates the modified record. The commands in the application’s Record menu also enable you to navigate through the records in the same manner as the toolbar buttons.

Notice that you’ve created a sophisticated database-access program without writing a single line of C++ code—an amazing feat. Still, the Employee application is limited. For example, it can’t add or delete records. As you may have guessed, that’s the next piece of the database puzzle, which you will add.

12.2.4 Adding and Deleting Records

When you can add and delete records from a database table, you will have a full-featured program for manipulating a flat (that is, not a relational) database. In this case, the flat database is the Employees table of the Department Store relational database. Adding and deleting records in a database table is an easier process than you might believe, thanks to Visual C++’s CRecordView and CRecordSet classes, which provide all the member functions you need in order to accomplish these common database tasks. You will need to add some menu items to the application. Follow these steps to include add and delete commands in the Employee application:

1. Select the ResourceView tab, open the Menu folder, and double-click the IDR_MAINFRAME menu ID.

2. Click the Record menu item to open it, and click the blank menu item at the bottom of the menu. Choose View, Properties and pin the Menu Item Properties dialog box in place.

3. In the ID edit box, enter ID_RECORD_ADD and in the Caption box, enter &Add Record. This adds a new command to the Record menu.

4. In the next blank menu item, add a delete command with the ID ID_RECORD_DELETE and the caption &Delete Record.

Next, you will connect these commands to toolbar buttons, Follow these steps:

1. In the ResourceView pane, open the Toolbar folder and then double-click the IDR_MAINFRAME ID. The application’s toolbar appears in the resource editor.

2. Click the blank toolbar button to select it, and then use the editor’s tools to draw a red plus on the button.

3. Double-click the new button in the toolbar. The Toolbar Button Properties property sheet appears. Select ID_RECORD_ADD in the ID box to connect this button to the menu, as shown in Figure 22.24.

4. Select the blank button again and draw a red minus sign, giving the button the ID_RECORD_DELETE ID. Drag and drop the Add and Delete buttons to the left of the Help (question mark) button.

Now that you have added the menu items and the toolbar buttons, you need to arrange for code to catch the command message sent when the user clicks the button or chooses the menu item. Because it is the view that is connected to the database, the view will catch these messages. Follow these steps:

1. Open ClassWizard and select the Message Maps tab.


FIG. 12.17 Add a button and connect it to the menu item.

2. Set the Class Name box to CEmployeeView, click the ID_RECORD_ADD ID in the Object IDs box, and then double-click COMMAND in the Messages box. The Add Member Function dialog box appears, as shown in Figure 12.18.


FIG. 12.18 Add a function to catch the message.

3. Click the OK button to accept the default name for the new function. The function appears in the Member Functions box at the bottom of the ClassWizard dialog box.

4. Add a member function for the ID_RECORD_DELETE command in the same way.

5. Open the EmployeeView.h file by double-clicking CEmployeeView in the ClassView pane. In the Attributes section of the class’s declaration, add the following lines:

protected:

BOOL m_bAdding;

6. Double-click the CEmployeeView constructor in ClassView to edit it, and add this line at the bottom of the function:

m_bAdding = FALSE;

7. Double-click the OnRecordAdd() function and edit it so that it looks like Listing 12.1. This code is explained in the next section.

Listing 12.1 CEmployeeView::OnRecordAdd()

void CEmployeeView::OnRecordAdd()

{

m_pSet->AddNew();

m_bAdding = TRUE;

CEdit* pCtrl = (CEdit*)GetDlgItem(IDC_EMPLOYEE_ID);

int result = pCtrl->SetReadOnly(FALSE);

UpdateData(FALSE);

}

8. Right-click CEmployeeView in ClassView and choose Add Virtual Function. Select OnMove from the list on the left, as shown in Figure 12.19, and then click the Add and Edit button to add the function and to edit the skeleton code immediately.


FIG. 12.19 Override the OnMove() function.

9. Edit the OnMove() function so that it has the code in Listing 12.2. This code is explained in the next section.

Listing 12.2 CEmployeeView::OnMove()

BOOL CEmployeeView::OnMove(UINT nIDMoveCommand)

{

if (m_bAdding)

{

m_bAdding = FALSE;

UpdateData(TRUE);

if (m_pSet->CanUpdate())

m_pSet->Update();

m_pSet->Requery();

UpdateData(FALSE);

CEdit* pCtrl = (CEdit*)GetDlgItem(IDC_EMPLOYEE_ID);

pCtrl->SetReadOnly(TRUE);

return TRUE;

}

else

return CRecordView::OnMove(nIDMoveCommand);

}

10. Double-click the OnRecordDelete() function and edit it so that it looks like Listing 12.3. This code is explained in the next section.

Listing 12.3 CEmployeeView::OnRecordDelete()

void CEmployeeView::OnRecordDelete()

{

m_pSet->Delete();

m_pSet->MoveNext();

if (m_pSet->IsEOF())

m_pSet->MoveLast();

if (m_pSet->IsBOF())

m_pSet->SetFieldNull(NULL);

UpdateData(FALSE);

}

You’ve now modified the Employee application so that it can add and delete, as well as update, records. After compiling the application, run it by selecting the Build, Execute command from Developer Studio’s menu bar or by pressing Ctrl+F5. When you do, you see the Employee application’s main window, which doesn’t look any different than it did in the preceding section. Now, however, you can add new records by clicking the Add button on the toolbar (or by selecting the Record, Add Record command on the menu bar) and delete records by clicking the Delete button (or by clicking the Record, Delete Record command).

When you click the Add button, the application displays a blank record. Fill in the fields for the record; then when you move to another record, the application automatically updates the database with the new record. To delete a record, just click the Delete button. The current record (the one on the screen) vanishes and is replaced by the next record in the database.

12.2.5 Examining the OnRecordAdd() Function

You might be wondering how the C++ code you added to the application works. OnRecordAdd() starts with a call to the AddNew() member function of CEmployeeSet, the class derived from CRecordSet. This sets up a blank record for the user to fill in, but the new blank record doesn’t appear on the screen until the view window’s UpdateData() function is called. Before that happens, you have a few other things to tackle.

After the user has created a new record, the database will need to be updated. By setting a flag in this routine, the move routine will be able to determine whether the user is moving away from an ordinary database record or a newly added one. That’s why m_bAdding is set to TRUE here.

Now, because the user is entering a new record, it should be possible to change the contents of the Employee ID field, which is currently set to read-only. To change the read-only status of the control, the program first obtains a pointer to the control with GetDlgItem() and then calls the control’s SetReadOnly() member function to set the read-only attribute to FALSE.

Finally, the call to UpdateData() will display the new blank record.

12.2.6 Examining the OnMove() Function

Now that the user has a blank record on the screen, it’s a simple matter to fill in the edit controls with the necessary data. To add the new record to the database, the user must move to a new record, an action that forces a call to the view window’s OnMove() member function. Normally, OnMove() does nothing more than display the next record. Your override will save new records as well.

When OnMove() is called, the first thing the program does is check the Boolean variable m_bAdding to see whether the user is in the process of adding a new record. If m_bAdding is FALSE, the body of the if statement is skipped and the else clause is executed. In the else clause, the program calls the base class (CRecordView) version of OnMove(), which simply moves to the next record.

If m_bAdding is TRUE, the body of the if statement is executed. There, the program first resets the m_bAdding flag and then calls UpdateData() to transfer data out of the view window’s controls and into the recordset class. A call to the recordset’s CanUpdate() method determines whether it’s okay to update the data source, after which a call to the recordset’s Update() member function adds the new record to the data source.

To rebuild the recordset, the program must call the recordset’s Requery() member function, and then a call to the view window’s UpdateData() member function transfers new data to the window’s controls. Finally, the program sets the Employee ID field back to read-only, with another call to GetDlgItem() and SetReadOnly().

12.2.7 Examining the OnRecordDelete() Function

Deleting a record is simple. OnRecordDelete() just calls the recordset’s Delete() function. When the record is deleted, a call to the recordset’s MoveNext() arranges for the record that follows to be displayed.

A problem might arise, though, when the deleted record was in the last position or when the deleted record was the only record in the recordset. A call to the recordset’s IsEOF() function will determine whether the recordset was at the end. If the call to IsEOF() returns TRUE, the recordset needs to be repositioned on the last record. The recordset’s MoveLast() function takes care of this task.

When all records have been deleted from the recordset, the record pointer will be at the beginning of the set. The program can test for this situation by calling the recordset’s IsBOF() function. If this function returns TRUE, the program sets the current record’s fields to NULL.

Finally, the last task is to update the view window’s display with another call to UpdateData().

12.2.8 Sorting and Filtering

In many cases when you’re accessing a database, you want to change the order in which the records are presented, or you may even want to search for records that fit certain criteria. MFC’s ODBC database classes feature member functions that enable you to sort a set of records on any field. You can also call member functions to limit the records displayed to those whose fields contain given information, such as a specific name or ID. This latter operation is called filtering. In this section, you will add sorting and filtering to the Employee application. Just follow these steps:

1. Add a Sort menu to the application’s menu bar, as shown in Figure 12.20. Let Developer Studio set the command IDs.

FIG. 12.20 The Sort menu has four commands for sorting the database.

2. Use ClassWizard to arrange for CEmployeeView to catch the four new sorting commands, using the function names suggested by ClassWizard. Figure 12.21 shows the resultant ClassWizard property sheet.


FIG. 12.21 After you add the four new functions, ClassWizard looks like this.

3. Add a Filter menu to the application’s menu bar, as shown in Figure 12.22. Let Developer Studio set the command IDs.

4. Use ClassWizard to arrange for CEmployeeView to catch the four new filtering commands, using the function names suggested by ClassWizard.

5. Create a new dialog box by choosing Insert, Resource and double-clicking Dialog; then edit the dialog so that it resembles the dialog box shown in Figure 12.23. Give the edit control the ID IDC_FILTERVALUE. Give the entire dialog the ID IDD_FILTER.


FIG. 12.22 The Filter menu has four commands.


FIG. 12.23 Create a filter dialog box.

6. Start ClassWizard while the new dialog box is on the screen. The Adding a Class dialog box appears. Select the Create a New Class option and click OK.

7. The New Class dialog box appears. In the Name box, type CFilterDlg.Click OK to add the class.

8. Click ClassWizard’s Member Variables tab. Connect the IDC_FILTERVALUE control to a member variable called m_filterValue. Click the OK button to dismiss ClassWizard.

Now that the menus and dialogs have been created and connected to skeleton functions, it’s time to add some code to those functions. Double-click OnSortDepartment() in ClassView and edit it to look like Listing 12.4.

Listing 12.4 CEmployeeView::OnSortDepartment()

void CEmployeeView::OnSortDepartment()

{

m_pSet->Close();

m_pSet->m_strSort = "DeptID";

m_pSet->Open();

UpdateData(FALSE);

}

Double-click OnSortID() in ClassView and edit it to look like Listing 12.5. Double-click OnSortName() in ClassView and edit it to look like Listing 12.6. Double-click OnSortRate() in ClassView and edit it to look like Listing 12.7.

Listing 12.5 CEmployeeView::OnSortId()

void CEmployeeView::OnSortId()

{

m_pSet->Close();

m_pSet->m_strSort = "EmployeeID";

m_pSet->Open();

UpdateData(FALSE);

}

Listing 12.6 CEmployeeView::OnSortName()

void CEmployeeView::OnSortName()

{

m_pSet->Close();

m_pSet->m_strSort = "EmployeeName";

m_pSet->Open();

UpdateData(FALSE);

}

Listing 12.7 LST14_07.TXT: Code for the OnSortRate() Function

void CEmployeeView::OnSortRate()

{

m_pSet->Close();

m_pSet->m_strSort = "EmployeeRate";

m_pSet->Open();

UpdateData(FALSE);

}

At the top of EmployeeView.cpp, add the following line after the other #include directives:

#include "FilterDlg.h"

Edit OnFilterDepartment(), OnFilterID(), OnFilterName(), and OnFilterRate(), using Listing 12.8.

Listing 12.8 The Four Filtering Functions

void CEmployeeView::OnFilterDepartment()

{

DoFilter("DeptID");

}

void CEmployeeView::OnFilterId()

{

DoFilter("EmployeeID");

}

void CEmployeeView::OnFilterName()

{

DoFilter("EmployeeName");

}

void CEmployeeView::OnFilterRate()

{

DoFilter("EmployeeRate");

}

All four functions call DoFilter(). You will write this function to filter the database records represented by the recordset class. Right-click CEmployeeView in ClassView and choose Add Member Function. The Function Type is void, and the declaration is DoFilter(CString col). It’s a protected member function because it’s called only from other member functions of CEmployeeView. Click OK to close the Add Member Function dialog box. Add the code from Listing 12.9.

Listing 12.9 CEmployeeView::DoFilter()

void CEmployeeView::DoFilter(CString col)

{

CFilterDlg dlg;

int result = dlg.DoModal();

if (result == IDOK)

{

CString str = col + " = `" + dlg.m_filterValue + "`";

m_pSet->Close();

m_pSet->m_strFilter = str;

m_pSet->Open();

int recCount = m_pSet->GetRecordCount();

if (recCount == 0)

{

MessageBox("No matching records.");

m_pSet->Close();

m_pSet->m_strFilter = "";

m_pSet->Open();

}

UpdateData(FALSE);

}

}

You’ve now added the capability to sort and filter records in the employee database. Build the application and run it. When you do, the application’s main window appears, looking the same as before. Now, however, you can sort the records on any field, by selecting a field from the Sort menu. You can also filter the records by selecting a field from the Filter menu and then typing the filter string into the Filter dialog box that appears. You can tell how the records are sorted or filtered by moving through them one at a time. Try sorting by department or rate, for example. Then try filtering on one of the departments you saw scroll by.

12.2.9 Examining the OnSortDept() Function

All the sorting functions have the same structure. They close the recordset, set its m_strSort member variable, open it again, and then call UpdateData() to refresh the view with the values from the newly sorted recordset. You don’t see any calls to a member function with Sort in its name. Then when does the sort happen? When the recordset is reopened.

A CRecordset object (or any object of a class derived from CRecordset, such as this program’s CEmployeeSet object) uses a special string, called m_strSort, to determine how the records should be sorted. When the recordset is being created, the object checks this string and sorts the records accordingly.

12.2.10 Examining the DoFilter() Function

Whenever the user selects a command from the Filter menu, the framework calls the appropriate member function, either OnFilterDept(), OnFilterID(), OnFilterName(), or OnFilterRate(). Each of these functions does nothing more than call the local member function DoFilter() with a string representing the field on which to filter.

DoFilter() displays the same dialog box, no matter which filter menu item was chosen, by creating an instance of the dialog box class and calling its DoModal() function.

If result doesn’t equal IDOK, the user must have clicked Cancel: The entire if statement is skipped, and the DoFilter() function does nothing but return.

Inside the if statement, the function first creates the string that will be used to filter the database. Just as you set a string to sort the database, so, too, do you set a string to filter the database. In this case, the string is called m_strFilter. The string you use to filter the database must be in a form like this:

ColumnID = ‘ColumnValue’

The column ID was provided to DoFilter() as a CString parameter, and the value was provided by the user. If, for example, the user chooses to filter by department and types hardware in the filter value box, DoFilter() would set str to DeptID = ‘hardware’.

With the string constructed, the program is ready to filter the database. As with sorting, the recordset must first be closed; then DoFilter() sets the recordset’s filter string and reopens the recordset.

What happens when the given filter results in no records being selected? Good question. The DoFilter() function handles this by obtaining the number of records in the new recordset and comparing them to zero. If the recordset is empty, the program displays a message box telling the user of the problem. Then the program closes the recordset, resets the filter string to an empty string, and reopens the recordset. This restores the recordset to include all the records in the Employees table.

Finally, whether the filter resulted in a subset of records or the recordset had to be restored, the program must redisplay the data—by calling UpdateData(), as always.

 

Next>>
 
© Dewsoft Overseas