⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch22.htm

📁 Using Visual C++ 6.0 一本关于Visual C++ 6.0基本编程应用的书籍。
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<P><A HREF="javascript:popUp('22uvc33.gif')"><B>FIG. 22.33</B></A><B> </B><I>Create
a dialog class for the Filter dialog box.</I></P>
<P>

<DL>
	<DD><B>8.</B> 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.
	<P>
</DL>

<P>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 22.4.</P>
<P>
<H4>Listing 22.4&#160;&#160;CEmployeeView::OnSortDepartment()</H4>
<PRE>void CEmployeeView::OnSortDepartment()
{
        m_pSet-&gt;Close();
        m_pSet-&gt;m_strSort = &quot;DeptID&quot;;
        m_pSet-&gt;Open();
        UpdateData(FALSE);
</PRE>
<PRE>}
</PRE>
<P>Double-click OnSortID() in ClassView and edit it to look like Listing 22.5. Double-click
OnSortName() in ClassView and edit it to look like Listing 22.6. Double-click OnSortRate()
in ClassView and edit it to look like Listing 22.7.</P>
<P>
<H4>Listing 22.5&#160;&#160;CEmployeeView::OnSortId()</H4>
<PRE>void CEmployeeView::OnSortId()
{
        m_pSet-&gt;Close();
        m_pSet-&gt;m_strSort = &quot;EmployeeID&quot;;
        m_pSet-&gt;Open();
        UpdateData(FALSE);
</PRE>
<PRE>}
</PRE>
<H4>Listing 22.6&#160;&#160;CEmployeeView::OnSortName()</H4>
<PRE>void CEmployeeView::OnSortName()
{
        m_pSet-&gt;Close();
        m_pSet-&gt;m_strSort = &quot;EmployeeName&quot;;
        m_pSet-&gt;Open();
        UpdateData(FALSE);
</PRE>
<PRE>}
</PRE>
<H4>Listing 22.7&#160;&#160;LST14_07.TXT: Code for the OnSortRate() Function</H4>
<PRE>void CEmployeeView::OnSortRate()
{
        m_pSet-&gt;Close();
        m_pSet-&gt;m_strSort = &quot;EmployeeRate&quot;;
        m_pSet-&gt;Open();
        UpdateData(FALSE);
</PRE>
<PRE>}
</PRE>
<P>At the top of EmployeeView.cpp, add the following line after the other #include
directives:</P>
<P>
<PRE>#include &quot;FilterDlg.h&quot;
</PRE>
<P>Edit OnFilterDepartment(), OnFilterID(), OnFilterName(), and OnFilterRate(), using
Listing 22.8.</P>
<P>
<H4>Listing 22.8&#160;&#160;The Four Filtering Functions</H4>
<PRE>void CEmployeeView::OnFilterDepartment()
{
        DoFilter(&quot;DeptID&quot;);
}
void CEmployeeView::OnFilterId()
{
        DoFilter(&quot;EmployeeID&quot;);
}
void CEmployeeView::OnFilterName()
{
        DoFilter(&quot;EmployeeName&quot;);
}
void CEmployeeView::OnFilterRate()
{
        DoFilter(&quot;EmployeeRate&quot;);
</PRE>
<PRE>}
</PRE>
<P>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 22.9.</P>
<P>
<H4>Listing 22.9&#160;&#160;CEmployeeView::DoFilter()</H4>
<PRE>void CEmployeeView::DoFilter(CString col)
{
    CFilterDlg dlg;
    int result = dlg.DoModal();
    
    if (result == IDOK)
    {
        CString str = col + &quot; = `&quot; + dlg.m_filterValue + &quot;`&quot;;
        m_pSet-&gt;Close();
        m_pSet-&gt;m_strFilter = str;
        m_pSet-&gt;Open();
        int recCount = m_pSet-&gt;GetRecordCount();
        
        if (recCount == 0)
        {
            MessageBox(&quot;No matching records.&quot;);
            m_pSet-&gt;Close();
            m_pSet-&gt;m_strFilter = &quot;&quot;;
            m_pSet-&gt;Open();
        }
        UpdateData(FALSE);
    }
</PRE>
<PRE>}
</PRE>
<P>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.</P>
<P>
<H3><A NAME="Heading15"></A>Examining the OnSortDept() Function</H3>
<P>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.</P>
<P>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.</P>
<P>
<H3><A NAME="Heading16"></A>Examining the DoFilter() Function</H3>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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:</P>
<P>
<PRE><I>ColumnID</I> = <I>`ColumnValue'</I>
</PRE>
<P>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 <B>hardware</B> in the filter value box, DoFilter() would set str to DeptID
= `hardware'.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>
<H2><A NAME="Heading17"></A>Choosing Between ODBC and DAO</H2>
<P>In the preceding section, you read an introduction to Visual C++'s ODBC classes
and how they're used in an AppWizard-generated application. Visual C++ also features
a complete set of DAO classes that you can use to create database applications. DAO
is, in many ways, almost a superset of the ODBC classes, containing most of the functionality
of the ODBC classes and adding a great deal of its own. Unfortunately, although DAO
can read ODBC data sources for which ODBC drivers are available, it's not particularly
efficient at the task. For this reason, the DAO classes are best suited for programming
applications that manipulate Microsoft's .mdb database files, which are created by
Microsoft Access. Other file formats that DAO can read directly are those created
by Fox Pro and Excel. If you are writing an application that uses an Access database
and always will, you might want to use DAO for its extra functionality. If, as is
more likely, your application uses another database format now or will move to another
format in the future, use ODBC instead.</P>
<P>The DAO classes, which use the Microsoft Jet Database Engine, are so much like
the ODBC classes that you can often convert an ODBC program to DAO simply by changing
the classnames in the program: CDatabase becomes CDaoDatabase, CRecordset becomes
CDaoRecordset, and CRecordView becomes CDaoRecordView. One big difference between
ODBC and DAO, however, is the way in which the system implements the libraries. ODBC
is implemented as a set of DLLs, whereas DAO is implemented as COM objects. Using
COM objects makes DAO a bit more up to date, at least as far as architecture goes,
than ODBC.</P>
<P>Although DAO is implemented as COM objects, you don't have to worry about directly
dealing with those objects. The MFC DAO classes handle all the details for you, providing
data and function members that interact with the COM objects. The CDaoWorkspace class
provides more direct access to the DAO database-engine object through static member
functions. Although MFC handles the workspace for you, you can access its member
functions and data members to explicitly initialize the database connection.</P>
<P>Another difference is that the DAO classes feature a more powerful set of methods
that you can use to manipulate a database. These more powerful member functions enable
you to perform sophisticated database manipulations without having to write a lot
of complicated C++ code or SQL statements.</P>
<P>In summary, ODBC and DAO similarities are the following:</P>

<UL>
	<LI>ODBC and DAO both can manipulate ODBC data sources. However, DAO is less efficient
	at this task because it's best used with .mdb database files.
	<P>
	<LI>AppWizard can create a basic database application based on either the ODBC or
	DAO classes. Which type of application you want to create depends, at least in some
	part, on the type of databases with which you will be working.
	<P>
	<LI>ODBC and DAO both use objects of an MFC database class to provide a connection
	to the database being accessed. In ODBC, this database class is called CDatabase,
	whereas in DAO, the class is called CDaoDatabase. Although these classes have different
	names, the DAO database class contains some members similar to those found in the
	ODBC class.
	<P>
	<LI>ODBC and DAO both use objects of a recordset class to hold the currently selected
	records from the database. In ODBC, this recordset class is called CRecordset, whereas
	in DAO, the class is called CDaoRecordset. Although these classes have different
	names, the DAO recordset class contains not only almost the same members as the ODBC
	class but also a large set of additional member functions.
	<P>
	<LI>ODBC and DAO use similar procedures for viewing the contents of a data source.
	That is, in both cases, the application must create a database object, create a recordset
	object, and then call member functions of the appropriate classes to manipulate the
	database.
</UL>

<P>Some differences between ODBC and DAO include the following:</P>

<UL>
	<LI>Although both ODBC and DAO MFC classes are much alike (very much, in some cases),
	some similar methods have different names. In addition, the DAO classes feature many
	member functions not included in the ODBC classes.
	<P>
	<LI>ODBC uses macros and enumerations to define options that can be used when opening
	recordsets. DAO, on the other hand, defines constants for this purpose.
	<P>
	<LI>Under ODBC, snapshot recordsets are the default, whereas under DAO, dynamic recordsets
	are the default.
	<P>
	<LI>The many available ODBC drivers make ODBC useful for many different database
	file formats, whereas DAO is best suited to applications that need to access only
	.mdb files.
	<P>
	<LI>ODBC is implemented as a set of DLLs, whereas DAO is implemented as COM objects.
	<P>
	<LI>Under ODBC, an object of the CDatabase class transacts directly with the data
	source. Under DAO, a CDaoWorkspace object sits between the CDaoRecordset and CDaoDatabase
	objects, thus enabling the workspace to transact with multiple database objects.
</UL>

<H2><A NAME="Heading18"></A>OLE DB</H2>
<P><I>OLE DB</I> is a collection of OLE (COM) interfaces that simplify access to
data stored in nondatabase applications such as email mailboxes or flat files. An
application using OLE DB can integrate information from DBMS systems such as Oracle,
SQL Server, or Access with information from nondatabase systems, using the power
of OLE (COM).</P>
<P>OLE DB applications are either <I>consumers</I> or <I>providers</I>. A provider
knows the format for a specific kind of file (such as an ODBC data source or a proprietary
format) and provides access to those files or data sources to other applications.
A consumer wants to access a database. For example, you might choose to rewrite the
Employees example of this chapter as an OLE DB consumer application.</P>
<P>You will receive some help from AppWizard if you choose to go this route. On Step
2, when you select your data source, one of the choices is an OLE DB data source.
Your application will be a little more complex to write than the ODBC example presented
here, but you will be able to manipulate the data in a way very similar to the methods
just covered. For example, the MFC class COleDBRecordView is the OLE DB equivalent
of CRecordView.</P>
<P>A full treatment of OLE DB is outside the scope of this chapter. You need to be
comfortable with OLE interfaces and with templates in order to use this powerful
tool. An OLE DB Programmer's Reference is in the Visual C++ online documentation.
When you are familiar with OLE and ActiveX concepts and have used templates, that's
a great place to start.&#160;&#160;l</P>
<H1></H1>
<CENTER>
<P>
<HR>
<A HREF="../ch21/ch21.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch23/ch23.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
</P>

<P>&#169; <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>


</BODY>

</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -