Learning enroll routines

Source: Internet
Author: User
Tags dbase dsn
Learning enroll routines

Visual c ++ provides an example named enroll as a tutorial for learning MFC database programming. enroll is divided into four steps. The task in this section is to guide the reader to complete the enroll routine of the first three steps and thoroughly analyze it. by learning the three-step routine, you will learn how to use Appwizard and classwizard to create an MFC database application.

When learning the enroll routine, the reader may feel that it is easy to use Appwizard to create a database application. It seems that you do not have to learn the previous sections. it is true that Appwizard automatically adds a lot of database-related code to the application, greatly simplifying the development of database applications. however, Appwizard is not omnipotent, and its database applications cannot meet users' needs. what users really want to know is how to write their own database applications without relying on Appwizard. This is the purpose of this chapter. in fact, the analysis in the previous sections and the subsequent analysis of the enroll routine serve this purpose.

Before learning enroll, ask the reader to copy the first three steps of enroll (under the samples/mfc/tutorial/enroll directory) to the hard disk from the visual C ++ 5.0 CD, for reference. in addition, enroll needs to use the ACCESS database stdred32.mdb, which is in the stdreg routine of vc5.0 (under the samples/mfc/database/stdreg directory ), please copy this example to your hard disk.

10.7.1 register a data source

ODBC

The application cannot use the database directly. You must register the data source for the database you want to use. data Source registration is completed by the ODBC manager, which is located in the 32-bit ODBC on the Windows 95 control panel. now let's register the data source for the ACCESS database stdreg32.mdb.

Open the control panel and double-click the "32-bit ODBC" icon. An "ODBC data source Manager" is displayed, as shown in Figure 10.5. Select the "user DSN" page in the Manager. The user DSN is only visible to the user and can only be used on the current machine.

Figure 10.5 ODBC data source Manager

Click "add". A "create data source" dialog box is displayed. In this dialog box, select Microsoft Access Driver (*. mdb), and then click Finish. Next, an ODBC Microsoft Access 97 setup dialog box is displayed, as shown in 10.6. This dialog box is used to connect a database with a data source name. Enter student registration in the data source name: column, and click Select.... In the dialog box that appears, locate and select stdreg32.mdb. After two OK buttons are pressed, a new data source named student registry is registered to the manager.

Figure 10.6 ODBC Microsoft Access 97 setup dialog box

Tip: If you want to register a data source for the DBASE or FoxPro database, you should select a directory instead of a file as the data source. This is because in access, an MDB file can contain multiple tables, so it can be considered that an MDB file is a database. In DBASE or FoxPro, a dbf file can correspond to only one table. A database may contain several DBF Files. Therefore, you can think that a directory containing several DBF Files is a database.

10.7.2 first enroll version

Enroll

As shown in version 10.3 of the first version, this program has two basic functions: browsing record set and modification record. After the record in the form is modified, you can move it to a new record to save the modification to the original record. Note that the course and section edit boxes in the form are read-only, because the content of these two fields is important and cannot be modified at will. Enroll uses the Section Table of stdreg32.mdb, which is a curriculum, as shown in table 10.2.

Now let's build the enroll application. First, use Appwizard to establish the enroll program framework. follow these steps:

Start Appwizard and specify an MFC project named enroll.

In the first step of MFC Appwizard, select single document.

In step 2 of MFC Appwizard, select database view without file support, click the data source... button, and select the student registration data source in the ODBC combo box in the database Options dialog box, as shown in Figure 10.7. Then press the "OK" button to open a select database table dialog box, as shown in 10.8. In this dialog box, select the section table. Press OK to exit.

In step 6 of MFC Appwizard, change the class cenrollset to csewizset and the class cenrollview to csectionform.

Click Finish to create an enroll project.

Figure 10.7 database Options dialog box

Figure 10.8 select database table dialog box

Open the Class View of the workspace and you can find that Appwizard automatically creates a record set class csectionset and a record View class csectionform, which are the derived classes of crecordset and crecordview respectively. Appwizard also automatically creates domain data members for the csectionset class.

To open the workspace resource view, you can easily find a dialog box template with ID idd_enroll_form. This template is used by the record view to display the form. Clear all controls in the template, expand the size of the template to 183 × 110, and place the controls as shown in Figure 10.3. Here we can adopt a lazy method: Open the resource file of the first version of enroll (enroll. RC), find and open the template in the idd_enroll_form dialog box, press and hold the ctrl key, select all controls in the template, and then press Ctrl + insert to copy the selected controls. Switch to your idd_enroll_form dialog box template, and press SHIFT + insert to paste the copied control to the template.

The next task is to use classwizard to connect the controls in the form with the domain data members of the record set to exchange the control with the DDX data of the current record. Follow these steps:

Go to classwizard, select the member variables page, and select the csectionform class.

Double-click idc_capacity in the Variable list to display the Add member variable dialog box. Note that the member variable name column of the dialog box displays a combox instead of the edit box that you normally see. 10.9, select m_pset-> m_capacity In the combo box list. Click OK.

Follow Step 1 to connect the domain data members of the record set for other controls. It is not difficult to determine the corresponding domain data member based on the control ID.

Figure 10.9 add member variable dialog box

 

You can find the following line in the definition of the csectionform class:

Csectionset * m_pset;

It can be seen that m_pset is a member of the csectionform class and points to a csectionset object. Classwizard can be used to connect controls with "external data" such as record sets. This is a special application of classwizard in database programming.

Compile and run enroll, and the reader will be surprised to find that enroll is a very good record browser, and users can modify the records.

Now, let's analyze what Appwizard and classwizard have done for enroll.

In the definition of cenrolldoc, there is a line as follows:

Csectionset m_sectionset;

The Appwizard embedded a csewizset object in the cenrolldoc class. This is equivalent to calling the constructor csectionset (null). The csectionset class constructor declaration is as follows:
Csectionset (cdatabase * pdatabase = NULL );

Function definitions are listed in listing 10.5. It can be seen that the constructor calls the constructor of the base class and initializes the domain data members. Through 10.5.4, we know that if the null parameter is passed to the constructor of the crecordset, The crecordset: OPEN function will automatically build a cdatabase object, and according to the crecordset :: the connection string returned by getdefaconnect connect establishes a connection with the data source. Csectionset provides a new version of the virtual function getdefaconnect connect, as shown in listing 10.6. The function provides the data source student registration.

 

List

10.5 csectionset Constructor

Csectionset: csectionset (cdatabase * PDB)

: Crecordset (PDB)

{

// {Afx_field_init (csectionset)

M_courseid = _ T ("");

M_sectionno = _ T ("");

M_instructorid = _ T ("");

M_roomno = _ T ("");

M_schedule = _ T ("");

M_capacity = 0;

M_nfields = 6;

//} Afx_field_init

M_ndefaulttype = snapshot;

}

 

 

List

10.6 getdefaconnect connect function of the derived class

Cstring csectionset: getdefaconnect connect ()

{

Return _ T ("ODBC; DSN = student registration ");

}

 

 

As for the establishment of the record set, it is actually completed in crecordview: oninitialupdate. This part of code is transparent to users and is listed here in listing 10.7. Call crecordset: open in this function to create a record set. The ongetrecordset function is called at the beginning of the function to obtain the record set object connected to the record view. Csectionform provides a new version of the virtual function ongetrecordset, as shown in listing 10.8, which submits m_pset to the caller. M_pset Initialization is completed in the csectionform: oninitialupdate function, as shown in listing 10.9.

 

List

10.7 crecordview: oninitialupdate Function

Void crecordview: oninitialupdate ()

{

Crecordset * precordset = ongetrecordset ();

// Recordset must be allocated already

Assert (precordset! = NULL );

 

If (! Precordset-> isopen ())

{

Cwaitcursor wait;

Precordset-> open ();

}

 

Cformview: oninitialupdate ();

}

 

 

List

10.8 ongetrecordset function of the derived class

Crecordset * csectionform: ongetrecordset ()

{

Return m_pset;

}

 

 

 

List

10.9 oninitialupdate function of the derived class

Void csectionform: oninitialupdate ()

{

M_pset = & getdocument ()-> m_sectionset;

Crecordview: oninitialupdate ();

}

 

 

 

Note that no parameters are provided when crecordset: open is called in crecordview: oninitialupdate, which means that the open function will obtain SQL information from crecordset: getdefasql SQL. Csectionset provides a new version of the virtual function getdefasql SQL. As shown in listing 10.10, this function returns the "section" table name.

 

List

10.10 getdefasql SQL function of the derived class

Cstring csectionset: getdefasql SQL ()

{

Return _ T ("[section]");

}

 

 

 

For the record scrolling and modification implementation, see 10.6. The Code related to DDX and DFX is listed in listing 10.3 and 10.2.

If you still do not understand the above analysis, read the previous sections of this chapter carefully.

 

10.7.3 enroll Version 2

Enroll

The second version shows the reader how to use two associated record sets in a record view, as well as the record filtering and sorting technology. This version makes the reader truly come into contact with the relational database. This section also describes how to use classwizard to create a record set class and how to parameterize a record set.

You can run the enroll example provided by VC 5.0 in step 2. The enroll interface has changed. The original course edit box is replaced with a combo box, as shown in Figure 10.10. The content in the combo box comes from the courseid field of the Course table of the same data source.

Figure 10.10 second enroll version

 

Course

Table content is shown in Table 10.5. Compared with table 10.2, you can find that the course table and section table have a common field courseid. The record view program uses this public field to associate two tables. For example, if you select math202 in the course combo box, the program Selects all records whose courseid is math202 in the section table and creates a new record set.

In fact, most tables in stdreg32.mdb share courseid. In the Course table of the master table, the courseid of each record is unique and we call it the primary key ). In course related tables, courseid is not necessarily unique. For example, in section tables, courseid is called a foreign key ). You can use keywords to associate multiple tables. Such a database is a relational database. Sectionno is also a keyword. In the section table, the sectioinno field is the primary keyword and its value is unique.

 

Table

10.5 Course table


Courseid (text)


Coursetitle (text)


Hours (INT)

Math101

Algebra

4

Math201

Calculus I

4

Math202

Calculus II

4

 

 

Now let's start creating a new version based on the previous section enroll. If the current project is not enroll, ask the reader to open the enroll project created in the previous section.

First, replace the course edit box with a combo box, which includes the following steps:

Open the template in the idd_enroll_form dialog box and delete the course edit box.

Add a combox to the original edit box. Open the Properties dialog box of the control, set its ID to idc_courselist, and select drop list on the styles page. Adjust the size of the drop-down list of the combo box (click the down arrow to expand its size ).

From top to bottom, the new tab order is arranged.

 

Next we will use classwizard to do some work related to the newly added combo box:

Go to classwizard, select the member variables page, and select the csectionform class. Click the idc_course item in the list and press delete to delete the item. Double-click the idc_courselist item and select m_pset-> m_courseid In the combo box of the add member variable dialog box.

Double-click idc_courselist again and add a ccombobox member named m_ctlcourselist to the csectionform class.

Select the message maps page and add the cbn_selendok notification message processing function to the idc_courselist combo box. The function name is onselendokcourselist. This function is used to respond to user-selected changes in the combo box.

Press OK to exit classwizard.

 

Next, you need to create a record set class named ccourseset for the Course table, which can be completed by classwizard. Please follow these steps:

Go to classwizard and click Add class... in the pop-up menu, select new ..., enter ccourseset in the name column of the create new class dialog box, select crecordset in the base class column, and click Create.

In the pop-up database Options dialog box, select the student registration data source in the ODBC combo box. Then press OK.

In the displayed select database tables dialog box, select the Course table. Press OK to confirm.

 

Looking at the new ccourseset class, the reader will find that classwizard automatically creates a domain data member corresponding to the fields in the Course table for the ccourseset class, and establishes the dofieldexchange function. Classwizard also provides new getdefaconnect connect and getdefasql SQL functions for the record set class.

Then, in the cenrolldoc class definition, add the following line to the m_sectionset member:

Ccourseset m_courseset;

In this way, cenrolldoc contains two record sets. Because the cenrolldoc class uses the ccourseset class, it must be included in all the # include "enroldoc. h "in the CPP file of the statement, in # include" enroldoc. h. These CPP files include the CPP files of the cenrollapp, csectionform, and cenrolldoc classes.

# Include "courseset. H"

In the definition of the csectionset class, add the following line to the field data member outside the "//} afx_field" comment.

Cstring m_strcourseidparam;

M_strcourseidparam is a parameter data member of the record set. Its role will be described later.

 

Finally, you can modify the program according to the configuration 10.11 and 10.12. Listing 10.11 lists part of the source code of the csectionset class, and listing 10.12 lists part of the code of the csectionform class.

 

Listing 10.11 code of the csectionset class

Csectionset: csectionset (cdatabase * PDB)

: Crecordset (PDB)

{

...

M_nparams = 1; // only one parameter data member exists.

M_strcourseidparam = "";

}

 

Void csectionset: dofieldexchange (cfieldexchange * pfx)

{

...

Pfx-> setfieldtype (cfieldexchange: Param );

Rfx_text (pfx, "courseidparam", m_strcourseidparam); // Replace the Parameter

}

 

 

Listing 10.12 code of the csectionform class

Void csectionform: oninitialupdate ()

{

M_pset = & getdocument ()-> m_sectionset;

 

 

Cenrolldoc * pdoc = getdocument ();

Pdoc-> m_courseset.m_strsort = "courseid ";

If (! Pdoc-> m_courseset.open ())

Return;

 

M_pset-> m_strfilter = "courseid =? "; // Use parameters

M_pset-> m_strcourseidparam = pdoc-> m_courseset.m_courseid;

M_pset-> m_strsort = "sectionno ";

M_pset-> m_pdatabase = pdoc-> m_courseset.m_pdatabase; // share cdatabase

 

Crecordview: oninitialupdate ();

 

 

M_ctlcourselist.resetcontent ();

If (pdoc-> m_courseset.isopen ())

{

While (! Pdoc-> m_courseset.iseof ())

{

M_ctlcourselist.addstring (

Pdoc-> m_courseset.m_courseid); // Add the courseid field to the table

Pdoc-> m_courseset.movenext ();

}

}

M_ctlcourselist.setcursel (0 );

}

 

Void csectionform: onselendokcourselist ()

{

 

If (! M_pset-> isopen ())

Return;

M_ctlcourselist.getlbtext (m_ctlcourselist.getcursel (),

M_pset-> m_strcourseidparam );

M_pset-> requery (); // re-Query

If (m_pset-> iseof ())

{

M_pset-> setfieldnull (& (m_pset-> m_courseid), false );

M_pset-> m_courseid = m_pset-> m_strcourseidparam;

}

Updatedata (false );

}

 

At the beginning of the csectionform: oninitialupdate function, the crecordset: OPEN function is called to create a ccourseset record set. Before the OPEN function is called, the set of records sorted by the courseid field is specified. Some of the causes and consequences of calling open functions have been explained before. It is not difficult for readers to analyze them. Readers may not be able to understand the following code. Why is there a "?" In the m_strfilter filter string of the record set? No.

This is because the "parameterized record set" technology is used in this example. In m_strfilter and m_strsort of the record set, you can use "?" ID is used as a parameter, which makes it more flexible to specify the filter and sort. For example, in the oninitialupdate function, the filter is specified as follows:

M_pset-> m_strfilter = "courseid =? ";

When calling open or requery, "?" It will be replaced by the content in csectionset: m_strcourseidparam. For example, if m_strcourseidparam is specified as "math101", m_strfilter is changed to "courseid = math101 ". In this way, you can customize the filter by specifying m_strcourseidparam. A member like m_strcourseidparam is called a parameter data member. Like a domain data member, it is unique to a record set. Classwizard does not support parameter data members. Users can only manually add them, and their names are determined by the user.

The parameter replacement is actually completed by the rfx function in csectionset: dofieldexchange. At the end of the dofieldexchange function, we add the following two rows:

Pfx-> setfieldtype (cfieldexchange: Param );

Rfx_text (pfx, "courseidparam", m_strcourseidparam );

Dofieldexchange can identify domain data members and parameter data members. The first line is used to indicate that the subsequent rfx function is used to replace parameters. The second row is an rfx function used for the m_strcourseidparam parameter. The name of the second rfx parameter can be determined by the user. Here, it is specified as "courseidparam ".

You can use one or more parameters in m_strfilter and m_strsort. When there are multiple parameters, note that the call order of the rfx function should correspond to the order in which the parameters appear. The Framework stipulates that you should first arrange parameters in m_strfilter and then m_strsort.

Crecordset has two data members: m_nfields and m_nparams, which are used to calculate the number of domain data members and parameter data members respectively. The former is automatically counted by classwizard, and the latter must be maintained by users. In the csectionset constructor, m_nparams is set to 1 because there is only one parameter data member.

Now let's continue to study oninitialupdate. Before oninitialupdate of the base class is called, there is a line of code in the program:

M_pset-> m_pdatabase = pdoc-> m_courseset.m_pdatabase;

M_pdatabase is a public member of the crecordset, which is a pointer to the cdatabase object. If the application uses more than two Record Sets, by default, each record set creates a cdatabase object representing the same data source (see 10.5.4), which is obviously unnecessary. The preceding Code enables the csectionset record set to share the cdatabase object created by the ccourseset record set. In this way, when crecordset: oninitialupdate is called to open the csectionset record set, no cdatabase will be created

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.