目录
1 技术要求.......................................................... 1
2 基本功能描述...................................................... 1
3 设计思路.......................................................... 2
3.1 添加功能 .................................................... 2
3.2 删除功能 .................................................... 3
3.3 修改功能 .................................................... 3
3.4 查询功能 .................................................... 4
3.5数据库访问接口ODBC .......................................... 4
4 软件设计.......................................................... 4
4.1 设计步骤 .................................................... 4
4.2 界面设计 .................................................... 7
4.3 关键功能的实现 .............................................. 8
4.3.1 添加功能 .............................................. 8
4.3.2 删除功能 .............................................. 8
4.3.3 修改功能 .............................................. 9
4.3.4 查询功能 .............................................. 9
4.3.5 添加用户及权限设置 ................................... 10
5 心得与体会....................................................... 10
6 参考文献......................................................... 11
7 附录............................................................. 11
7.1 调试报告 ................................................... 11
7.2 测试结果 ................................................... 12
7.3 关键源代码 ................................................. 15
电子通讯录的实现
1 技术要求
(1)能创建、修改和增删学生通讯录
1)创建功能:能够轻松地录入一个朋友的姓名、性别、出生日期、通讯地址、电话号码、QQ号码等信息;
2)浏览功能:显示通讯录的全部信息;
3)追加功能:在原有数据资料的基础上按顺序增加记录,可以一次完成若干条信息的输入;
4)删除功能:按照记录的ID或姓名等删除通讯信息。这一步首先根据输
入的删除内容在电子通讯录里查找记录,给出提示信息。若找到记录,提示是否删除,确定执行删除后,显示通讯录的内容;若没有找到,则提示无此人。
5)查找功能:给出姓名,查找该记录并显示该人的信息。
6)插入功能:给出插入位置,执行插入后,查询是否被插入,显示通讯录的内容;
7)排序功能:根据姓名对通讯录进行升序排列。应提供一个界面来调用各个功能,调用界面和各个功能的操作界面应尽可能清晰美观。
(2)能够按多种方式进行查询:查询时请分别使用折半查找法和顺序查找法进行查找。
(3) 应用MFC创建基于对话框的Windows应用程序,设计友好方便的图形用户界面
2 基本功能描述
电子通讯录是一个小的信息系统,通讯信息包括姓名、性别、出生日期、
通讯地址、电话号码、QQ号码等,具有浏览信息,追加记录,删除记录,查询记录,修改记录等功能。
通讯录管理系统采用ODBC\Access数据库作为软件的后台,用微软公司的
快速开发工具Microsoft visual c++6.0开发软件的前台界面及功能实现部分,用
SQL(结构化查询语言)实现对数据库中数据的查询,修改,以及删除等操作。在本通讯录系统中,使用了Microsoft ADO Data Control 6.0 (SP6) (OLEDB)和Microsoft DataGrid Control 6.0 (SP6) (OLEDB)这两个数据库控件,方便数据的显示,用户可以以姓名,对象编号,出生年份等查询条件,按模糊查找和精确查找对数据库进行查询,并显示到主界面的表格中。考虑到有重复姓名等情况的存在,所以在建立数据库时将对象编号作为主键,如果需要进行删除或者修改时,则必须先给出对象编号,经过判断之后才可以进行下一步操作。由于通讯录保存了个人的通讯信息,为保护个人隐私和确保信息安全,所以设置登录密码以及权限设置的功能,并具有修改或删除用户名,权限,密码等功能,不具备权限的用户不能进行相应的操作。
3 设计思路
本通讯录的各个功能模块相对比较分散,相互之间的联系不大,以下将针
对通讯录中的主要模块配以流程图进行说明,同时说明数据库访问接口ODBC。
3.1 添加功能
在添加新成员时,主要考虑操作者是否有该项权利,以及判断新增加的成员的编号是否存在和是否需要继续添加。流程图如下:
图1 添加功能流程图
3.2 删除功能
在删除成员时,主要考虑操作者是否有该项权利,以及在删除对象时询问
操作者是否真的要删除并显示删除对象的部分信息。流程图如下:
图2 删除功能流程图 3.3 修改功能
在修改成员时,主要考虑操作者是否有该项权利,以及判断修改后的成员
的编号是否为其他(不包括当前编号)已存在的编号。流程图如下:
图3 修改功能流程图
3.4 查询功能
在查询时,主要考虑查询条件是否满足,以及查询时使用的查询方法,在
一部分,本通讯录提供了以姓名为模糊查询的查询方式和以编号等其他条件为精确查询的查询方式,并将查询后的结果在Microsoft DataGrid Control 6.0 (SP6) (OLEDB)中显示出来,鉴于此功能判断环节比较少,故省略流程图。
3.5数据库访问接口ODBC
ODBC是开放式数据库互连(Open Database Connectivity)的简称,是微软公司推出的一种实现应用程序和关系数据库之间通讯的方法标准,接口标准。符合标准的数据库就可以通过SQL语言编写的命令对数据库进行操作,但只能针对关系数据库进行操作。ODBC本质上是一组数据库访问API,由一组函数调用组成,核心是SQL语句,其结构如图4。在具体操作时,必须先用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。这样,只要应用程序将数据源名提供给ODBC,ODBC就能建立起与相应数据库的连接。
图4 ODBC结构图
4 软件设计
以下将通过三个模块对这次的通讯录的实现予以说明。
4.1 设计步骤
1) 创建数据库,命名为ELC,建立两张表,分别为成员信息表ELCAB和用户登入表PASSWORD。此时可以将管理员加入到PASSWORD中,也可以为成员信息表加入信息。
图5 建立数据库
2) 使用ODBC管理器注册数据源。
图6 注册数据源
3) 创建MFC AppWizard(exe)工程,工程名为BBLX。选择单文档应用程序,在向导的第二步中加入数据源,并选择“Database view with file support”。点击“完成”。
4) 设计主窗口以及其他需要调用的对话框窗口。添加Microsoft ADO Data Control 6.0 (SP6) (OLEDB)和Microsoft DataGrid Control 6.0 (SP6) (OLEDB)这两个控件。为窗口加入对应的编辑框,列表框,按钮等必须控件。
图7 界面设计1
图8 界面设计2
图9 界面设计3
5) 选择类向导,为各个功能控件添加相应的变量或函数。也可以通过类向导或点击相应的类为类添加所需函数或变量。
6) 添加代码并测试通讯录的功能。为了使软件比较人性化,添加一些菜单项和设置快捷键。调试程序直至无误。
4.2 界面设计
1) 本通讯录的主要界面如下图所示。
图10 用户设置界面
图11 通讯录主界面
2) 本通讯录的部分重要控件表。
本通讯录的控件主要有编辑框,按钮, ADO Data Control,DataGrid Control,组合框以及菜单。为了程序的正常运行,需要为对应的编辑框,
ADO Data
Control,DataGrid Control加入变量,并将菜单与对应的按钮绑定或者为其加入代码。由于控件比较多,这里就不赘述了。详细参照附录中的源代码。
4.3 关键功能的实现
4.3.1 添加功能
在主对话框中添加添加按钮,并为此按钮添加代码,使其与增加成员界面
相联系。完成添加功能的语句主要是m_pSet->AddNew();它提供了将添加界面中的信息添加到数据库中的可能,只需将添加界面中编辑框中的内容赋值给对应的指针即可,例如m_pSet->m_NAME=add.m_na。然后调用函数m_pSet-
>Update( ) ; m_pSet->Requery( );为了使添加的成员立马显示到表格中,还需要通过类向导添加刷新函数。代码如下:
void CBBLXView::OnNew()
{// TODO: Add your control notification handler code here
CString SqlStr;
SqlStr ="SELECT * FROM ELCAB ORDER BY NUMBLE ASC ";
m_ado.SetRecordSource(SqlStr);
m_ado.Refresh();}
当然只有这些是不够的。考虑到同姓名的人存在,本通讯录将编号作为主
键,所以在添加成员时需要判断主键是否重复。同时也要判断用户是否要继续
添加和用户是否有添加的权限,这些功能都是通过MessageBox()予以实现的。
4.3.2 删除功能
完成添加功能的语句主要是m_pSet-> Delete( )。在删除对象之前首先需要
输入需要删除对象的编号,如果编号为空或不存在将不能实现删除,同时也要判断操作者是否有该项权利。在程序中,为了防止操作者操作失误,在程序中添加了询问操作者的功能,例如
while(flg==1){
CString info="\0";
info = "姓名:\t" + m_pSet->m_NAME + "\n";
info += "性别:\t" + m_pSet->m_SEX + "\n";
info += "职称:\t" + m_pSet->m_PROF + "\n";
info += "单位地址:\t" + m_pSet->m_DNAME + "\n";
info += "手机号码:\t" + m_pSet->m_TPN + "\n";
if(m_num==m_pSet->m_NUMBLE)
{ flg1=MessageBox( info, "请确认删除的对象信",100 ); flg=0; t=0;}
else {t=1;} m_pSet->MoveNext( );
if( m_pSet->IsEOF( ) ){flg=0;}}
这样就降低了发生删除错误的可能性。操作完以后调用OnNew(),使表格信息更新。
4.3.3 修改功能
修改功能可以看成是添加功能与删除功能的结合,其核心语句就是
m_pSet->Edit();与删除一样,在开始的时候需要判断输入的编号的可用性以及用户的权限。只有满足条件时才会进入修改界面。在这里需要先将查询到的编号信息送给修改界面,其中查询语句与删除的大同小异,可以参看删除功能中给出的代码,然后添加m_pSet->MovePrev();使指针回到当前,再使用赋值语句即可,接下来使用m_pSet->Edit()便可以进行更新数据库信息了。在这些过程中记得调用m_pSet->Update( ) ; m_pSet->Requery( ); UpdateData();等函数以免出错。操作完以后调用OnNew(),使表格信息更新
4.3.4 查询功能
查询功能主要是通过SQL语句来进行的,在本通讯录中提供了多种查询方式,均在组合框中列出来了,同时查询之后还有排序,本通讯录提供了两种排序方式,可以按编号和姓名的升序排列。例如
CString SqlStr;
SqlStr ="SELECT * FROM ELCAB WHERE " + MakeSqlStr();
m_ado.SetRecordSource(SqlStr);
m_ado.Refresh()
查询提供了功能。其中MakeSqlStr()用来获取主界面的信息。
而SqlStr ="SELECT * FROM ELCAB ORDER BY NUMBLE ASC "则提供了按姓名排序的功能。
4.3.5 添加用户及权限设置
在这一部分添加用户,删除用户,修改密码与主界面中的实现方法类似,这里就不在赘述。不同的是,首先要先通过类向导添加一个包含密码表
PASSWORD的类,然后将用户设置界面与该类联系起来,通过修改用户设置中的信息来更改PASSWORD中的信息。然后在登入界面通过查询来判断操作者是否有权利进入通讯录。在设置权限时,为了简便,使用了单选按钮,通过下面的语句来实现设置: flg2=GetCheckedRadioButton(IDC_A,IDC_AC);
if(flg2==IDC_A){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=0;}
if(flg2==IDC_ADD1){pass2.m_ADD=1;pass2.m_ALT=0;pass2.m_DEL=0;} if(flg2==IDC_C){pass2.m_ADD=0;pass2.m_ALT=1;pass2.m_DEL=0;}
if(flg2==IDC_AC){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=1;}
这样就可以将权限存入表中,以便判断用户的权限了。
5 心得与体会
能力拓展果然比一般的课程设计难,一看到能力拓展的选题我就有了这种
想法。那些题目都不知道是啥意思,最后就选了电子通讯里,相对其他的来说,这个是唯一一个让我明白要做什么的题目,不就是数据库加应用程序嘛吗,当初是这样想的,可是实际操作起来就没想的那么简单了。
在刚开始做这个的时候,VC++已经是忘的差不多了,于是不得不回过头去复习,数据库则由于从未实际操作过,面对SQL,ACCESS完全是无从下手,从网上下的资料也不知所云。特别是数据库与MFC的连接,当时完全不知道还要动用ODBC注册器。于是不得不承认自己自己完全没学到数据库的应用。网上的知识往往跳跃性比较大,也不系统,所以在复习VC++的同时,也到图书馆借了不少数据库的书。经过慢慢的学习之后,总算可以上手了,成功的完成了数据库与MFC的连接。写到这里,不得不说,系统的掌握知识和耐心的学习比浮躁得像无头苍蝇般四处乱窜要实用得多。
做好这些准备工作之后,才开始进入正题。对于增加,删除,修改等功能,编写程序的难度并不大,主要是对指针m_pSet的把握,理解了m_pSet的作用以及CRecordset和CRecordview这两个类的作用,功能的实现是不会太难的。同时在在调试过程中,为了达到较好的交互效果,MessageBox功不可没,特别
是删除和增加这一环节,通过利用MessageBox的返回值来达到询问操作者是否要进行此项操作。
在网上,类似的通讯录软件多的数不胜数,随便下载了一个,与自己的一比较,就显示出了自己的软件的缺点,如不能获取表格中的点击信息。看来如果想进一步完善作品,还需要更加努力。不过这次能力拓展,充分的调用了自己的所学的知识,也算是这次练习的最大收获吧。
6 参考文献
[1] 揣锦华.面向对象程序设计与VC++实践.西安电子科技大学出版
社,2005年2月
[2] 陈志泊,王春玲.数据库原理及应用教程(第二版).人民邮电出版
社,2008年3月
[3] 同志工作室.Visual C++ 6.0数据库开发实例.人民邮电出版社,2001年1月
[4] 郑阿奇,丁有和,郑进.Visual C++ 6.0实用教程.电子工业出版社,2000年8月
7 附录
7.1 调试报告
在调试过程中出现的问题实在是太多了一下就摘录部分典型。
1)未添加头文件,致使程序中的变量未定义,引发了大批错误。
图12 调试错误1
2) 程序运行正常,未报错,但是exe文件执行出现异常,来自数据库的错误,不得不终止程序。
图13 调试错误2
图14 调试错误3
3)SQL语句出现错误。程序也是没有出现报错,但是在执行查询时总是报错,提示SQL语句不能被执行,经过排查,发现写入的查询语句在进行连接时引入了不能被SQL识别的字符,使得SQL语法错误。
7.2 测试结果
由于本程序的可能结果太多,而且重复性较高,故只列入几个主要的测试结果的截图展示效果,其他的可能性将顺带描述。
1)登入界面。在这里需要输入正确的用户名和密码,否则不能登入。对于登入条件的判断分为用户名或密码为空以及用户名和密码不正确。
图15 用户名或密码有误
2)删除功能。先判断输入的编号是否为空和是否存在,不满足条件则弹出对话框予以提醒。接着判断权限并给予提醒。最后是对删除信息的显示并询问是否要删除,点击是则删除,点击否则取消。并却执行完操作后表格中将予以对应的显示。
图16 是否删除
3)查询功能。根据输入的查询信息显示出对应的信息。点击刷新按钮将使表格中的内容按编号的升序排列,点击菜单中的按姓名排序将使表格中的内容按姓名的升序排列。
图17 查询信息
图18 按姓名升序排列
4)添加功能。先判断权限之后进入添加界面。在这里如果添加的成员的编号存在则提示并询问是否继续添加,添加完一个对象后则提示是否继续添加。是则继续,否则退出。
图19 添加成员
5)修改功能。此功能与添加和删除功能有些许相似之处。先判断输入的编号是否为空和是否存在,不满足条件则弹出对话框予以提醒。接着判断权限并给予提醒。接下来就是对修改之后的信息进行判断,如果修改了编号则要判断该编号是否已经存在。
图20 该编号已存在 是否继续修改
图21 编号不存在
6)用户权限设置。在这一界面可以添加新的使用用户及其权限,用户修改密码以及删除用户。鉴于与前面的重复类容太多,这里就不赘述了。
图22 用户设置
7.3 关键源代码
1)用户设置部分代码
void CDelete::OnOK()
{// TODO: Add extra validation here
CCodel pass; pass.Open(); pass.MoveFirst();
int flg=1,flg1=1;
if(IDOK){ UpdateData(true);
while(flg==1){
if(m_newuser==pass.m_USER&&m_oldcode==pass.m_CODE){
flg=0;flg1=0;} pass.MoveNext(); if(pass.IsEOF()){flg=0;}}
pass.MovePrev();
if(flg1==1){MessageBox("您未登入!","错误信息"); return;}
if(flg1==0){
if(m_newcode.IsEmpty()){MessageBox("新密码不能为空!","错误信息"); return;}
else{ pass.Edit(); pass.m_CODE=m_newcode;
if(m_checkcode!=m_newcode){ MessageBox("确认密码与修改后的密码不符,请重新输入!","错误信息"); return;}
pass.Update(); MessageBox("修改成功","提示"); UpdateData(false);
} }}pass.Close();}
void CDelete::OnADD1()
{// TODO: Add your control notification handler code here
CCodel pass2; pass2.Open(); pass2.MoveFirst(); int flg=1;
int flg1=1; int flg2; UpdateData(true);
if(IDOK){if(m_nuname.IsEmpty()||m_nucode.IsEmpty()){
MessageBox("用户名和密码都不能为空^!^","提示"); return;}
while(flg==1){ if(m_nuname==pass2.m_USER){flg=0;flg1=0;} pass2.MoveNext(); if(pass2.IsEOF()){flg=0;}} if(flg1==0){MessageBox("该用户名已存在,请从新输入","提示
");return;} if(flg1==1){ pass2.AddNew();pass2.m_USER=m_nuname;
pass2.m_CODE=m_nucode;
flg2=GetCheckedRadioButton(IDC_A,IDC_AC);
if(flg2==IDC_A){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=0;}
if(flg2==IDC_ADD1){pass2.m_ADD=1;pass2.m_ALT=0;pass2.m_DEL=0;} if(flg2==IDC_C){pass2.m_ADD=0;pass2.m_ALT=1;pass2.m_DEL=0;}
if(flg2==IDC_AC){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=1;}
MessageBox("添加成功。","提示");}}
pass2.Close();}
void CDelete::OnDEL()
{// TODO: Add your control notification handler code here
CCodel pass1; pass1.Open(); pass1.MoveFirst();
int flg=1,flg1=1,flg2=1,flg3=1; UpdateData(true);
if(m_newuser.IsEmpty()){MessageBox("请输入需要删除的用户名^!^","提示");return;}
else{ while(flg==1)
{if(m_newuser==pass1.m_USER){flg=0;flg1=0;}
pass1.MoveNext(); if(pass1.IsEOF()){flg=0;}} pass1.MovePrev();
if(m_newuser=="BBX"){MessageBox("该用户不能被删除","提示");return;} else{if(flg1==1){MessageBox("您需要删除的用户不存在","提示");return;} if(flg1==0){flg2=MessageBox( m_newuser, "请确认删除的对象信息:",100 ); if(flg2==6){ flg3=MessageBox("确定删除?","提示", 100 );}
if(flg3==6){pass1.MovePrev( ); pass1.Delete( ); pass1.Requery( );
MessageBox("已删除^!^","提示", 0 );}}}}pass1.Close();}
BOOL CDelete::OnInitDialog()
{ CDialog::OnInitDialog();
// TODO: Add extra initialization here
CheckRadioButton(IDC_A,IDC_AC,IDC_A); UpdateData(false);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE}
2)主程序代码
void CBBLXView::OnQuery()
{// TODO: Add your control notification handler code here
UpdateData(true); int index1 = m_condition.GetCurSel();
switch(index1)
{case 0:break; case 1:break; case 2:break; case 3:break;
default: {MessageBox("请选择正确的查询条件^!^","提示");return;}} if(m_keywords.IsEmpty())
{MessageBox("请输入查询信息^!^","提示");return;}
else{ CString SqlStr;
SqlStr ="SELECT * FROM ELCAB WHERE " + MakeSqlStr();
m_ado.SetRecordSource(SqlStr); m_ado.Refresh();}
CString CBBLXView::MakeSqlStr()
{ CString SqlStr; UpdateData(true); int index = m_condition.GetCurSel(); if(!m_keywords.IsEmpty()) switch(index)
{ case 0:
{ SqlStr += " NUMBLE ='"; SqlStr += m_keywords; SqlStr += "'"; }break; case 1:
{ SqlStr += " BYEAR ='"; SqlStr += m_keywords; SqlStr += "'"; }break; case 2:
{ SqlStr += " NAME like'"; SqlStr += m_keywords; SqlStr += "%'"; }break; case 3:
{ SqlStr += " SEX ='"; SqlStr += m_keywords; SqlStr += "'"; }break; case 4:
{ SqlStr += " PROF ='"; SqlStr += m_keywords; SqlStr += "'";}break; }return SqlStr;}
void CBBLXView::OnNew()
{// TODO: Add your control notification handler code here
CString SqlStr;
SqlStr ="SELECT * FROM ELCAB ORDER BY NUMBLE ASC "; m_ado.SetRecordSource(SqlStr); m_ado.Refresh();}
void CBBLXView::OnDelete()
{// TODO: Add your control notification handler code here
if( IDOK ){ int flg=1,t=0,flg1=0,flg2=0;
m_pSet->MoveFirst( ); UpdateData(TRUE);
if(m_num.IsEmpty()){MessageBox("请输入需要删除的对象的编号^!^","提示");return;} else{ while(flg==1){ CString info="\0";
info = "姓名:\t" + m_pSet->m_NAME + "\n";
info += "性别:\t" + m_pSet->m_SEX + "\n";
info += "职称:\t" + m_pSet->m_PROF + "\n";
info += "单位地址:\t" + m_pSet->m_DNAME + "\n";
info += "手机号码:\t" + m_pSet->m_TPN + "\n";
if(m_num==m_pSet->m_NUMBLE)
{ flg1=MessageBox( info, "请确认删除的对象信息:",100 ); flg=0; t=0;} else {t=1;}
m_pSet->MoveNext( ); if( m_pSet->IsEOF( ) ){flg=0;}}
if(t==1){MessageBox("你输入的编号不存在^!^","提示", 0 );} if(flg1==6){ flg2=MessageBox("确定删除?","提示", 100 );} if(flg2==6){m_pSet->MovePrev( );
m_pSet->Delete( ); m_pSet->Requery( ); MessageBox("已删除^!^","提示", 0 ); OnNew();}}}
void CBBLXView::OnExit()
{// TODO: Add your control notification handler code here
exit(0); }
void CBBLXView::OnAlter()
{ // TODO: Add your control notification handler code here
int flag=1,t=0,flg3=1,flg4=1; CString fr; m_pSet->MoveFirst();
UpdateData(TRUE); if(m_num.IsEmpty()){
MessageBox("请输入需要修改的对象的编号^!^","提示");return;} else {while(flag==1){ if(m_num==m_pSet->m_NUMBLE)
{flag=0; t=0;} else {t=1;} m_pSet->MoveNext( );
if( m_pSet->IsEOF( ) ){flag=0;}};
if(t==1){MessageBox("你输入的编号不存在","提示", 0 );return;} m_pSet->MovePrev(); CAlter alt; // 工作对话框开始的程序:
//将当前记录的各字段值拷贝到对话框的对应成员变量上:
UpdateData(TRUE); //激活对话框控件
alt.m_bda= m_pSet->m_BDAY;
alt.m_bmon= m_pSet->m_BMONTH;
alt.m_byea= m_pSet->m_BYEAR;
alt.m_dadd= m_pSet->m_DADDRESS;
alt.m_dnam= m_pSet->m_DNAME;
alt.m_ema=m_pSet->m_EMAIL;
alt.m_fa=m_pSet->m_FAX;
alt.m_fadd=m_pSet->m_FADDRESS;
alt.m_pn1=m_pSet->m_PN;
alt.m_sex1=m_pSet->m_SEX;
alt.m_numb=m_pSet->m_NUMBLE;
fr=m_pSet->m_NUMBLE;
alt.m_nam=m_pSet->m_NAME;
alt.m_pro=m_pSet->m_PROF;
alt.m_qq1=m_pSet->m_QQ;
alt.m_rem=m_pSet->m_REMAEK;
alt.m_tpn1=m_pSet->m_TPN;
alt.m_net1=m_pSet->m_NET;
UpdateData(FALSE); //控件上的改变显示出来
//(2)按对话框的"OK"按钮时返回,返回之后重置数据库该记录的修改值: while(flg4==1){ UpdateData(TRUE); if(alt.DoModal()==IDOK){
int flg5=0,flg6=1,flg7=1; m_pSet->MoveFirst();
while(flg6==1){ if(alt.m_numb==m_pSet->m_NUMBLE&&alt.m_numb!=fr){ flg3=MessageBox("该编号已存在,是否继续修改?","提示",100);
flg5=1;flg6=0;} m_pSet->MoveNext( ); if( m_pSet->IsEOF( ) ){flg6=0;}} if(flg3==6){flg4=1;} else flg4=0; if(flg5==0){
m_pSet->MoveFirst(); while(flg7==1){
if(fr==m_pSet->m_NUMBLE) {flg7=0; }
else {t=1;} m_pSet->MoveNext( );if( m_pSet->IsEOF( ) ){flg7=0;}}; m_pSet->MovePrev(); m_pSet->Edit();
m_pSet->m_BDAY = alt.m_bda ;
m_pSet->m_BMONTH = alt.m_bmon ;
m_pSet->m_BYEAR = alt.m_byea;
m_pSet->m_DADDRESS= alt.m_dadd;
m_pSet->m_DNAME = alt.m_dnam ;
m_pSet->m_NET=alt.m_net1;
m_pSet->m_TPN=alt.m_tpn1;
m_pSet->m_SEX=alt.m_sex1;
m_pSet->m_REMAEK=alt.m_rem;
m_pSet->m_QQ=alt.m_qq1;
m_pSet->m_PROF=alt.m_pro;
m_pSet->m_NAME=alt.m_nam;
m_pSet->m_EMAIL=alt.m_ema;
m_pSet->m_FAX=alt.m_fa;
m_pSet->m_FADDRESS=alt.m_fadd;
m_pSet->m_NUMBLE=alt.m_numb;
m_pSet->m_PN=alt.m_pn1;
m_pSet->Update( ) ;
m_pSet->Requery( );
UpdateData(FALSE);
MessageBox("修改成功^!^","提示",0); OnNew();}}else flg4=0;}}} void CBBLXView::OnAdd()
{// TODO: Add your control notification handler code here
CAdd add; int i=1,j=1;int flg=0;int flg1=0;int flg2=0; UpdateData(true); while(i==1){ int j=0; int k=0;
if(add.DoModal()==IDOK){ if(add.m_nu.IsEmpty()){
flg1=MessageBox("编号不能为空,是否继续添加?","提示",100);j=1; if(flg1==6){i=1;} else i=0;}else{
while(!m_pSet->IsEOF()){ if(add.m_nu==m_pSet->m_NUMBLE){ flg2=MessageBox("该编号已存在,是否继续添加?","提示",100); k=1;break;} m_pSet->MoveNext( );}
if(flg2==6){i=1;} else i=0;
if(j==0&&k==0){ m_pSet->AddNew();
m_pSet->m_BDAY = add.m_bd ;
m_pSet->m_BMONTH = add.m_bm ;
m_pSet->m_BYEAR = add.m_by;
m_pSet->m_DADDRESS= add.m_dadd;
m_pSet->m_DNAME = add.m_dn ;
m_pSet->m_NET=add.m_net2;
m_pSet->m_TPN=add.m_tpn2;
m_pSet->m_SEX=add.m_se;
m_pSet->m_REMAEK=add.m_re;
m_pSet->m_QQ=add.m_qq2;
m_pSet->m_PROF=add.m_pr;
m_pSet->m_NAME=add.m_na;
m_pSet->m_EMAIL=add.m_em;
m_pSet->m_FAX=add.m_fx;
m_pSet->m_FADDRESS=add.m_fa;
m_pSet->m_NUMBLE=add.m_nu;
m_pSet->m_PN=add.m_pn2;
m_pSet->Update( ) ; m_pSet->Requery( ); UpdateData(FALSE); flg=MessageBox("添加成功。是否继续添加?","提示",100); OnNew();if(flg==6){i=1;}
else i=0;} }} else i=0;}}
void CBBLXView::OnNameq()
{// TODO: Add your control notification handler code here CString SqlStr;
SqlStr ="SELECT * FROM ELCAB ORDER BY NAME ASC "; m_ado.SetRecordSource(SqlStr);
m_ado.Refresh();
}
目录
1 技术要求.......................................................... 1
2 基本功能描述...................................................... 1
3 设计思路.......................................................... 2
3.1 添加功能 .................................................... 2
3.2 删除功能 .................................................... 3
3.3 修改功能 .................................................... 3
3.4 查询功能 .................................................... 4
3.5数据库访问接口ODBC .......................................... 4
4 软件设计.......................................................... 4
4.1 设计步骤 .................................................... 4
4.2 界面设计 .................................................... 7
4.3 关键功能的实现 .............................................. 8
4.3.1 添加功能 .............................................. 8
4.3.2 删除功能 .............................................. 8
4.3.3 修改功能 .............................................. 9
4.3.4 查询功能 .............................................. 9
4.3.5 添加用户及权限设置 ................................... 10
5 心得与体会....................................................... 10
6 参考文献......................................................... 11
7 附录............................................................. 11
7.1 调试报告 ................................................... 11
7.2 测试结果 ................................................... 12
7.3 关键源代码 ................................................. 15
电子通讯录的实现
1 技术要求
(1)能创建、修改和增删学生通讯录
1)创建功能:能够轻松地录入一个朋友的姓名、性别、出生日期、通讯地址、电话号码、QQ号码等信息;
2)浏览功能:显示通讯录的全部信息;
3)追加功能:在原有数据资料的基础上按顺序增加记录,可以一次完成若干条信息的输入;
4)删除功能:按照记录的ID或姓名等删除通讯信息。这一步首先根据输
入的删除内容在电子通讯录里查找记录,给出提示信息。若找到记录,提示是否删除,确定执行删除后,显示通讯录的内容;若没有找到,则提示无此人。
5)查找功能:给出姓名,查找该记录并显示该人的信息。
6)插入功能:给出插入位置,执行插入后,查询是否被插入,显示通讯录的内容;
7)排序功能:根据姓名对通讯录进行升序排列。应提供一个界面来调用各个功能,调用界面和各个功能的操作界面应尽可能清晰美观。
(2)能够按多种方式进行查询:查询时请分别使用折半查找法和顺序查找法进行查找。
(3) 应用MFC创建基于对话框的Windows应用程序,设计友好方便的图形用户界面
2 基本功能描述
电子通讯录是一个小的信息系统,通讯信息包括姓名、性别、出生日期、
通讯地址、电话号码、QQ号码等,具有浏览信息,追加记录,删除记录,查询记录,修改记录等功能。
通讯录管理系统采用ODBC\Access数据库作为软件的后台,用微软公司的
快速开发工具Microsoft visual c++6.0开发软件的前台界面及功能实现部分,用
SQL(结构化查询语言)实现对数据库中数据的查询,修改,以及删除等操作。在本通讯录系统中,使用了Microsoft ADO Data Control 6.0 (SP6) (OLEDB)和Microsoft DataGrid Control 6.0 (SP6) (OLEDB)这两个数据库控件,方便数据的显示,用户可以以姓名,对象编号,出生年份等查询条件,按模糊查找和精确查找对数据库进行查询,并显示到主界面的表格中。考虑到有重复姓名等情况的存在,所以在建立数据库时将对象编号作为主键,如果需要进行删除或者修改时,则必须先给出对象编号,经过判断之后才可以进行下一步操作。由于通讯录保存了个人的通讯信息,为保护个人隐私和确保信息安全,所以设置登录密码以及权限设置的功能,并具有修改或删除用户名,权限,密码等功能,不具备权限的用户不能进行相应的操作。
3 设计思路
本通讯录的各个功能模块相对比较分散,相互之间的联系不大,以下将针
对通讯录中的主要模块配以流程图进行说明,同时说明数据库访问接口ODBC。
3.1 添加功能
在添加新成员时,主要考虑操作者是否有该项权利,以及判断新增加的成员的编号是否存在和是否需要继续添加。流程图如下:
图1 添加功能流程图
3.2 删除功能
在删除成员时,主要考虑操作者是否有该项权利,以及在删除对象时询问
操作者是否真的要删除并显示删除对象的部分信息。流程图如下:
图2 删除功能流程图 3.3 修改功能
在修改成员时,主要考虑操作者是否有该项权利,以及判断修改后的成员
的编号是否为其他(不包括当前编号)已存在的编号。流程图如下:
图3 修改功能流程图
3.4 查询功能
在查询时,主要考虑查询条件是否满足,以及查询时使用的查询方法,在
一部分,本通讯录提供了以姓名为模糊查询的查询方式和以编号等其他条件为精确查询的查询方式,并将查询后的结果在Microsoft DataGrid Control 6.0 (SP6) (OLEDB)中显示出来,鉴于此功能判断环节比较少,故省略流程图。
3.5数据库访问接口ODBC
ODBC是开放式数据库互连(Open Database Connectivity)的简称,是微软公司推出的一种实现应用程序和关系数据库之间通讯的方法标准,接口标准。符合标准的数据库就可以通过SQL语言编写的命令对数据库进行操作,但只能针对关系数据库进行操作。ODBC本质上是一组数据库访问API,由一组函数调用组成,核心是SQL语句,其结构如图4。在具体操作时,必须先用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。这样,只要应用程序将数据源名提供给ODBC,ODBC就能建立起与相应数据库的连接。
图4 ODBC结构图
4 软件设计
以下将通过三个模块对这次的通讯录的实现予以说明。
4.1 设计步骤
1) 创建数据库,命名为ELC,建立两张表,分别为成员信息表ELCAB和用户登入表PASSWORD。此时可以将管理员加入到PASSWORD中,也可以为成员信息表加入信息。
图5 建立数据库
2) 使用ODBC管理器注册数据源。
图6 注册数据源
3) 创建MFC AppWizard(exe)工程,工程名为BBLX。选择单文档应用程序,在向导的第二步中加入数据源,并选择“Database view with file support”。点击“完成”。
4) 设计主窗口以及其他需要调用的对话框窗口。添加Microsoft ADO Data Control 6.0 (SP6) (OLEDB)和Microsoft DataGrid Control 6.0 (SP6) (OLEDB)这两个控件。为窗口加入对应的编辑框,列表框,按钮等必须控件。
图7 界面设计1
图8 界面设计2
图9 界面设计3
5) 选择类向导,为各个功能控件添加相应的变量或函数。也可以通过类向导或点击相应的类为类添加所需函数或变量。
6) 添加代码并测试通讯录的功能。为了使软件比较人性化,添加一些菜单项和设置快捷键。调试程序直至无误。
4.2 界面设计
1) 本通讯录的主要界面如下图所示。
图10 用户设置界面
图11 通讯录主界面
2) 本通讯录的部分重要控件表。
本通讯录的控件主要有编辑框,按钮, ADO Data Control,DataGrid Control,组合框以及菜单。为了程序的正常运行,需要为对应的编辑框,
ADO Data
Control,DataGrid Control加入变量,并将菜单与对应的按钮绑定或者为其加入代码。由于控件比较多,这里就不赘述了。详细参照附录中的源代码。
4.3 关键功能的实现
4.3.1 添加功能
在主对话框中添加添加按钮,并为此按钮添加代码,使其与增加成员界面
相联系。完成添加功能的语句主要是m_pSet->AddNew();它提供了将添加界面中的信息添加到数据库中的可能,只需将添加界面中编辑框中的内容赋值给对应的指针即可,例如m_pSet->m_NAME=add.m_na。然后调用函数m_pSet-
>Update( ) ; m_pSet->Requery( );为了使添加的成员立马显示到表格中,还需要通过类向导添加刷新函数。代码如下:
void CBBLXView::OnNew()
{// TODO: Add your control notification handler code here
CString SqlStr;
SqlStr ="SELECT * FROM ELCAB ORDER BY NUMBLE ASC ";
m_ado.SetRecordSource(SqlStr);
m_ado.Refresh();}
当然只有这些是不够的。考虑到同姓名的人存在,本通讯录将编号作为主
键,所以在添加成员时需要判断主键是否重复。同时也要判断用户是否要继续
添加和用户是否有添加的权限,这些功能都是通过MessageBox()予以实现的。
4.3.2 删除功能
完成添加功能的语句主要是m_pSet-> Delete( )。在删除对象之前首先需要
输入需要删除对象的编号,如果编号为空或不存在将不能实现删除,同时也要判断操作者是否有该项权利。在程序中,为了防止操作者操作失误,在程序中添加了询问操作者的功能,例如
while(flg==1){
CString info="\0";
info = "姓名:\t" + m_pSet->m_NAME + "\n";
info += "性别:\t" + m_pSet->m_SEX + "\n";
info += "职称:\t" + m_pSet->m_PROF + "\n";
info += "单位地址:\t" + m_pSet->m_DNAME + "\n";
info += "手机号码:\t" + m_pSet->m_TPN + "\n";
if(m_num==m_pSet->m_NUMBLE)
{ flg1=MessageBox( info, "请确认删除的对象信",100 ); flg=0; t=0;}
else {t=1;} m_pSet->MoveNext( );
if( m_pSet->IsEOF( ) ){flg=0;}}
这样就降低了发生删除错误的可能性。操作完以后调用OnNew(),使表格信息更新。
4.3.3 修改功能
修改功能可以看成是添加功能与删除功能的结合,其核心语句就是
m_pSet->Edit();与删除一样,在开始的时候需要判断输入的编号的可用性以及用户的权限。只有满足条件时才会进入修改界面。在这里需要先将查询到的编号信息送给修改界面,其中查询语句与删除的大同小异,可以参看删除功能中给出的代码,然后添加m_pSet->MovePrev();使指针回到当前,再使用赋值语句即可,接下来使用m_pSet->Edit()便可以进行更新数据库信息了。在这些过程中记得调用m_pSet->Update( ) ; m_pSet->Requery( ); UpdateData();等函数以免出错。操作完以后调用OnNew(),使表格信息更新
4.3.4 查询功能
查询功能主要是通过SQL语句来进行的,在本通讯录中提供了多种查询方式,均在组合框中列出来了,同时查询之后还有排序,本通讯录提供了两种排序方式,可以按编号和姓名的升序排列。例如
CString SqlStr;
SqlStr ="SELECT * FROM ELCAB WHERE " + MakeSqlStr();
m_ado.SetRecordSource(SqlStr);
m_ado.Refresh()
查询提供了功能。其中MakeSqlStr()用来获取主界面的信息。
而SqlStr ="SELECT * FROM ELCAB ORDER BY NUMBLE ASC "则提供了按姓名排序的功能。
4.3.5 添加用户及权限设置
在这一部分添加用户,删除用户,修改密码与主界面中的实现方法类似,这里就不在赘述。不同的是,首先要先通过类向导添加一个包含密码表
PASSWORD的类,然后将用户设置界面与该类联系起来,通过修改用户设置中的信息来更改PASSWORD中的信息。然后在登入界面通过查询来判断操作者是否有权利进入通讯录。在设置权限时,为了简便,使用了单选按钮,通过下面的语句来实现设置: flg2=GetCheckedRadioButton(IDC_A,IDC_AC);
if(flg2==IDC_A){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=0;}
if(flg2==IDC_ADD1){pass2.m_ADD=1;pass2.m_ALT=0;pass2.m_DEL=0;} if(flg2==IDC_C){pass2.m_ADD=0;pass2.m_ALT=1;pass2.m_DEL=0;}
if(flg2==IDC_AC){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=1;}
这样就可以将权限存入表中,以便判断用户的权限了。
5 心得与体会
能力拓展果然比一般的课程设计难,一看到能力拓展的选题我就有了这种
想法。那些题目都不知道是啥意思,最后就选了电子通讯里,相对其他的来说,这个是唯一一个让我明白要做什么的题目,不就是数据库加应用程序嘛吗,当初是这样想的,可是实际操作起来就没想的那么简单了。
在刚开始做这个的时候,VC++已经是忘的差不多了,于是不得不回过头去复习,数据库则由于从未实际操作过,面对SQL,ACCESS完全是无从下手,从网上下的资料也不知所云。特别是数据库与MFC的连接,当时完全不知道还要动用ODBC注册器。于是不得不承认自己自己完全没学到数据库的应用。网上的知识往往跳跃性比较大,也不系统,所以在复习VC++的同时,也到图书馆借了不少数据库的书。经过慢慢的学习之后,总算可以上手了,成功的完成了数据库与MFC的连接。写到这里,不得不说,系统的掌握知识和耐心的学习比浮躁得像无头苍蝇般四处乱窜要实用得多。
做好这些准备工作之后,才开始进入正题。对于增加,删除,修改等功能,编写程序的难度并不大,主要是对指针m_pSet的把握,理解了m_pSet的作用以及CRecordset和CRecordview这两个类的作用,功能的实现是不会太难的。同时在在调试过程中,为了达到较好的交互效果,MessageBox功不可没,特别
是删除和增加这一环节,通过利用MessageBox的返回值来达到询问操作者是否要进行此项操作。
在网上,类似的通讯录软件多的数不胜数,随便下载了一个,与自己的一比较,就显示出了自己的软件的缺点,如不能获取表格中的点击信息。看来如果想进一步完善作品,还需要更加努力。不过这次能力拓展,充分的调用了自己的所学的知识,也算是这次练习的最大收获吧。
6 参考文献
[1] 揣锦华.面向对象程序设计与VC++实践.西安电子科技大学出版
社,2005年2月
[2] 陈志泊,王春玲.数据库原理及应用教程(第二版).人民邮电出版
社,2008年3月
[3] 同志工作室.Visual C++ 6.0数据库开发实例.人民邮电出版社,2001年1月
[4] 郑阿奇,丁有和,郑进.Visual C++ 6.0实用教程.电子工业出版社,2000年8月
7 附录
7.1 调试报告
在调试过程中出现的问题实在是太多了一下就摘录部分典型。
1)未添加头文件,致使程序中的变量未定义,引发了大批错误。
图12 调试错误1
2) 程序运行正常,未报错,但是exe文件执行出现异常,来自数据库的错误,不得不终止程序。
图13 调试错误2
图14 调试错误3
3)SQL语句出现错误。程序也是没有出现报错,但是在执行查询时总是报错,提示SQL语句不能被执行,经过排查,发现写入的查询语句在进行连接时引入了不能被SQL识别的字符,使得SQL语法错误。
7.2 测试结果
由于本程序的可能结果太多,而且重复性较高,故只列入几个主要的测试结果的截图展示效果,其他的可能性将顺带描述。
1)登入界面。在这里需要输入正确的用户名和密码,否则不能登入。对于登入条件的判断分为用户名或密码为空以及用户名和密码不正确。
图15 用户名或密码有误
2)删除功能。先判断输入的编号是否为空和是否存在,不满足条件则弹出对话框予以提醒。接着判断权限并给予提醒。最后是对删除信息的显示并询问是否要删除,点击是则删除,点击否则取消。并却执行完操作后表格中将予以对应的显示。
图16 是否删除
3)查询功能。根据输入的查询信息显示出对应的信息。点击刷新按钮将使表格中的内容按编号的升序排列,点击菜单中的按姓名排序将使表格中的内容按姓名的升序排列。
图17 查询信息
图18 按姓名升序排列
4)添加功能。先判断权限之后进入添加界面。在这里如果添加的成员的编号存在则提示并询问是否继续添加,添加完一个对象后则提示是否继续添加。是则继续,否则退出。
图19 添加成员
5)修改功能。此功能与添加和删除功能有些许相似之处。先判断输入的编号是否为空和是否存在,不满足条件则弹出对话框予以提醒。接着判断权限并给予提醒。接下来就是对修改之后的信息进行判断,如果修改了编号则要判断该编号是否已经存在。
图20 该编号已存在 是否继续修改
图21 编号不存在
6)用户权限设置。在这一界面可以添加新的使用用户及其权限,用户修改密码以及删除用户。鉴于与前面的重复类容太多,这里就不赘述了。
图22 用户设置
7.3 关键源代码
1)用户设置部分代码
void CDelete::OnOK()
{// TODO: Add extra validation here
CCodel pass; pass.Open(); pass.MoveFirst();
int flg=1,flg1=1;
if(IDOK){ UpdateData(true);
while(flg==1){
if(m_newuser==pass.m_USER&&m_oldcode==pass.m_CODE){
flg=0;flg1=0;} pass.MoveNext(); if(pass.IsEOF()){flg=0;}}
pass.MovePrev();
if(flg1==1){MessageBox("您未登入!","错误信息"); return;}
if(flg1==0){
if(m_newcode.IsEmpty()){MessageBox("新密码不能为空!","错误信息"); return;}
else{ pass.Edit(); pass.m_CODE=m_newcode;
if(m_checkcode!=m_newcode){ MessageBox("确认密码与修改后的密码不符,请重新输入!","错误信息"); return;}
pass.Update(); MessageBox("修改成功","提示"); UpdateData(false);
} }}pass.Close();}
void CDelete::OnADD1()
{// TODO: Add your control notification handler code here
CCodel pass2; pass2.Open(); pass2.MoveFirst(); int flg=1;
int flg1=1; int flg2; UpdateData(true);
if(IDOK){if(m_nuname.IsEmpty()||m_nucode.IsEmpty()){
MessageBox("用户名和密码都不能为空^!^","提示"); return;}
while(flg==1){ if(m_nuname==pass2.m_USER){flg=0;flg1=0;} pass2.MoveNext(); if(pass2.IsEOF()){flg=0;}} if(flg1==0){MessageBox("该用户名已存在,请从新输入","提示
");return;} if(flg1==1){ pass2.AddNew();pass2.m_USER=m_nuname;
pass2.m_CODE=m_nucode;
flg2=GetCheckedRadioButton(IDC_A,IDC_AC);
if(flg2==IDC_A){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=0;}
if(flg2==IDC_ADD1){pass2.m_ADD=1;pass2.m_ALT=0;pass2.m_DEL=0;} if(flg2==IDC_C){pass2.m_ADD=0;pass2.m_ALT=1;pass2.m_DEL=0;}
if(flg2==IDC_AC){pass2.m_ADD=0;pass2.m_ALT=0;pass2.m_DEL=1;}
MessageBox("添加成功。","提示");}}
pass2.Close();}
void CDelete::OnDEL()
{// TODO: Add your control notification handler code here
CCodel pass1; pass1.Open(); pass1.MoveFirst();
int flg=1,flg1=1,flg2=1,flg3=1; UpdateData(true);
if(m_newuser.IsEmpty()){MessageBox("请输入需要删除的用户名^!^","提示");return;}
else{ while(flg==1)
{if(m_newuser==pass1.m_USER){flg=0;flg1=0;}
pass1.MoveNext(); if(pass1.IsEOF()){flg=0;}} pass1.MovePrev();
if(m_newuser=="BBX"){MessageBox("该用户不能被删除","提示");return;} else{if(flg1==1){MessageBox("您需要删除的用户不存在","提示");return;} if(flg1==0){flg2=MessageBox( m_newuser, "请确认删除的对象信息:",100 ); if(flg2==6){ flg3=MessageBox("确定删除?","提示", 100 );}
if(flg3==6){pass1.MovePrev( ); pass1.Delete( ); pass1.Requery( );
MessageBox("已删除^!^","提示", 0 );}}}}pass1.Close();}
BOOL CDelete::OnInitDialog()
{ CDialog::OnInitDialog();
// TODO: Add extra initialization here
CheckRadioButton(IDC_A,IDC_AC,IDC_A); UpdateData(false);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE}
2)主程序代码
void CBBLXView::OnQuery()
{// TODO: Add your control notification handler code here
UpdateData(true); int index1 = m_condition.GetCurSel();
switch(index1)
{case 0:break; case 1:break; case 2:break; case 3:break;
default: {MessageBox("请选择正确的查询条件^!^","提示");return;}} if(m_keywords.IsEmpty())
{MessageBox("请输入查询信息^!^","提示");return;}
else{ CString SqlStr;
SqlStr ="SELECT * FROM ELCAB WHERE " + MakeSqlStr();
m_ado.SetRecordSource(SqlStr); m_ado.Refresh();}
CString CBBLXView::MakeSqlStr()
{ CString SqlStr; UpdateData(true); int index = m_condition.GetCurSel(); if(!m_keywords.IsEmpty()) switch(index)
{ case 0:
{ SqlStr += " NUMBLE ='"; SqlStr += m_keywords; SqlStr += "'"; }break; case 1:
{ SqlStr += " BYEAR ='"; SqlStr += m_keywords; SqlStr += "'"; }break; case 2:
{ SqlStr += " NAME like'"; SqlStr += m_keywords; SqlStr += "%'"; }break; case 3:
{ SqlStr += " SEX ='"; SqlStr += m_keywords; SqlStr += "'"; }break; case 4:
{ SqlStr += " PROF ='"; SqlStr += m_keywords; SqlStr += "'";}break; }return SqlStr;}
void CBBLXView::OnNew()
{// TODO: Add your control notification handler code here
CString SqlStr;
SqlStr ="SELECT * FROM ELCAB ORDER BY NUMBLE ASC "; m_ado.SetRecordSource(SqlStr); m_ado.Refresh();}
void CBBLXView::OnDelete()
{// TODO: Add your control notification handler code here
if( IDOK ){ int flg=1,t=0,flg1=0,flg2=0;
m_pSet->MoveFirst( ); UpdateData(TRUE);
if(m_num.IsEmpty()){MessageBox("请输入需要删除的对象的编号^!^","提示");return;} else{ while(flg==1){ CString info="\0";
info = "姓名:\t" + m_pSet->m_NAME + "\n";
info += "性别:\t" + m_pSet->m_SEX + "\n";
info += "职称:\t" + m_pSet->m_PROF + "\n";
info += "单位地址:\t" + m_pSet->m_DNAME + "\n";
info += "手机号码:\t" + m_pSet->m_TPN + "\n";
if(m_num==m_pSet->m_NUMBLE)
{ flg1=MessageBox( info, "请确认删除的对象信息:",100 ); flg=0; t=0;} else {t=1;}
m_pSet->MoveNext( ); if( m_pSet->IsEOF( ) ){flg=0;}}
if(t==1){MessageBox("你输入的编号不存在^!^","提示", 0 );} if(flg1==6){ flg2=MessageBox("确定删除?","提示", 100 );} if(flg2==6){m_pSet->MovePrev( );
m_pSet->Delete( ); m_pSet->Requery( ); MessageBox("已删除^!^","提示", 0 ); OnNew();}}}
void CBBLXView::OnExit()
{// TODO: Add your control notification handler code here
exit(0); }
void CBBLXView::OnAlter()
{ // TODO: Add your control notification handler code here
int flag=1,t=0,flg3=1,flg4=1; CString fr; m_pSet->MoveFirst();
UpdateData(TRUE); if(m_num.IsEmpty()){
MessageBox("请输入需要修改的对象的编号^!^","提示");return;} else {while(flag==1){ if(m_num==m_pSet->m_NUMBLE)
{flag=0; t=0;} else {t=1;} m_pSet->MoveNext( );
if( m_pSet->IsEOF( ) ){flag=0;}};
if(t==1){MessageBox("你输入的编号不存在","提示", 0 );return;} m_pSet->MovePrev(); CAlter alt; // 工作对话框开始的程序:
//将当前记录的各字段值拷贝到对话框的对应成员变量上:
UpdateData(TRUE); //激活对话框控件
alt.m_bda= m_pSet->m_BDAY;
alt.m_bmon= m_pSet->m_BMONTH;
alt.m_byea= m_pSet->m_BYEAR;
alt.m_dadd= m_pSet->m_DADDRESS;
alt.m_dnam= m_pSet->m_DNAME;
alt.m_ema=m_pSet->m_EMAIL;
alt.m_fa=m_pSet->m_FAX;
alt.m_fadd=m_pSet->m_FADDRESS;
alt.m_pn1=m_pSet->m_PN;
alt.m_sex1=m_pSet->m_SEX;
alt.m_numb=m_pSet->m_NUMBLE;
fr=m_pSet->m_NUMBLE;
alt.m_nam=m_pSet->m_NAME;
alt.m_pro=m_pSet->m_PROF;
alt.m_qq1=m_pSet->m_QQ;
alt.m_rem=m_pSet->m_REMAEK;
alt.m_tpn1=m_pSet->m_TPN;
alt.m_net1=m_pSet->m_NET;
UpdateData(FALSE); //控件上的改变显示出来
//(2)按对话框的"OK"按钮时返回,返回之后重置数据库该记录的修改值: while(flg4==1){ UpdateData(TRUE); if(alt.DoModal()==IDOK){
int flg5=0,flg6=1,flg7=1; m_pSet->MoveFirst();
while(flg6==1){ if(alt.m_numb==m_pSet->m_NUMBLE&&alt.m_numb!=fr){ flg3=MessageBox("该编号已存在,是否继续修改?","提示",100);
flg5=1;flg6=0;} m_pSet->MoveNext( ); if( m_pSet->IsEOF( ) ){flg6=0;}} if(flg3==6){flg4=1;} else flg4=0; if(flg5==0){
m_pSet->MoveFirst(); while(flg7==1){
if(fr==m_pSet->m_NUMBLE) {flg7=0; }
else {t=1;} m_pSet->MoveNext( );if( m_pSet->IsEOF( ) ){flg7=0;}}; m_pSet->MovePrev(); m_pSet->Edit();
m_pSet->m_BDAY = alt.m_bda ;
m_pSet->m_BMONTH = alt.m_bmon ;
m_pSet->m_BYEAR = alt.m_byea;
m_pSet->m_DADDRESS= alt.m_dadd;
m_pSet->m_DNAME = alt.m_dnam ;
m_pSet->m_NET=alt.m_net1;
m_pSet->m_TPN=alt.m_tpn1;
m_pSet->m_SEX=alt.m_sex1;
m_pSet->m_REMAEK=alt.m_rem;
m_pSet->m_QQ=alt.m_qq1;
m_pSet->m_PROF=alt.m_pro;
m_pSet->m_NAME=alt.m_nam;
m_pSet->m_EMAIL=alt.m_ema;
m_pSet->m_FAX=alt.m_fa;
m_pSet->m_FADDRESS=alt.m_fadd;
m_pSet->m_NUMBLE=alt.m_numb;
m_pSet->m_PN=alt.m_pn1;
m_pSet->Update( ) ;
m_pSet->Requery( );
UpdateData(FALSE);
MessageBox("修改成功^!^","提示",0); OnNew();}}else flg4=0;}}} void CBBLXView::OnAdd()
{// TODO: Add your control notification handler code here
CAdd add; int i=1,j=1;int flg=0;int flg1=0;int flg2=0; UpdateData(true); while(i==1){ int j=0; int k=0;
if(add.DoModal()==IDOK){ if(add.m_nu.IsEmpty()){
flg1=MessageBox("编号不能为空,是否继续添加?","提示",100);j=1; if(flg1==6){i=1;} else i=0;}else{
while(!m_pSet->IsEOF()){ if(add.m_nu==m_pSet->m_NUMBLE){ flg2=MessageBox("该编号已存在,是否继续添加?","提示",100); k=1;break;} m_pSet->MoveNext( );}
if(flg2==6){i=1;} else i=0;
if(j==0&&k==0){ m_pSet->AddNew();
m_pSet->m_BDAY = add.m_bd ;
m_pSet->m_BMONTH = add.m_bm ;
m_pSet->m_BYEAR = add.m_by;
m_pSet->m_DADDRESS= add.m_dadd;
m_pSet->m_DNAME = add.m_dn ;
m_pSet->m_NET=add.m_net2;
m_pSet->m_TPN=add.m_tpn2;
m_pSet->m_SEX=add.m_se;
m_pSet->m_REMAEK=add.m_re;
m_pSet->m_QQ=add.m_qq2;
m_pSet->m_PROF=add.m_pr;
m_pSet->m_NAME=add.m_na;
m_pSet->m_EMAIL=add.m_em;
m_pSet->m_FAX=add.m_fx;
m_pSet->m_FADDRESS=add.m_fa;
m_pSet->m_NUMBLE=add.m_nu;
m_pSet->m_PN=add.m_pn2;
m_pSet->Update( ) ; m_pSet->Requery( ); UpdateData(FALSE); flg=MessageBox("添加成功。是否继续添加?","提示",100); OnNew();if(flg==6){i=1;}
else i=0;} }} else i=0;}}
void CBBLXView::OnNameq()
{// TODO: Add your control notification handler code here CString SqlStr;
SqlStr ="SELECT * FROM ELCAB ORDER BY NAME ASC "; m_ado.SetRecordSource(SqlStr);
m_ado.Refresh();
}