C++中用ODBC和ADO方式连接SQL数据库__完成
C++
1
1.1
.......等数据表。在表的数据结构设计中,字段名尽量采用“”较好的标识符,在程序中看到它,
也就知道它实际含义,即“
说明
关于失联党员情况说明岗位说明总经理岗位说明书会计岗位说明书行政主管岗位说明书
”处的文字解释。
下面就是这样做的,在。
1.2
在下面的讨论中,结合本教科
书
关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf
(详见第247页),不妨做“学生成绩管理数据库”,它有三个数据表:
/C/8/C/8/C/6/C/10/C/4/C/16 表名为StudentTable
(number , name , sex , birthdate , height, specialty )
/C/8 /C/20/C/10/C/4 /C/10 表名为CourseTable
(CourseNumber , ForSpecial , CourseName , TotalCredit, TestDate )
(studentNO, courseNo, score ) 表名为StudentScoreTable
/C/8 /C/8/C/6
?ACCESSSQL Server
VC++SQL。
?C++特别适合做“文本(类型CString)”处理。在学生成绩管理数据库中,各字段一律定义为“文本型”,当字段实际类型是数值型或要做算术运算时,C++提供了将数值字符串转换为算术型量转换函数:
atoi(str)atol(str)依次将串转换为int、long;而atof(str)转换double或float型。
2
2.1 ACCESS
2.2 SQL Server
?省略
2.3 ODBC用户DSN
例如:由ACCESS创建的数据库,它是一个容器型文件,扩展名为“.mdb”。所以,上述数据库文件
是“学生成绩管理.mdb”。
操作:“开始 / 控制面板 / 性能和维护 / 管理工具 / ODBC数据源 ”,则弹出“ODBC数据源管理器”对话框。先选择“用户DSN”,再按“添加(D)…”按钮:
按“添加”按钮之后,又弹出下面“”对话框
取数据源的驱动程序“Microsoft Access Driver (*.mdb)”之后,按“”按钮。当按“”按钮之后,系统回到第2步,弹出下面“ODBC Microsoft Access”对话框。在此,完成将已经设计
的ACCESS系统的数据库送入系统ODBC并且命名(数据源(N):处填写)。例如,将“学生成绩管理.mdb”数据库,送入系统数据源ODBC中并且命名为StudentAndJava
3
.
entifier
标识符(俗话讲“名字”),缩写词是。
M
Microsoft oundation lassLibrary
微软的基础类库。
lication()
泛指“应用”(程序)。
pplication rogramming nterface
应用程序接口。
Application Frameworks
应用程序框架。
AppWizard
应用程序向导。
WorkSpace
VC++的工作空间视窗,有三个页(面):
Class页:“类”视图页,展示当前应用程序所用的类。
Resource页:“资源”视图页,展示当前应用程序所用的资源(如Dialog和Menu等)。
File页:“文件”视图页,展示当前应用程序所存放的文件(如扩展名为.cpp、.h文件)。
pen ataaseonnectivity(开放的数据库连接)。为各种类型的数据库管理系统提供了统一
的编程接口,例如不同数据库系统的驱动程序。
M()
CObject
是大多数类的基类,完成动态空间的分配与回收,支持一般诊断与出错处理。
CCmdTarget
负责将系统事件(消息)和窗口事件(消息)发送给响应该事件的对象。
CWinApp
是CCmdTarget类的派生类,完成对线程的控制(线程的建立、运行、终止、挂起)。
CDocument
是文档类,包括应用程序在运行期间所得到的数据。
CWnd
是通用窗口类,提供Windows中的所有通用特性、对话框和控件。
CFrameWnd
是从CWnd继承来的,实现了
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
的框架应用程序。
CDialog
用来控制对话框窗口。
CView
用于让用户通过窗口来访问文档。
CMDIFameWnd
是一个简化的窗口框架(没有最大化和最小化按钮),用于多文档应用程序的主框架窗口的显示和
管理。
CMDIChildWnd
用于文档子窗口的显示和管理。
动态记录集CRecordSet
选择和连接ODBC中数据库的某个“表”。
)控件
静态文本(Static Text)
设计“标签”,默认的是“IDC_STATIC”。不接受用户的输入,不产生
通知
关于发布提成方案的通知关于xx通知关于成立公司筹建组的通知关于红头文件的使用公开通知关于计发全勤奖的通知
消息。例如,书
写数据库的字段名、提示词。
组框(Group Box)
定义一个矩形框,默认的是“IDC_STATIC”。矩形框内可以放按钮等控件,使界面设计“好看”一点。
编辑框(Edit Box)
在对换话框中用于设计文本数据的显示或输入,系统默认的是“IDC_EDIT1”,用其属性对换话框中“General”选项后,用户可重新命名字(例如:IDC_STATIC_number)。
命令按钮(Button)
映射消息:BN_CLICKED 单击,BN_DOUBLECLICKED 双击,响应“单击”消息的是“事件(Events)”
函数程序。系统默认的是IDC_BUTTON1。
驱动机制
Windows的环境中,系统产生的动作和用户程序运行产生的动作“称为”事件(Events)产生的消息(Message),Windows是通过系统发送消息来完成用户输入的。
例如:用户按鼠标左按钮,系统发送 WM_LBUTTONDOWN 消息;
用户敲一个字符键,系统发送 WM_CHAR 消息;
用户进行菜单选择、工具按钮单击等操作,系统发送 WM_COMMAND 消息;
应用程序中的光标、菜单、工具栏、位图、对话框、.....,都是资源,系统都用相应的“标识符”
来区分。这些资源,像VC++中的常量一样,可以被编辑和修改。VC++的许多编辑器,都能达到“所见即所
得”的设计效果。
例如:IDOK为对话框中“确认”,IDCANCEL为对话框中“取消”,BN_CLICKED为单击按钮。 Windows的
实现用户界面、在屏幕上显示文本和图形,都是通过动态连接库来实现的。动态连接库是一些具有
扩展名为DLL文件,文件中是一些特殊结构的函数。
例如:USER32.DLL,负责窗口管理,功能有消息、菜单、光标、计时器,其它与控制窗口显示相关的
功能。
C++Project
1在C++环境中,选择菜单“/”,在弹出的“新建”对话框中,取“工程/MFC AppWizard(exe)/给工程命名”。例如,工程名是“学生成绩管理”:
2在MFC向导的1,选择“S单个文档”(或M多重文档),然后按“下一步”按钮。即,要创建
一个(界面),在界面上设置各种“控件”:
3在MFC向导的2,取“W数据库查看使用文件支持”,并通过命令Data Source去浏览已经存放在ODBC中的数据库及其数据库中的一个表:
数据库和数据表选择成功后,按MFC向导对话框中“完成”按钮以及最后的“确定”按钮,就进入下面的C++的MFC开发环境。可以用“工具箱”中的控件在界面上设计了,例如控件(标签文本框、组框、命令按钮,在工具箱中的图标依次是)。
注意:“W”将数据库与表单视图连接在一起,或者说建立了“表单视图与记录集”之间的联系,系统自动产生了程序操作数据库的指针m_pSet->。
4
.1 m_pSet->()
1 激活界面中控件
UpdateData( TRUE ); 激活表单中控件,例如m_Name、m_Number、m_Result…等。
UpdateData( FALSE ); 使用户能看见表单视图(界面上)当前记录的m_Name、m_Number、…等的变化
2数据指针的位置的确定
m_pSet->IsEOF( ) 是否遇到数据表,“是”返回值为。
m_pSet->IsBOF( ) 是否为数据表文件。
m_pSet->MoveFirst( ); 指向1记录
m_pSet->MoveNext( ); 指向当前位置的记录
m_pSet->MovePrev( ); 指向当前位置的记录
m_pSet->MoveLast( ); 指向记录
m_pSet->m_字段名;(例如:学号字段,m_pSet->m_number)
3在数据库中添加一个新记录
m_pSet->AddNew( ); 的功能函数
在此语句之后,书写向数据库追加的记录的各个字段。最后写下面两句换话:
m_pSet->Update( ) ; 新记录写入数据库的数据表。
m_pSet->Requery( ); 刷新记录集。这将改动“物理”数据库。
4删除数据库中当前显示的记录
m_pSet->Delete( ); 删除“”“<>”
5执行“统计查询”类命令的一般程序模式
在对话框上添加一个“”,再创建该命令的(Events...),在函数体内书写程序,组织“”等操作。例如:
m_pSet->MoveFirst( );
while( !m_pSet->IsEOF() ) 没有遇到数据表尾时继续循环。
{ 统计和判断语句;
放结果信息的控件m_Result 成员变量;
MessageBox("按确定键看下一个记录","对话框", 0 );
m_pSet->MoveNext( );
}
.2
引用系统内部的对话框,下面的是它们一般
格式
pdf格式笔记格式下载页码格式下载公文格式下载简报格式下载
:
AfxMessageBox("提示信息", int, int ); 窗口标题不能自己确定
MessageBox("提示信息","窗口标题", int ); 可以自己确定窗口标题
1AfxMessageBox("窗口内提示信息,标题默认为项目名", 100, 10 ); 返回值是整数。
有“是(Y)”、“否(N)” 两个按钮,选择“是(Y)”函数返回值 6、 “否(N)”函数返回值 7。
2MessageBox("窗口内提示信息","窗口标题", 0 ); 只有一个“确定”按钮,返回值是整数1。
int flag = MessageBox( "窗口内提示信息", "窗口标题",100 );
有“是(Y)”、“否(N)” 两个按钮,选择“是(Y)”函数返回值 6、 “否(N)”函数返回值 7。
用户在程序中用if判flag中保存的返回值 ,决定执行“则”或“否则”动作。
3利用字符串“并置”运算,将记录的各个字段“合并”到1个字符串变量中,放到MessageBox()或者AfxMessageBox()中,作为提示信息随时输出。
例如:CString info="\0";
info = ":\t" + m_pSet->m_number + "\n";
info += ":\t" + m_pSet->m_name + "\n";
info += ":\t" + m_pSet->m_sex + "\n";
info += ":\t" + m_pSet->m_column1 + "\n";
info += ":\t" + m_pSet->m_birthdate + "\n";
if( 查询条件满足 )
{ MessageBox( info, "",100 ); return; }
.3
在C++环境中创建的“项目(Project)”,例如“学生成绩管理”工程,做“编译、连接、运行”时,结果显示为:
在标题栏上出现了“”字样。我们希望将“–学生成绩管理”中的“无标题–”去掉,改成设计者,例如换成为“学生成绩管理”。
在Class View 页,展开类CMyApp(因为我们用汉字“学生成绩管理”作为工程名,C++不识别“汉字标识符”,所以工程类名用My代替,全名是CMyApp),双击函数InitInstance。双击函数InitInstance之后,在弹出的源码文档中,找到函数InitInstance的下面显示位置(该函数尾部),添加“”的一行:
m_pMainWnd->SetWindowText("学生成绩管理");//新加的
再重新“编译、连接、运行”,结果的标题就变成为希望的了:
.4 (main()函数所在地)中。
这是开发较复杂项目时必然出现的问题。例如,对一个数据表作记录添加时,用另一个对话框接受用户输入的字段值,在调用处启动该对话框中,然后引用其控件的,再做记录添加操作。同样,做不同数据表操作时,有时也需要“交流信息”,也可以用这样办法来实现。
1在主调文档中用Insert Dialog新建立一个对话框,命名为Dlg1Name。
在VC++的工作空间视窗中选择“资源页ResourceView”,然后“右击”Dialog,在弹出的快捷菜单中选择“Insert Dialog”(见下图),则出现一个对话框,按“Ctrl + W”键之后,给该对话框命名为Dlg1Name以后再插入对话框时,可以命名为Dlg2Name、Dlg3Name、Dlg4Name。
当单击选项“Insert Dialog”之后,出现只带“OK和Cancel”两个按钮的对话框,默认的ID是IDD_DIALOG1、默认的标题是Dialog
按“W”键之后,系统弹出“Adding a Class”对话框,按“OK”按钮,则出现给该对话框资源命名字的“New Class”对话框,我们输入Dlg1Name(这个名字就是IDD_DIALOG1以资源方式出现在程序中,是程序员操作该对话框的手段,请见下面2点),然后按“OK”按钮:
2在IDD_DIALOG1对话框中设置“标签、文本框”等控件,并将控件映射到对应的,见下图。在主调处设计一个命令按钮,在命令按钮的事件函数中说明“Dlg1Name dlg;”对象,请并用对象dlg去操作IDD_DIALOG1对话框中的成员变量。
例如:对话框中的成员变量是:m_number和m_name
用对象操作是:dlg.m_number 和 dlg.m_name
#include "Dlg1Name.h"
void CMyView::OnButtonAdd( )
{ //记录添加模块,操作另一个对话框:
Dlg1Name dlg;
if( dlg.DoModal()==IDOK )
{ //按IDD_DIALOG1 “OK”按钮返回之后:
m_pSet->AddNew( ); //先执行追加新记录的功能函数AddNew()
m_pSet->m_number = dlg.m_number;//给学号、姓名字段赋值:
m_pSet->m_name = dlg.m_name;
//... ... 其他字段
m_pSet->Update( ) ; //新记录写入数据库的数据表
m_pSet->Requery( ); //刷新记录集。这将改动"物理"数据库。
}
}
3将新插入对话框(例如IDD_DIALOG1)的默认“Dialog”改成有实际意义的窗口标题。
例如:这是做记录插入用的对话框,所以对话框标题取作“添加记录对话框”。在该对话框的属性窗口(Dialog Properties)中,写上新的标题:
.5 (如)ODBC
1连接主控文档m_pSet->所指向的那个数据表时
先找到项目的“头文件(“学生成绩管理Set.h)”,展示了其中的“类名(CMySet)”,然后在新建对话框的.CPP文件中添加:
#include “学生成绩管理Set.h”
CMySet pset ;
通过对象pset即可操作字段名和记录移动等功能函数。
例如: pset.Open( );
和pset.m_number;
2使用系统基类CRecordset为新建对话框连接ODBC中的其他数据表
按“Ctrl + W”键,进入MFC Class Wizard,然后操做下面三步:
当第3步点击“New...”之后,弹出下面“New Class”对话框,操作(1)和(2)之后按“OK”:
上面按“OK”按钮之后,弹出“DataBase Options”对话框,这时要选择数据库、点动态使用。然后按该对话框左上角的“OK”按钮,进入(Select Database Tables)选择数据库中某个数据表的对话框,选定一个表。
要操作对话框Dlg1Name中已经连接上的命名为Dlg1Dataset数据表时,可用下面代码:
#include "Dlg1Dataset.h"
Dlg1Dataset pset;
pset.Open( );
pset.m_;
pset.m_ MoveNextt( ); ....
.6 “”,C++
m_pSet->是MFC AppWizard建立的,目的是建立“表单视图与记录集”之间的联系。但是,有一个“弱点”:当ACCESS库或SQL库中的数据表“”,则VC++中表单文档就不识别了。
m_pSet->是唯一的。P254图
8.14。 可以在MFC AppWizard的环境下,用Update Column与Bind All按钮来重新修改。要注意的是“只能用于开始创建项目时的带数据库的、含main()函数的单个文档”,因为指针
1将原来的“Member Variables”的成员变量(上图CYYYSet下的),用Delete Variable命令一一删
除,然后再单击Update Column按钮,重新从数据源ODBC中选择“数据库”和“表”。
2对第1步重新连接的数据库及表,单击Bind All按钮,则重新添加相关联字段。
.7 Project“”
例如在MFC环境下,往项目“学生成绩管理”对话框的工具箱中添加ADO Data 控件,过程为:
使用C++菜单“工程添加工程Components and controls …”,则弹出Components and controls Gallery对话框;
在该对话框中双击“Registered Activex Controls”文件夹;在展开的Registered Activex Controls文件夹内,使用滚动条寻找所需要的控件。例如,对应的文件为Microsoft ADO Data Control,version 6.0 OLEDB。
找到控件所对应的文件之后,点击该文件名(即选中),然后按“Insert”按钮(这之后的系统询问,一律使用默认值),最后将控件插入到“”之中,方便使用。
注意:往工具箱内添加其他控件的做法,与上面操作过程类似。
DataGrid控件: 对应文件(Microsoft DataGrid Control,version 6.0 OLEDB)
DataCombo控件:对应文件(Microsoft DataCombo Control,version 6.0 OLEDB)
Web控件: 对应文件(Microsoft Web Browser )
.8 标签(Static text )控件建立时,系统默认的ID是“IDC_STATIC”。在它的属性对话框中,要给
它一个命名,比如是“IDC_STATIC_QUERY”。注:增加英文词Query是为了可读性
在“查询记录”所对应的加下面(:只有命令按钮的事件函数内才
能用):
CStatic *pwnd=(CStatic*)GetDlgItem( IDC_STATIC_ QUERY );
pwnd->SetWindowText("输入要查询的学号:");
这样,“查询记录”运行时,动态文本信息将送进IDC_STATIC_ QUERY 的框架内。 更换组框(Group Box)的标题
其它“命令按钮”使用时。 void CEx_MCIView::OnButtonTop( )
{ CStatic *pwnd=(CStatic*)GetDlgItem( IDC_STATIC_top );
pwnd->SetWindowText("");
}
5 MFC AppWizardADO .1 m_pSet->ADO
。
1采用“.4”节的做法,在C++Project。
采用“.4”节的做法,在插入新的对话框并且命名字。
采用“.7”节做法,在项目(Project)的“工具箱”中添加ADO Data控件DataGrid控件。在新建对话框中设置ADOData控件和DataGrid控件,状态如下:
查看对话框上的控件Adodc1或DataGrid1的属性时,右击该控件,在弹出的窗口内“属性”:
这就打开控件属性窗口(Properties),在此对控件做下面的属性(Property )值设置:
设置控件Adodc1和DataGrid1的属性,。
在Adodc1属性对话框中:ConnectionString 属性填:DSN=StudentAndJava
记录源(RecordSource) 属性填:命令方式和访问的表
而DataGrid1的属性:DataSource 属性值取IDC_ADODC1控件所绑定的。
4 用命令方式例如下面代码
#include "Dlg2Name.h"
void CMyView::OnButtonQuery( )
{ Dlg2Name dlg;
if( dlg.DoModal( )==IDOK )
{ AfxMessageBox("打开数据编辑对话框");
UpdateData(FALSE);
}
}
5.2
。
1DataGrid属性选择(下图)。
2主空界面的m_pSet->数据库表和DataGrid操作的数据库表是同一个,则两个窗口可以同步。
ADO操作的数据库,既可以是ACCESS、也可以是SQL Server,模式一样。
注意:因为做“记录追加、记录删除”时,涉及“数据库的表”物理改动,有一个响应时间问题,所以用“新建对话框”教适宜,主控模块用“命令调用”方式,启动一次对话框,做一个记录的“追加”或者“删除”操作。
由控件提供数据源的列表能够提供记录“添加、删除、更新(即修改)”等操作,见下图的标识,应该充分利用它。
4用DataGrid列表作记录删除时,先用鼠标器选择要删除的记录行(则行变为有底色),然后按人
热键“DELETE”。主调对话框也被删除。
5用DataGrid列表做记录插入时,先用鼠标器指到“*”标记行,然后将光标移进“相关字段”并输入新数据。记录录入完成后,按“OK”按钮:主调对话框可以看到新记录。
6在DataGrid的列表中,做记录字段值修改时,随时可以用鼠标器点击到“目标字段”,然后光标在“该字段”闪动,用户进行修改字段数据。修改完成后,按“OK”按钮返回。
5.3 “
。
做法:用Insert Dialog 插入一个对话框,命名为Dlg3Name,标题是“数据查询和统计对话框”,在此设计查询键、查询命令。查询命令的事件处理函数,完成被查询对象的操作,即对相关数据表的访问。
源代码:
1主控处“查询记录”事件的程序: #include "Dlg3Name.h"
void CMyView::OnButtonQuery( )
{ Dlg3Name dlg;
dlg.DoModal( );
}
2“数据查询和统计对话框”中查询命令的程序:
#include "学生成绩管理Set.h"
void Dlg3Name::OnButtonQuery( ) {//对话框3中,访问主控界面的数据库
CMySet pset;
UpdateData(TRUE);
pset.Open();
pset.MoveFirst();
while ( !pset.IsEOF() )
{
if ( m_number==pset.m_number || m_name==pset.m_name )
{ CString info="\0"; 查询条件满足
info = "学号:\t" + pset.m_number + "\n";
info += "姓名:\t" + pset.m_name + "\n";
info += "性别:\t" + pset.m_sex + "\n";
info += "出生日期:\t" + pset.m_birthdate + "\n";
info += "专业:\t" + pset.m_specialty + "\n";
MessageBox( info, "查询到的记录如下:",100 );
return;
}else pset.MoveNext( );
}
}
然虽在一个“主控文档窗口”内 ,既可以用指针操作数据库,同时也可以用ADO控件操作同一数据库,只因为DataGrid控件做“记录追加、记录删除”时要物理地修改数据库,有时运行不正常。因为ADO和DataGrid的“游标”定位方式,与操有差异的。
当DataGrid表中,要将原来的英文字段名(如CourseNumber)换成汉字输出时,应在Adodc1控件的“记录源”选项中,用命令SQL语句,一般格式为:
SELECT CourseNumber AS , CourseName AS FORM CourseTable
5.4 引用ADO 数据源的控件、控件的使用方法。
C++系统中,一个对话框中可以设置多个Adodc ,但是一个Adodc 只能连接数据库的一
个()表。
和操作数据表,像控洋那样,也要依靠Adodc 连接的数据库。
所以,要想访问不同的数据表,必须各自用Adodc1 。
右击“”控件,在掸出快捷菜单中取“属性(R)...DataList Object”,则有:
在属性“RowSource”项下指定“IDC ADODC1”;在属性“ListField”项下选择被LIST的
字段(例如“商品名”,但是一个控件)。
实现“”控件的使用时,类似控件的做法。将商品编号字段“shangpinID”放入:
6
在“5.3”节已经讲到:控件的“允许添加、允许删除、允许更新”,能方便完成记录追加、记录删除和字段值修改。但是,对数据库的大量和操作不能完成,这需要程序员自己来设计程序了,6。
做法:用Insert Dialog 插入一个对话框,命名为Dlg3Name,标题是“数据查询和统计对话框”,在
当没有DataGrid列表自动提供的操作功能的时候,自己书写功能程序。这是要学会的。
此设计查询键、查询命令。查询命令的事件处理函数,完成被查询对象的操作,即对相关数据表的访问。 .1
m_pSet->。
这样做的要求是:
1记录查询时:必须是先赋给了查询键值。若执行“查询”命令时没有输入查询键值,则不执行“查询的模块程序”而返回。
2删除当前记录时:必须是浏览到了要删除的记录。若执行“删除”命令时没有指定到记录位置就返回,则不执行“m_pSet->Delete( );”命令。
3记录追加时:仍然是采用在另一个对话框中交互式地键入各字段数据,存放在对话框的各个成员变量中,从对话框返回后,定义该对话框的对象dlg,通过dlg引用成员变量程序执行,在m_pSet->AddNew( )命令执行后,依次将“dlg.成员变量 赋值给 m_pSet->字段名”。
4修改记录时:即做当前记录的相关字段内容修改。在当前记录中,鼠标器点击的字段,光标进入,
则键入新数据,然后执行命令m_pSet->Edit( ),则数据库被物理地修改。如果你点击“修改记录”命令之前,没有指定到记录位置、或者没有修改当前记录的字段值,则不执行命令m_pSet->Edit( )。
:
void CMyView::OnButtonQuery( )
{ CRecordsetStatus status;
m_pSet->GetStatus(status); //必须及时跟踪指针m_pSet->所指的记录号
UpdateData(TRUE);//激活表单控件(例如m_strQuery)
m_strQuery.TrimLeft( );
if ( m_strQuery.IsEmpty() )
{ MessageBox("你输入的查询学号为空!");
m_recordNO = status.m_lCurrentRecord - 1; //返回值0时是#1号,所以给-1
UpdateData(FALSE);
return;
}
else //自己用循环查找,不用书上的:
{ m_pSet->MoveFirst( );
while( !m_pSet->IsEOF( ) )
{ m_pSet->GetStatus(status); //及时索引当前记录号
m_recordNO = status.m_lCurrentRecord + 1;
if( m_strQuery==m_pSet->m_number )
{ UpdateData(FALSE);return; }
//找到,自动更新表单控件的显示内容为当前记录,然后退出。
else m_pSet->MoveNext( );
}
MessageBox("没有查找到你要查询的学号记录!");//循环内没正常退出,表明到文件尾还没找到。
m_pSet->MoveFirst( ); //让指针移到开头为别处使用
return;
}
}
// CStatic *pwnd=(CStatic*)GetDlgItem( IDC_STATIC_QUERY );
// pwnd->SetWindowText("输入要查询的学号:");
// int flag=MessageBox( "?","询问对话框",100 ); // if( flag!=6 )return; //执行“查询”命令时没给查询条件则返回。 atoi(str)、atol(str)依次将串转换为int、long;而atof(str)转换double或float型。
// 利用字符串“并置”运算,将记录的各个字段“合并”到1个串变量中,放到MessageBox()中,作为提示信息及时输出: CString info="\0";
info = ":\t" + m_pSet->m_number + "\n";
info += ":\t" + m_pSet->m_name + "\n";
MessageBox( info, "",100 ); return;
删除:
删除记录程序,对用户的当前指定记录(表单视图中正在显示的)做物理删除操作。为此,对“
”,用MessageBox("你是否浏览到了要删除的记录?","删除询问",100)来询问;对“”,
用MessageBox("你确实要删除第(" + info +")号记录吗?", "确认删除",100 )来做人机交互。
void CMyView::OnButtonDelete( )
{ int tag=MessageBox("你是否浏览到了要删除的记录?","删除询问",100);
if( tag != 6 ) return; //执行"删除"命令时没有浏览到指定到记录位置,则返回。
CRecordsetStatus status;
CString info="0";
long num=0;
m_pSet->GetStatus(status);
num = status.m_lCurrentRecord;//获得当前记录号,0为#1号
num++; //使得#1号就是1。""。
while( num != 0 )
{ int x= num % 10;
info += x + '0'; //转换为字符,并且"并置"到info
num = num/10;
}
int flag= MessageBox("你确实要删除第(" + info +")号记录吗?", "确认删除",100 );
if( flag==6 )
{ m_pSet->Delete( );
m_pSet->Requery(); // 刷新记录,重新整里盘文件。可以。
//不能在《删除》时使用命令:m_pSet->Update( );
// if( )s1 else s2,产生"<>"。
if( status.m_lCurrentRecord==0 ) m_pSet->MoveNext();
else m_pSet->MoveFirst( );
UpdateData(FALSE);
}else return;
}
: 追加记录
对数据库做“记录追加”时,涉及值的录入与修改,用另一个对话框做交互式地输入或修改各字段的数据,是最合适的。
假设做此工作的对话框的ID是IDD_DIALOG1,我们给该对话框命名的类名是 Dlg1Name,就可在对话框中做的数据库初始化,在确认完全正确之后,,通过定义了Dlg1Name的对象dlg,将“dlg.”的数据值赋值给“m_pSet->m_字段名”。
#include "Dlg1Name.h"
void CMyView::OnButtonAdd( )
{ //记录添加模块,操作另一个对话框:
Dlg1Name dlg;
if( dlg.DoModal()==IDOK )
{ m_pSet->AddNew( ); //先执行追加新记录的功能函数AddNew()
m_pSet->m_number = dlg.m_number;//给学号、姓名字段赋值:
m_pSet->m_name = dlg.m_name;
m_pSet->m_sex = dlg.m_sex;
m_pSet->m_birthdate= dlg.m_birthdate;
m_pSet->m_height = dlg.m_height;
m_pSet->m_specialty= dlg.m_specialty;
m_pSet->Update( ) ; //新记录写入数据库的数据表
m_pSet->Requery( ); //刷新记录集。这将改动"物理"数据库。
}else return;
}
修改记录
设计有“修改记录”命令按钮,要修改记录的“记录号”指示器。
修改当前记录的字段值的模块:
?在用m_pSet->浏览记录时,其特性是可自然地接收用户对各字段值的修改并且写入盘文件。
我们采用常规的方法:新建一个对话框(例如类名是Dlg5Name),在其中做记录修改操作,过程是:
(1)用户在主界面用m_pSet->浏览的时候,所选定的记录是要修改的当前记录,界面上设置了指示
器。当按 “修改记录”命令按钮时,首先询问:
int tag=MessageBox( "是你选定的要修改的记录号吗?","询问对话框",100);
(2)当回答“(y)”时,将当前记录的各字段值拷贝到要打开的对话框的成员变量:
m_pSet->字段名 dlg.成员变量
在对话框中显示原来数据,并提示你修改。修改谁,用鼠标点击,光标出现,可以编辑。
(3)修改成功之后,若按对话框的“OK”按钮,又返回到主界面,再对m_pSet->所指示的当前记录重新赋值:
dlg.成员变量 m_pSet->字段名
?上面使用m_pSet->指针的往返过程中,因为用户未再移动“指针”,所以记录位置未改动。这一点,
是我们随时可指定被修该记录号的重要环节。
这个程序“长一点”了,但要点只3句,多数是重复语句。
#include "Dlg5Name.h"
void CMyView::OnButtonModify( )
{ //执行"修改记录"命令之前,下面4行是及时跟踪指针m_pSet->移动时所指定的记录号:
CRecordsetStatus status;
m_pSet->GetStatus(status);
m_currentRecordNo = status.m_lCurrentRecord + 1; //因#1号是0,所以+1,变成物理#1
UpdateData(FALSE);
Dlg5Name dlg; // 工作对话框开始的程序:
int tag=MessageBox( "是你选定的要修改的记录号吗?","询问对话框",100);
if( tag==6 )
{ //(1)将当前记录的各字段值拷贝到对话框的对应成员变量上:
UpdateData(TRUE);//激活对话框控件
dlg.m_number = m_pSet->m_number;
dlg.m_name = m_pSet->m_name;
dlg.m_sex = m_pSet->m_sex;
dlg.m_birthdate = m_pSet->m_birthdate;
dlg.m_height = m_pSet->m_height;
dlg.m_specialty = m_pSet->m_specialty;
UpdateData(FALSE);//控件上的改变显示出来
//(2)按对话框的“OK”按钮时返回,返回之后重置数据库该记录的修改值:
dlg.DoModal( );
m_pSet->Edit();
m_pSet->m_number = dlg.m_number ;
m_pSet->m_name = dlg.m_name ;
m_pSet->m_sex = dlg.m_sex ;
m_pSet->m_birthdate = dlg.m_birthdate ;
m_pSet->m_height = dlg.m_height ;
m_pSet->m_specialty = dlg.m_specialty ;
m_pSet->Update( ) ;
m_pSet->Requery( );
UpdateData(FALSE);
}
else MessageBox( "在记录修改对话框中你没有按[OK]按钮!",0);
return;
}
可以在例如
“查询”和“执行”命令的代码是类似的:
#include "学生成绩管理Set.h"
void Dlg3Name::OnButtonQuery( ) {//对话框3中,访问主控界面的数据库
CMySet pset;
UpdateData(TRUE);
pset.Open();
pset.MoveFirst( );
while ( !pset.IsEOF() )
{
if( m_number==pset.m_number || m_name==pset.m_name )
{ CString info="\0";
info = "学号:\t" + pset.m_number + "\n"; info += "姓名:\t" + pset.m_name + "\n";
info += "性别:\t" + pset.m_sex + "\n"; info += "出生日期:\t" + pset.m_birthdate + "\n";
info += "专业:\t" + pset.m_specialty + "\n";
MessageBox( info, "查询到的记录如下:",100 );
return;
}else pset.MoveNext( );
}
}
void Dlg3Name::OnButtonTotal( ) {// 统计类似查询,都要从头到尾浏览整个表。
// 对每个记录按条件统计:
CMySet pset;
UpdateData(TRUE);
m_birthdate=0; m_sex=0;
pset.Open();
pset.MoveFirst();
while ( !pset.IsEOF() )
{ if( pset.m_birthdate>="1980-1-1" )m_birthdate++;
if( pset.m_sex=="男" )m_sex++;
UpdateData(FALSE);
pset.MoveNext();
} .2
} 用菜单方式调用不同对话框,各对话框自己连接一个数据的不同数据表,而不
同数据表的常规操作(仍然是:
7
7.1
用Insert Dialog 插入一个对话框,命名为Dlg4Name,标题是“多媒体对话框”。在对话框设置一个web控件,对应的成员变量名是m_WebBrowser;再设置一个命令按钮(启动Web),命令的事件处理函数是完成多媒体文件的和。
void Dlg4Name::OnButtonWeb( )
{ CFileDialog dlg(TRUE);
dlg.m_ofn.lpstrFilter = "\\*.gif; *.jpg; *.html; *.wav; *.flash";
if ( dlg.DoModal( ) ==IDOK )
{ COleVariant vt( dlg.GetPathName( ) );
VARIANT bt; //m_WebBrowserWeb
m_WebBrowser.Navigate2( vt, &bt, &bt, &bt, &bt );
}
}
7.2 C++
清华教材299 [9.4] VC++MCIWnd。
MCIWndVC++
AVIMP3WAVMIDI…”
11M26(当2使用数据库时,已用了)
2StdAfx.h
#ifndef _AFX_NO_AFXCMN_SUPPORT //
#include
//(2)
#pragma comment(lib,"vfw32.lib")
3CEx_MCIApp :: InitInstance (在类Cex_MCIApp的成员函数InitInstance 内
添加下面一句话:)
if ( !MCIWndRegisterClass( ) ) return FALSE;
4 CEx_MCIView m_hMyMCIwnd class CEx_MCIView : public CView
{ protected:
CEx_MCIView( );
DECLARE_DYNCREATE(CEx_MCIView)
public:
CEx_MCIDoc* GetDocument( ); //
HWND m_hMyMCIwnd ;
… …. …
5 MFC ClassWizard CEx_MCIView OnInitialUpdate
按CTRL+W键,进入MFC ClassWizard环境,Class name下找到CEx_MCIView,Messages下找到OnInitialUpdate, 按Add Function 。见下图箭头示。
m_hMyMCIwnd = MCIWndCreate( m_hWnd,AfxGetInstanceHandle(),MCIWNDF_NOTIFYSIZE |
MCIWNDF_NOERRORDLG |WS_CHILD | WS_VISIBLE,NULL);
if( m_hMyMCIwnd == NULL )return;
const CString &filename = GetDocument()->GetPathName();
if( filename.GetLength() > 0 )
MCIWndOpen( m_hMyMCIwnd, (LPCSTR)filename,0 );
当前面的2使用数据库时,则函数OnInitialUpdate已被系统建立,只需要在原代码的后面添加上这几句话,即可以了。
6CEx_MCIView m_hMyMCIwnd 初始化为NULL。
7MCIWnd MCIWNDM_NOTIFYSIZE (窗口大小改变),
。在头文件Ex_MCIView.h下图右边箭头位置
afx_msg LONG OnNotifySize(UINT wParam, LONG lParam); //
8Ex_MCIView.cpp要加源代码:
ON_MESSAGE(MCIWNDM_NOTIFYSIZE, OnNotifySize ) //
9CEx_MCIView.OnNotifySizeMCIWnd大小。现场如下图所示(即在CEx_MCIView.cpp的尾部,我们自己直接添加OnNotifySize函数模块整体)
所添加的OnNotifySize函数的源代码为:
LONG CEx_MCIView::OnNotifySize( UINT wParam, LONG lParam ) //
{ CRect rc;
CFrameWnd *pParent = GetParentFrame( ); //
if( m_hMyMCIwnd )
{ ::GetWindowRect( m_hMyMCIwnd, rc );
pParent->CalcWindowRect( rc,CWnd::adjustBorder );
CSize size( rc.Width( ), rc.Height( ) );
if( GetExStyle( ) & WS_EX_CLIENTEDGE )
{ size.cx += 4; size.cy += 4; }
pParent->SetWindowPos(NULL, 0, 0, size.cx, size.cy,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE ); }
else
{ pParent->SetWindowPos( NULL,0,0, 200, 160,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE ); }
return 1;
}
10VC/AVIMP3WAV…”
按“播放”按钮。