📄 chap10_7.htm
字号:
<p align="JUSTIFY"> <b>清单10.10
派生类的GetDefaultSQL函数</b></p>
<p align="JUSTIFY">CString CSectionSet::GetDefaultSQL()</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">return _T("[Section]");</p>
<p align="JUSTIFY">}</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY"> </p>
</b>
<p align="JUSTIFY"><b> </b> </p>
<p align="JUSTIFY"> 至于记录的滚动和修改的实现,请参看10.6。而与DDX和DFX有关的代码已在清单10.3和10.2中列出。</p>
<p align="JUSTIFY"> 如果读者对上面的分析还有不明白的地方,那么请再把本章的前几节内容再仔细阅读一遍。</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> <b></b>10.7.3 Enroll的第二个版本</p>
<p align="JUSTIFY"> Enroll的第二个版本向读者演示了在一个记录视图中使用两个相关联的记录集,以及记录的过滤和排序技术,该版本使读者真正接触到了关系数据库。本小节还将向读者介绍如何用ClassWizard建立记录集类,以及参数化记录集的方法。</p>
<p align="JUSTIFY"> 读者可以先运行VC
5.0提供的Enroll例子的第二步看看。Enroll的界面有了一个变化,原来的Course编辑框被替换成了组合框,如图10.10所示。组合框中的内容来自同一数据源的另一张表Course的CourseID字段。</p>
<p align="center"> <img src="T10_10.gif" alt="T10_10.tif (174388 bytes)" width="480" height="342"></p>
<p align="center"> 图10.10
Enroll的第二个版本</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> Course表的内容如表10.5所示,与表10.2相对照,读者可以发现Course表和Section表有一个公共字段CourseID。记录视图程序正是利用这个公共字段把两张表联系起来的。例如,当用户在Course组合框中选择了MATH202时,程序将选择Section表中所有CourseID为MATH202的记录并建立新的记录集。</p>
<p align="JUSTIFY"> 事实上,在STDREG32.MDB的大部分表都共享了CourseID。在主表Course表中,每个记录的CourseID是唯一的,我们称其为主关键字(Primary
key)。在Course的相关表中,CourseID不一定唯一,如Section表,我们称相关表中的CourseID为外关键字(Foreign
key)。通过关键字可以把多张表联系到一起,这样的数据库就是关系数据库。SectionNo也是一个关键字,在Section表中,SectioinNo字段是主关键字,它的值是唯一的。</p>
<p align="JUSTIFY"> <b> </b></p>
<b>
<p align="CENTER">表10.5 Course表</p>
</b>
<table border="1" cellspacing="1" cellpadding="1" width="579">
<tr>
<td width="33%"><b>
<p align="JUSTIFY">CourseID(Text)
</b></td>
<td width="33%"><b>
<p align="JUSTIFY">CourseTitle(Text)
</b></td>
<td width="33%"><b>
<p align="JUSTIFY">Hours(int)
</b></td>
</tr>
<tr>
<td width="33%">
<p align="JUSTIFY">MATH101
</td>
<td width="33%">
<p align="JUSTIFY">Algebra
</td>
<td width="33%">
<p align="JUSTIFY">4
</td>
</tr>
<tr>
<td width="33%">
<p align="JUSTIFY">MATH201
</td>
<td width="33%">
<p align="JUSTIFY">Calculus I
</td>
<td width="33%">
<p align="JUSTIFY">4
</td>
</tr>
<tr>
<td width="33%">
<p align="JUSTIFY">MATH202
</td>
<td width="33%">
<p align="JUSTIFY">Calculus II
</td>
<td width="33%">
<p align="JUSTIFY">4
</td>
</tr>
</table>
<p> </p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> 现在就让我们开始在上一小节Enroll的基础上制作新版本。若当前工程不是Enroll,请读者打开上一小节创建的Enroll工程。</p>
<p align="JUSTIFY"> 首先要把Course编辑框替换成组合框,这包括下面几步:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">打开IDD_ENROLL_FORM对话框模板并删除Course编辑框。</p>
<p align="JUSTIFY">在原来编辑框的位置加入一个组合框。打开该控件的属性对话框,令其ID为IDC_COURSELIST,并在Styles页中选择Drop
List。注意要适当调整组合框的下拉列表尺寸(点击向下的箭头后扩大其尺寸)。</p>
<p align="JUSTIFY">自上到下从新安排Tab顺序。</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY"> 接下来要用ClassWizard做一些与新加的组合框有关的工作:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">进入ClassWizard,选择Member
Variables页并选择CSectionForm类。单击列表中的IDC_COURSE项并按Delete键删除该项。然后双击IDC_COURSELIST项,在Add
Member Variable对话框的组合框中选择m_pSet->m_CourseID。</p>
<p align="JUSTIFY">再次双击IDC_COURSELIST,并为CSectionForm类加入一个名为m_ctlCourseList的CComboBox类成员。</p>
<p align="JUSTIFY">选择Message
Maps页,为IDC_COURSELIST组合框加入CBN_SELENDOK通知消息处理函数,函数名为OnSelendokCourselist。该函数负责响应用户在组合框中选择的变化。</p>
<p align="JUSTIFY">按OK按钮退出ClassWizard。</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY"> 接着,需要为Course表创建一个名为CCourseSet的记录集类,这个工作可由ClassWizard完成,请读者按下面几步操作:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">进入ClassWizard,点击Add
Class...按钮并在弹出的菜单中选择New...,然后在Create
New Class对话框中的Name栏中输入CCourseSet,在Base
class栏中选择CRecordset,按Create按钮。</p>
<p align="JUSTIFY">在弹出的Database
Options对话框中,在ODBC组合框里选择Student
Registration数据源。然后按OK按钮。</p>
<p align="JUSTIFY">在弹出的Select
Database Tables对话框中选择Course表。按OK确认。</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY"> 看看新建的CCourseSet类,读者会发现ClassWizard自动为CCourseSet类创建了与Course表的字段相对应的域数据成员,并且建立了DoFieldExchange函数。ClassWizard也为记录集类提供了新的GetDefaultConnect和GetDefaultSQL函数。</p>
<p align="JUSTIFY"> 接着,在CEnrollDoc类的定义中,紧接着m_sectionSet成员,加入下面一行:</p>
<b>
<p align="JUSTIFY">CCourseSet m_courseSet;</p>
</b>
<p align="JUSTIFY">这样CEnrollDoc就包含了两个记录集。由于CEnrollDoc类用到了CCourseSet类,所以要在所有含有#include
“EnrolDoc.h”语句的CPP文件中,在#include
“EnrolDoc.h”语句的前面加上如下的include语句。这些CPP文件包括CEnrollApp、CSectionForm和CEnrollDoc类所在的CPP文件。</p>
<b>
<p align="JUSTIFY">#include "CourseSet.h"</p>
</b>
<p align="JUSTIFY">在CSectionSet类的定义中,紧接着域数据成员,在“//}}AFX_FIELD”注释外加入下面一行。</p>
<b>
<p align="JUSTIFY">CString m_strCourseIDParam;</p>
</b>
<p align="JUSTIFY">m_strCourseIDParam是记录集的参数数据成员,其作用将在后面说明。</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> 最后,请读者按清单10.11和10.12修改程序。清单10.11列出的是CSectionSet类的部分源代码,清单10.12列出的是CSectionForm类的部分代码。</p>
<p align="JUSTIFY"> <b> </b></p>
<p align="JUSTIFY"> <b>清单10.11
CSectionSet类的部分代码</b> </p>
<p align="JUSTIFY">CSectionSet::CSectionSet(CDatabase* pdb)</p>
<p align="JUSTIFY">: CRecordset(pdb)</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY"><b>. . .</b></p>
<p align="JUSTIFY"> <b>m_nParams
= 1; //</b><b>只有一个参数数据成员</b></p>
<b>
<p align="JUSTIFY">m_strCourseIDParam = "";</p>
</b>
<p align="JUSTIFY">}</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">void CSectionSet::DoFieldExchange(CFieldExchange*
pFX)</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY"><b>. . .</b></p>
<b>
<p align="JUSTIFY">pFX->SetFieldType(CFieldExchange::param);</p>
</b>
<p align="JUSTIFY"><b>RFX_Text(pFX,
"CourseIDParam", m_strCourseIDParam); //</b><b>替换参数</b></p>
<p align="JUSTIFY">}</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> <b> </b></p>
<p align="JUSTIFY"> <b>清单10.12
CSectionForm类的部分代码</b></p>
<p align="JUSTIFY">void CSectionForm::OnInitialUpdate()</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">m_pSet = &GetDocument()->m_sectionSet;</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">CEnrollDoc* pDoc = GetDocument();</p>
<p align="JUSTIFY">pDoc->m_courseSet.m_strSort = "CourseID";</p>
<p align="JUSTIFY">if (!pDoc->m_courseSet.Open())</p>
<p align="JUSTIFY">return;</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> m_pSet->m_strFilter
= "CourseID = ?"; //使用参数</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -