教学材料《Visual C++程序》-第4章-3_第1页
教学材料《Visual C++程序》-第4章-3_第2页
教学材料《Visual C++程序》-第4章-3_第3页
教学材料《Visual C++程序》-第4章-3_第4页
教学材料《Visual C++程序》-第4章-3_第5页
已阅读5页,还剩116页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

4.7章后实训实训1学生档案管理本软件全面记录了有关学生(职工、职员等)档案的各方面信息,完全可以在实际中应用。程序运行后,先一次性输入年级、专业、班级;然后以班级为单位,逐个输入学生姓名和学生的各项自然情况;特别是在学生电子档案编辑框中,可以任意书写学生的多方面信息,像在长长的纸上书写一样,其独有的特点是不受表格等方面的限制。下一页返回4.7章后实训程序设计步骤如下:(1)建一个单文档应用程序,名为:大学生档案。第6步选取CFormView(可以在主窗口内添加控件)作为视图的基类。(2)参照图4.43添加表4.23所示的控件。(3)给文档类添加成员变量。文档类中的数据就是要操作的对象,所以必须将其定义为文档类的数据成员。

1)在文档类大学生档案Doc.h文件中的public下定义一个结构体。上一页下一页返回4.7章后实训classCMyDoc:publicCDocument{……public:struct {charclas[10];//级

charpro[20];//专业

charcla[20];//班及学习性质

charname[20];//对应姓名

charstuid[20];//学号

charsex[10];//性别

charage[20];//出生年月

chartel[20];//电话

charpos[20];//职务

charschool[9999];//学生电子档案,最多写9999个字符

}m_student[120];//一个班最多120个学生

……}上一页下一页返回4.7章后实训2)初始化变量在文档类执行文件“大学生档案Doc.cpp”中的构造函数中,对这些变量进行初始化。for(inti=0;i<120;i++){m_student[i].clas[0]=NULL;//级

m_student[i].pro[0]=NULL;//专业

m_student[i].cla[0]=NULL;//班及学习性质

m_student[i].name[0]=NULL;//对应姓名

m_student[i].stuid[0]=NULL;//学号

m_student[i].sex[0]=NULL;//性别

m_student[i].age[0]=NULL;//出生年月

m_student[i].tel[0]=NULL;//电话

m_student[i].pos[0]=NULL;//职务

m_student[i].school[0]=NULL;//学生电子档案}上一页下一页返回4.7章后实训(4)给视图类添加成员变量和记录姓名的变量。视图类负责屏幕的显示内容。在此要加入的视图类数据成员实际上就是文档类的数据成员在屏幕上的映射。而将视图类中的变量显示在屏幕上最简捷的方法是将变量与某编辑控件关联,即为编辑框引入变量。

1)利用MFCClassWizard为IDD_MY_FORM对话框中的各个控件引入表4.24所示的变量(在view类中),操作如下。选择View→ClassWizard命令,打开MemberVariables(加成员变量)选项卡,在Classname下拉列表中选择CMyView(在视图里)选项并在下面的列表框中选中IDC_COMBO选项,单击AddVariable…按钮,输入成员变量名m_noList。注意类型用Category:下拉control变为CComboBox类型(其他变量的类型可下拉VariableType改变成CString类型等)。上一页下一页返回4.7章后实训2)在CMyView.h的public下添加一个记录姓名的变量。classCMyView:publicCFormView{intm_nCurrentNo;//用来指示数组的下标,即存放索引号用。在私有模式下。

….}(5)变量初始化。1)修改OnInitialUpdate()函数,做如下2个工作。①设置ComboBox“姓名”②在View.cpp里将文档类中变量赋给对应的编辑控件变量。上一页下一页返回4.7章后实训voidCMyView::OnInitialUpdate(){ CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit();CMyDoc*pDoc=GetDocument();//获得文档窗口指针m_noList.ResetContent();//删除组合框的全部项和编辑文本for(inti=0;i<120;i++){//如果对应姓名空,则向组合框尾部添加对应姓名字符串(nIndex=-1)if(strcmp(pDoc->m_student[i].name,""))//将对应的姓名pDoc->m_student[i].name,索引号nIndex=-1添到组合框末尾m_noList.InsertString(-1,pDoc->m_student[i].name);//文档变量的姓名加到组合框末尾}上一页下一页返回4.7章后实训m_noList.SetCurSel(0);//设置当前选择项(参数为当前选择项索引)//下面是组合框的姓名所对应的各个编辑框显示内容

m_clas=pDoc->m_student[0].clas;//级

m_pro=pDoc->m_student[0].pro;//专业

m_cla=pDoc->m_student[0].cla;//班及学习性质

m_name=pDoc->m_student[0].name;//对应姓名

m_stuid=pDoc->m_student[0].stuid;//学号

m_sex=pDoc->m_student[0].sex;//性别

m_age=pDoc->m_student[0].age;//出生年月

m_tel=pDoc->m_student[0].tel;//电话

m_pos=pDoc->m_student[0].pos;//职务

m_school=pDoc->m_student[0].school;//学生电子档案

UpdateData(false);//把程序中改变的值更新到控件中去}上一页下一页返回4.7章后实训说明:①GetParentFrame()得到主框架窗口。②RecalcLayout是CFrameWnd定义的虚拟函数,边框窗口在必要的时候调用虚拟函数。

RecalcLayout来重新放置它的控制条和客户窗口,例如在创建窗口、响应消息WM_SIZE时CFrameWnd::RecalcLayout调用CWnd的成员函数RepositionBars完成控制条窗口的重新放置。③ResizeParentToFit()使得父窗口从新调整大小。④InsertString(intnIndex,LPCTSTRlpszString);//在组合框的指定位置插入字符串,nIndex=-1是索引号处为-1,表示字符串加到组合框末尾。上一页下一页返回4.7章后实训⑤UpdateData(TRUE)把在控件中输入的值更新到变量中去,当然要为控件关联上变量才行。UpdateData(FALSE)把程序中改变的值更新到控件中去。UpdateData刷新的是当前对话框。2)在构造函数View.cpp里对变量m_nCurrentNo(数组下标变量,即索引号)初始化。CMyView::CMyView():CFormView(CMyView::IDD){ ……. m_nCurrentNo=0;//存放索引号变量初值赋0}上一页下一页返回4.7章后实训(6)用另一个对话框输入学生的姓名

1)插入一个对话框,ID为默认即IDD_DIALOG1,将OK改为“确定”,将CANCEL改为“取消”,拖一个静态文本static输入“请逐个输入学生姓名”,拖一个编辑框EditBox,ID为IDC_EDIT_NUM。

2)为这个对话框建类。双击这个对话框单击OK按钮在类名处输入CinDlog单击OK按钮退出。

3)用View→ClassWizard命令为CinDlog对话框上的编辑框IDC_EDIT_NUM建成员变量,变量名为m_num,类型为CString。上一页下一页返回4.7章后实训(7)弹出对话框并完成其编辑框向组框加入姓名的工作。1)将BUTTON1映射到View.cpp中,并将对话框类inDlog包含在View.cpp中,即在View.cpp文件的前头输入#include"inDlog.h"(注意:要输入在#include"stdafx.h"下面)2)在voidCMy1View::OnButton1()加入下列代码:voidCMy1View::OnButton1(){UpdateData(true);//把你在控件中输入的值更新到你的变量中去//将姓名插入到组合框CinDlogdlg;上一页下一页返回4.7章后实训dlg.m_num.TrimLeft();//对话框上输入姓名的编辑框对应的变量,即删除编辑框左空格

dlg.m_num.TrimRight();//删除编辑框右空格

if(IDOK==dlg.DoModal()){if(dlg.m_num.IsEmpty())//编辑框输入姓名没有?如果没输入,输出姓名不能为空信息

{MessageBox("姓名不能为空!!"); return; }上一页下一页返回4.7章后实训//在列表框中搜索与所给字符串精确匹配的第一项,精确查找字符串

if((m_noList.FindStringExact(-1,dlg.m_num))!=LB_ERR){MessageBox("列表中已有相同的姓名,不能添加!!");return;}}m_noList.InsertString(-1,dlg.m_num);//姓名不空、不同,就向组合框尾部添加新姓名

m_noList.SetCurSel(m_noList.GetCount()-1);//设置当前选择项(获取组合框的项数)

m_nCurrentNo=m_noList.GetCurSel();//获得当前选择项的索引上一页下一页返回4.7章后实训//m_clas="";//级和下面专业、班级这三个框不充零,一个班所有学生只写一次即可

//m_pro="";//专业

//m_cla="";//学习性质与班级

m_name="";//姓名

m_stuid="";//学号

m_sex="";//性别

m_age="";//出生年月

m_tel="";//电话

m_pos="";//职务

m_school="";//学生电子档案

UpdateData(false);//将控件的关联变量的值传给控件并改变控件状态

}上一页下一页返回4.7章后实训(8)处理数据记录的录入。实现数据记录的编辑,就是处理编辑框的EN_CHANGE(编辑框发生改变)事件。为此,要为编辑框的EN_CHANGE事件添加响应函数,且要在消息响应函数中编写将编辑框的数据传给文档类对应的变量代码。1)在视图类CMyView逐个添加以下消息响应函数:上一页下一页返回4.7章后实训上一页下一页返回控件ID消息(事件)函数说明IDC_EDIT_NAMEEN_CHANGEOnChangeEditName编辑与显示对应姓名IDC_EDIT_STUIDEN_CHANGEOnChangeEditStuid编辑与显示学号IDC_EDIT_CLASEN_CHANGEOnChangeEditClas编辑与显示级IDC_EDIT_PROEN_CHANGEOnChangeEditPro编辑与显示专业IDC_EDIT_CLAEN_CHANGEOnChangeEditCla编辑与显示班及学习性质IDC_EDIT_AGEEN_CHANGEOnChangeEditAge编辑显示出生年月IDC_EDIT_SCHOOLEN_CHANGEOnChangeEditSchool编辑显示学生电子档案IDC_EDIT_SEXEN_CHANGEOnChangeEditSex编辑与显示性别IDC_EDIT_TELEN_CHANGEOnChangeEditTel编辑与显示电话号码IDC_EDIT_POSEN_CHANGEOnChangeEditPos编辑与显示职务4.7章后实训2)为函数OnChangeEditName()加代码:voidCMyView::OnChangeEditName()//对应姓名{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据。//用控件的值去更新与之关联的变量,从而使m_name的值与其关联的对应姓名编辑框一致UpdateData(true);//下面的if语句是当对应的变量值有所改变时,进行值的传递,这样保证文档类与视图类相对应的变//量值时刻保持一致。同时设置数据修改标志,当用户退出程序时,程序会自动提示是否将数据保存

if(strcmp(pDoc->m_student[m_nCurrentNo].name,m_name)) {strcpy(pDoc->m_student[m_nCurrentNo].name,m_name); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训3)为OnChangeEditStuid()函数添代码:voidCMyView::OnChangeEditStuid()//学号{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据。//用控件的值去更新与之关联的变量,从而使m_stuid的值与其关联的学号编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].stuid,m_stuid)){strcpy(pDoc->m_student[m_nCurrentNo].stuid,m_stuid); pDoc->SetModifiedFlag();//设置数据修改标志}}上一页下一页返回4.7章后实训4)为OnChangeEditClas()函数添代码:voidCMyView::OnChangeEditClas()//级{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据。//用控件的值去更新与之关联的变量,从而使m_clas的值与其关联的级编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].clas,m_clas)) { strcpy(pDoc->m_student[m_nCurrentNo].clas,m_clas); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训5)为OnChargeEditPro()函数添代码:voidCMyView::OnChangeEditPro()//专业{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据。//用控件的值去更新与之关联的变量,从而使m_pro的值与其关联的专业编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].pro,m_pro)) {strcpy(pDoc->m_student[m_nCurrentNo].pro,m_pro); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训6)为OnChangeEditCla()函数添代码:voidCMyView::OnChangeEditCla()//班级及学习性质{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据。//用控件值去更新与之关联的变量,从而使m_cla的值与其关联的班及学习性质编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].cla,m_cla)) {strcpy(pDoc->m_student[m_nCurrentNo].cla,m_cla); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训7)为OnChangeEditAge()函数添代码:voidCMyView::OnChangeEditAge()//出生年月{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据//用控件的值去更新与之关联的变量,从而使m_age的值与其关联的出生年月编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].age,m_age)) {strcpy(pDoc->m_student[m_nCurrentNo].age,m_age); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训8)为OnChangeEditSchool()函数添代码:voidCMyView::OnChangeEditSchool()//编辑与显示学生电子档案{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据//用控件值去更新与之关联的变量,从而使m_school的值与其关联的学生情况编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].school,m_school)) { strcpy(pDoc->m_student[m_nCurrentNo].school,m_school); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训9)为OnChangeEditSex()函数添代码:voidCMyView::OnChangeEditSex()//性别{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据//用控件的值去更新与之关联的变量,从而使m_sex的值与其关联的性别编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].sex,m_sex)) {strcpy(pDoc->m_student[m_nCurrentNo].sex,m_sex); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训10)为OnChangeEditTel()函数添代码:voidCMyView::OnChangeEditTel()//电话{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据//用控件的值去更新与之关联的变量,从而使m_tel的值与其关联的电话编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].tel,m_tel)){strcpy(pDoc->m_student[m_nCurrentNo].tel,m_tel); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训11)为OnChangeEditPos()函数加代码:voidCMyView::OnChangeEditPos()//职务{CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据

//用控件的值去更新与之关联的变量,从而使m_pos的值与其关联的职务编辑框一致UpdateData(true);if(strcmp(pDoc->m_student[m_nCurrentNo].pos,m_pos)) { strcpy(pDoc->m_student[m_nCurrentNo].pos,m_pos); pDoc->SetModifiedFlag();//设置数据修改标志

}}上一页下一页返回4.7章后实训12)再在视图类CMyView为组合框IDC_COMBO添加CBN_SELCHANGE映射消息,并添加代码如下:voidCMyView::OnSelchangeCombo(){CMyDoc*pDoc=GetDocument();//获取指向文档类对象指针,用于操作文档类中数据。UpdateData(true);CinDlogdlg; m_nCurrentNo=m_noList.GetCurSel();//获得当前选择项的索引

inti=m_noList.GetCurSel(); m_clas=pDoc->m_student[m_nCurrentNo].clas;上一页下一页返回4.7章后实训m_pro=pDoc->m_student[m_nCurrentNo].pro; m_cla=pDoc->m_student[m_nCurrentNo].cla;dlg.m_num=pDoc->m_student[m_nCurrentNo].name;//文档的姓名赋给对话框上

//的编辑框m_name=pDoc->m_student[m_nCurrentNo].name;//文档姓名赋给视图成员变量

m_stuid=pDoc->m_student[m_nCurrentNo].stuid;//文档学号上一页下一页返回4.7章后实训m_sex=pDoc->m_student[m_nCurrentNo].sex;//文档性别

m_age=pDoc->m_student[m_nCurrentNo].age;//文档出生年月

m_tel=pDoc->m_student[m_nCurrentNo].tel;//文档电话

m_pos=pDoc->m_student[m_nCurrentNo].pos;//文档职务

m_school=pDoc->m_student[m_nCurrentNo].school;//文档学生电子档案

UpdateData(false);}上一页下一页返回4.7章后实训13)在视图类CMyView.h的public下加一位图类变量:CBitmapm_bitmap;//用于显示照片复制一个班同学的照片(类型为.bmp)到本项目的文件夹中(这里只复制5张),名字编号为:x0.bmp、x1.bmp、x2.bmp、x3.bmp、x4.bmp,照片的大小为166*149,用photoshop处理好,用前面例4.10的方法来显示照片,照片编号和程序中显示的照片号要一致。在上面组合框映射消息函数voidCMyView::OnSelchangeCombo()中接着添加下列代码(在该函数UpdateData(false)语句的上面):上一页下一页返回4.7章后实训voidCMyView::OnSelchangeCombo(){……m_school=pDoc->m_student[m_nCurrentNo].school;//文档学生电子档案if(i==0){CDC*pDC=GetDC();HBITMAPhBitmap=(HBITMAP)LoadImage(NULL,_T("x0.bmp"),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE| LR_LOADFROMFILE);上一页下一页返回4.7章后实训m_bitmap.Attach(hBitmap);BITMAPbm;m_bitmap.GetBitmap(&bm);//注意此处易出错,与你添加的图形有关。

CDCdcImage;if(!dcImage.CreateCompatibleDC(pDC))return;CBitmap*pOldBitmap=dcImage.SelectObject(&m_bitmap);//调用BitBlt()函数显示照片

pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcImage,0,0,SRCCOPY); dcImage.SelectObject(pOldBitmap);DeleteObject(m_bitmap.Detach());//释放位图存储空间}上一页下一页返回4.7章后实训if(i==1){CDC*pDC=GetDC();HBITMAPhBitmap=(HBITMAP)LoadImage(NULL,_T("x1.bmp"),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE| LR_LOADFROMFILE); m_bitmap.Attach(hBitmap); BITMAPbm;m_bitmap.GetBitmap(&bm);//注意此处易出错,与你添加的图形有关。

CDCdcImage;上一页下一页返回4.7章后实训 if(!dcImage.CreateCompatibleDC(pDC)) return; CBitmap*pOldBitmap=dcImage.SelectObject(&m_bitmap); pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcImage,0,0,SRCCOPY); //调用BitBlt()函数显示照片

dcImage.SelectObject(pOldBitmap); DeleteObject(m_bitmap.Detach());//释放位图存储空间}上一页下一页返回4.7章后实训if(i==2){CDC*pDC=GetDC(); HBITMAPhBitmap=(HBITMAP)LoadImage(NULL,_T("x2.bmp"), IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE| LR_LOADFROMFILE); m_bitmap.Attach(hBitmap); BITMAPbm;m_bitmap.GetBitmap(&bm);//注意此处易出错,与你添加的图形有关。

CDCdcImage;上一页下一页返回4.7章后实训if(!dcImage.CreateCompatibleDC(pDC)) return; CBitmap*pOldBitmap=dcImage.SelectObject(&m_bitmap); pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcImage,0,0,SRCCOPY); //调用BitBlt()函数显示照片

dcImage.SelectObject(pOldBitmap); DeleteObject(m_bitmap.Detach());//释放位图存储空间}上一页下一页返回4.7章后实训if(i==3){CDC*pDC=GetDC(); HBITMAPhBitmap=(HBITMAP)LoadImage(NULL,_T("x3.bmp"), IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE| LR_LOADFROMFILE); m_bitmap.Attach(hBitmap); BITMAPbm;m_bitmap.GetBitmap(&bm);//注意此处易出错,与你添加的图形有关。

CDCdcImage;上一页下一页返回4.7章后实训if(!dcImage.CreateCompatibleDC(pDC)) return; CBitmap*pOldBitmap=dcImage.SelectObject(&m_bitmap);//调用BitBlt()函数显示照片

pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcImage,0,0,SRCCOPY); dcImage.SelectObject(pOldBitmap); DeleteObject(m_bitmap.Detach());//释放位图存储空间}上一页下一页返回4.7章后实训if(i==4){CDC*pDC=GetDC(); HBITMAPhBitmap=(HBITMAP)LoadImage(NULL,_T("x4.bmp"), IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE| LR_LOADFROMFILE); m_bitmap.Attach(hBitmap); BITMAPbm;m_bitmap.GetBitmap(&bm);//注意此处易出错,与你添加的图形有关。

CDCdcImage;上一页下一页返回4.7章后实训if(!dcImage.CreateCompatibleDC(pDC)) return; CBitmap*pOldBitmap=dcImage.SelectObject(&m_bitmap); //调用BitBlt()函数显示照片

pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcImage,0,0,SRCCOPY); dcImage.SelectObject(pOldBitmap); DeleteObject(m_bitmap.Detach());//释放位图存储空间}上一页下一页返回4.7章后实训if(i==5){CDC*pDC=GetDC(); HBITMAPhBitmap=(HBITMAP)LoadImage(NULL,_T("x5.bmp"), IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE| LR_LOADFROMFILE); m_bitmap.Attach(hBitmap); BITMAPbm;m_bitmap.GetBitmap(&bm);//注意此处易出错,与你添加的图形有关。

CDCdcImage;上一页下一页返回4.7章后实训if(!dcImage.CreateCompatibleDC(pDC)) return; CBitmap*pOldBitmap=dcImage.SelectObject(&m_bitmap); pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcImage,0,0,SRCCOPY); //调用BitBlt()函数显示照片

dcImage.SelectObject(pOldBitmap); DeleteObject(m_bitmap.Detach());//释放位图存储空间} UpdateData(false);}上一页下一页返回4.7章后实训注意:下面的(14)、(15)可以不做,也能实现预期效果。14)在工具栏中添加“打开”和“另存为”按钮。学生档案写完后要保存,而用到时要打开,故要设计“打开”和“保存”控件。具体作法如下。①在Workspace窗口的资源(ResourceView)列表中,双击Toolbar下的ID_MAINFRAME选项,打开工具栏编辑器,单击最后一个空白按钮,画上适当图形,再双击这个按钮,ID处输入ID_FILE_MYOPEN,Prompt处输入“打开\n打开”(“\n”之前是程序运行时状态栏提示信息,“\n”之后为鼠标光标移动至该按钮时光标下方给出的提示信息)。②按上步骤再加一个保存按钮ID_FILE_MYSAVE,Prompt处输入“保存\n保存”。上一页下一页返回4.7章后实训15)在CMyView类中添加消息响应函数。①添加“打开”消息响应函数。选择View→ClassWizard命令,打开MessageMaps选项卡,在Classname下拉列表中选择CMyView选项ObjectIDs:ID_FILE_MYOPEN→Message:COMMAND→AddFunction→EditCode开始添加代码如下:上一页下一页返回4.7章后实训voidCMyView::OnFileMyopen(){ CStringstrFilter="AllFiles(*.*)|*.*|DatFile(*.dat)|*.dat||";//打开文件对话框

CFileDialogFileDlg(true,NULL,NULL,OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,(LPCSTR)strFilter,this); if(FileDlg.DoModal()!=IDOK)return; CStringstrFileName=FileDlg.GetPathName(); CFilef;上一页下一页返回4.7章后实训if(!f.Open(strFileName,CFile::modeRead)) { AfxMessageBox("打开文件失败"); return; } CMyDoc*pDoc=GetDocument();//读出文件中的数据,存放到文档类的数据成员中

f.Read(&m_nCurrentNo,sizeof(int));上一页下一页返回4.7章后实训for(inti=0;i<120;i++) { f.Read(pDoc->m_student[i].clas,10);//级

f.Read(pDoc->m_student[i].pro,20);//专业

f.Read(pDoc->m_student[i].cla,10);//班

f.Read(pDoc->m_student[i].ins,20);//对应学号

f.Read(pDoc->m_student[i].name,10); f.Read(pDoc->m_student[i].sex,3); f.Read(pDoc->m_student[i].age,4); f.Read(pDoc->m_student[i].tel,14); f.Read(pDoc->m_student[i].pos,20);//职务

f.Read(pDoc->m_student[i].school,999);//学生电子档案

}上一页下一页返回4.7章后实训f.Close(); //将文档类的数据传递给视图类数据成员,并显示

m_noList.SetCurSel(m_nCurrentNo);//设置当前选择项

m_clas=pDoc->m_student[m_nCurrentNo].clas;//级

m_pro=pDoc->m_student[m_nCurrentNo].pro;//专业

m_cla=pDoc->m_student[m_nCurrentNo].cla;//班

m_ins=pDoc->m_student[m_nCurrentNo].ins;//对应学号

m_name=pDoc->m_student[m_nCurrentNo].name; m_sex=pDoc->m_student[m_nCurrentNo].sex; m_age=pDoc->m_student[m_nCurrentNo].age; m_tel=pDoc->m_student[m_nCurrentNo].tel; m_pos=pDoc->m_student[m_nCurrentNo].pos; //职务

m_school=pDoc->m_student[m_nCurrentNo].school;//学生电子档案

UpdateData(false);}上一页下一页返回4.7章后实训②添加“保存”消息响应函数(按如上步骤将“保存”函数加到View.cpp里,并加代码)。voidCMyView::OnFileMysave(){ CStringstrFilter="AllFile(*.*)|*.*|DatFile(*.dat)|*.dat||"; CFileDialogFileDlg(false,NULL,NULL,OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,(LPCSTR)strFilter,this); if(FileDlg.DoModal()!=IDOK)return; CStringstrFileName=FileDlg.GetPathName(); CFilef;上一页下一页返回4.7章后实训if(!f.Open(strFileName,CFile::modeCreate|CFile::modeWrite)) { AfxMessageBox("创建文件失败"); return; } CMyDoc*pDoc=GetDocument(); f.Write(&m_nCurrentNo,sizeof(int)); for(inti=0;i<120;i++) { f.Write(pDoc->m_student[i].clas,10);//级

f.Write(pDoc->m_student[i].pro,20);//专业

f.Write(pDoc->m_student[i].cla,10);//班

f.Write(pDoc->m_student[i].ins,20);//对应学号上一页下一页返回4.7章后实训f.Write(pDoc->m_student[i].name,10); f.Write(pDoc->m_student[i].sex,10); f.Write(pDoc->m_student[i].age,10); f.Write(pDoc->m_student[i].tel,20); f.Write(pDoc->m_student[i].pos,20);//职务

f.Write(pDoc->m_student[i].school,9999);//学生电子档案

} f.Close();}上一页下一页返回4.7章后实训16)添加串行化存储和装入。程序运行后,按姓名写入一班学生的信息,并可按个浏览;但这样退出程序后学生的信息就没了。为了将学生的信息保留下来,并在用到时还能打开,要进行串行化存储和装入,做法是在CMyDoc.cpp文件的Serialize(CArchive&ar)函数里添加如下代码:voidCMyDoc::Serialize(CArchive&ar){ if(ar.IsStoring()) { for(inti=0;i<120;i++) {ar.Write(m_student[i].clas,10);//级

ar.Write(m_student[i].pro,20);//专业

ar.Write(m_student[i].cla,20);//班及学习性质上一页下一页返回4.7章后实训ar.Write(m_student[i].name,20);//对应姓名

ar.Write(m_student[i].stuid,20);//学号

ar.Write(m_student[i].sex,10);//性别

ar.Write(m_student[i].age,20);//出生年月

ar.Write(m_student[i].tel,20);//电话

ar.Write(m_student[i].pos,20);//职务

ar.Write(m_student[i].school,9999);//学生电子档案

} }上一页下一页返回4.7章后实训else { for(inti=0;i<120;i++) {ar.Read(m_student[i].clas,10);//级

ar.Read(m_student[i].pro,20);//专业

ar.Read(m_student[i].cla,20);//班及学习性质

ar.Read(m_student[i].name,20);//对应姓名

ar.Read(m_student[i].stuid,20);//学号

ar.Read(m_student[i].sex,10);//性别

ar.Read(m_student[i].age,20);//出生年月

ar.Read(m_student[i].tel,20);//电话

ar.Read(m_student[i].pos,20);//职务

ar.Read(m_student[i].school,9999);//学生电子档案

} }}上一页下一页返回4.7章后实训

程序正确运行后,单击按钮(单击此处输入学生姓名)输入学生信息,输入完后保存(起一个文件名一班学生信息),接着可浏览并退出。再次运行此程序时,会发现信息为空,选择“文件”→“打开”→“一班学生信息”命令,便会显示出一班的学生信息了,接着还可以进行添加修改等工作。如果想建二班学生信息档案,可再运行此程序,直接输入二班学生信息,之后再起名“二班学生信息”,其他如此类推。上一页下一页返回4.7章后实训注意:组合框里的姓名必须与编辑框里的对应姓名一致,最好是在输入学生信息时,从组合框里将名字复制到编辑框的对应姓名里。各个班都建好后,进入E盘的vcpp文件夹,找到这个程序,点开,在Debug里把带图标的那个执行文件(.exe)复制出来,放到适当地方,它就可当项目执行了。注意:要为本软件设置密码(口令),请按第3章“口令设置实例”进行,见图4.44所示,步骤如下。上一页下一页返回4.7章后实训(1)插入一个对话框,打开其属性对话框,将ID改为IDD_PASSWORD_DIALOG。(2)按图4.44的布局布置控件。

1)将OK和CANCEL改为“确定”和“取消”。

2)拖一个静态文本(StaticText),标题写“请输入用户名”,并拖一个编辑控件(EditBox),将其ID改为IDC_PASSWORD_EDIT1,在Style中选PassWord属性。

3)再拖一个静态文本(StaticText),标题写“请输入密码”,拖一个编辑控件(EditBox),将其ID改为IDC_PASSWORD_EDIT2,在Style中选PassWord属性。上一页下一页返回4.7章后实训(3)创建对话框类,类名为CPassWordDialog。(4)加成员变量。为对话框(Classname处为CPassWordDialog)上的编辑框控件IDC_PASSWORD_EDIT1和IDC_PASSWORD_EDIT2加String类型的成员变量m_password1和m_password2,在MaximumCharacters处输入“20”(字符串个数最多为20)。(5)在应用程序“大学生档案.cpp”的InitInstance()函数中添加代码:上一页下一页返回4.7章后实训BoolCMyApp::InitInstance(){m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();CPassWordDialogCDlg;if(CDlg.DoModal()==IDOK)//用户按了确定按钮{if(CDlg.m_password1!="beijing")//用户名

{AfxMessageBox("用户名错误,确定后将退出程序");returnFALSE;}上一页下一页返回4.7章后实训if(CDlg.m_password2!="1949")//密码

{AfxMessageBox("密码错误,确定后将退出程序");returnFALSE;}}else//如果按下取消按钮程序也结束

returnFALSE;returnTRUE;}(6)在应用程序“学生档案管理.cpp”头部加:#include"PassWordDialog.h"。注:密码对话框可做得大一些,覆盖住应用程序界面,使打开的界面更美观。上一页下一页返回4.7章后实训

下面补充介绍一下组合框、ComboBox控件、CArchive类和Serialize()函数。1.组合框本例使用了组合框来存储与显示姓名。组合框可以看作是一个编辑框或静态文本框与一个列表框的组合,组合框的名称也正是由此而来的。当前选定的项将显示在组合框的编辑框或静态文本框中,如果组合框具有下拉列表(drop-downlist)样式,则用户可以在编辑框中输入列表框中某一项的首字母,在列表框可见时,与该字母相匹配的最近的项将被加亮显示。在绘制组合框时,可以使用控件的Properties对话框设置控件的各种属性式样。如表4.25所示。上一页下一页返回4.7章后实训2.ComboBox控件

ComboBox控件与CComboBox类关联。CComboBox类常见的成员函数如表4.26所示。3.CArchive类

CArchive类没有基类,它提供了串行化对象从文件中读写的类型安全缓冲机制,可以把CArchive对象想象成一种二进制流,就像输入/输出流一样可以顺序高效的处理二进制对象数据。使用CArchive对象之前,必须先创建一个CFile对象,同时保证CArchive对象的读写标志设置与文件打开方式相一致。对于一个CArchive对象,可以进行存储操作,也可以读取,但不能两者同时进行。CArchive类的成员函数如下所示。上一页下一页返回4.7章后实训Read、Write——读写指定字节数的缓冲区内容。ReadString、WriteString——读写一行文本。ReadObject、WriteObject——调用一个对象的Serialize函数来读或写。ReadClass、WriteClass——读写一个CRuntimeClass指明对象。IsLoading、IsStoring——判断当前读写状态。Serialize()函数在MFCAppWizard自动生成的程序框架中,文件的串行化操作都是由CDocument派生类的成员函数Serialize()完成的。上一页下一页返回4.7章后实训

在这个成员函数中,使用CArchive对象完成具体的操作。参数中传递进来的CArchive引用对象,是由MFC程序框架根据用户输入需要执行串行化操作时创建的,它包含了所需要的文件信息,使用它可以对各种CArchive类支持的数据格式进行读写、调用其他CObject派生类对象的串行化函数等。

MFCAppWizard自动生成的代码已经完成的工作是:用户选择“打开”、“保存”或“另存为”等命令时,程序框架创建着这个文件的CFile对象,将它关联到新创建的CArchive对象上,并设置CArchive对象的Store或Load标志,用这个对象来调用CDocument派生类的Serialize()成员函数。在Serialize()函数完成读写操作返回后,自动删除Serialize()函数和CFile对象。上一页下一页返回4.7章后实训实训2编制一个拆分两个窗口的程序最初左边窗口显示文字是“切换窗口0”,右边窗口显示文字是“切换窗口1”。当点击菜单“切换窗口”的子菜单“窗口2”时(最初窗口1是屏蔽的),在右边窗口中显示“切换窗口2”。当再点击菜单“切换窗口”的子菜单“窗口1”时,在右边窗口中显示“切换窗口1”。可这样多次点击菜单,右边窗口的文字不断转换。(1)建一个单文档的应用程序,名为:切换窗口。(2)创建菜单命令,如图4.45所示。上一页下一页返回4.7章后实训其中“切换窗口”下的子菜单:“窗口1”的ID为ID_SWITCH_VIEW1“窗口2”的ID为ID_SWITCH_VIEW2(3)将菜单“窗口1”和“窗口2”的消息映射到主框架(MainFrm)类中。注意:要把COMMAND和UPDATE_COMMAND_UI消息都映射到主框架类中。说明:ON_COMMAND与ON_UPDATE_COMMAND_UI的区别。ON_COMMAND是点击了按钮或菜单项后的响应消息。ON_UPDATE_COMMAND_UI是用来表示对应的按钮和菜单项的状态的响应消息,即按钮和菜单的特性,如菜单带核对符“√”就要通过ON_UPDATE_COMMAND_UI完成。上一页下一页返回4.7章后实训(4)分别为上面的消息映射添加代码:voidCMainFrame::OnSwitchView1(){CRectcr;GetClientRect(&cr);CSizepaneSize1(3*cr.Width()/4,cr.Height());CCreateContextContext;Context.m_pNewViewClass=RUNTIME_CLASS(CSwitchView1);Context.m_pCurrentDoc=((CMyApp*)AfxGetApp())->m_pDoc;上一页下一页返回4.7章后实训Context.m_pCurrentFrame=this;Context.m_pNewDocTemplate=Context.m_pCurrentDoc->GetDocTemplate();Context.m_pLastView=(CView*)m_wndSplitter.GetPane(0,0);m_wndSplitter.DeleteView(0,1);m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CSwitchView1),paneSize1,&Context);上一页下一页返回4.7章后实训CSwitchView1*pView=(CSwitchView1*)m_wndSplitter.GetPane(0,1);pView->GetParentFrame()->RecalcLayout();m_wndSplitter.RecalcLayout();pView->OnInitialUpdate();m_wndSplitter.SetActivePane(0,1);}voidCMainFrame::OnUpdateSwitchView1(CCmdUI*pCmdUI){pCmdUI->Enable(!m_wndSplitter.GetPane(0,1)->IsKindOf(RUNTIME_CLASS(CSwitchView1)));}上一页下一页返回4.7章后实训voidCMainFrame::OnSwitchView2(){CRectcr;GetClientRect(&cr);CSizepaneSize1(3*cr.Width()/4,cr.Height());CCreateContextContext;Context.m_pNewViewClass=RUNTIME_CLASS(CSwitchView2);Context.m_pCurrentDoc=((CMyApp*)AfxGetApp())->m_pDoc;Context.m_pCurrentFrame=this;Context.m_pNewDocTemplate=Context.m_pCurrentDoc->GetDocTemplate();Context.m_pLastView=(CView*)m_wndSplitter.GetPane(0,0);上一页下一页返回4.7章后实训m_wndSplitter.DeleteView(0,1);m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CSwitchView2),paneSize1,&Context);CSwitchView2*pView=(CSwitchView2*)m_wndSplitter.GetPane(0,1);pView->GetParentFrame()->RecalcLayout();m_wndSplitter.RecalcLayout();pView->OnInitialUpdate();m_wndSplitter.SetActivePane(0,1);}上一页下一页返回4.7章后实训voidCMainFrame::OnUpdateSwitchView2(CCmdUI*pCmdUI){pCmdUI->Enable(!m_wndSplitter.GetPane(0,1)-> IsKindOf(RUNTIME_CLASS(CSwitchView2)));}(5)向项目中增加两个新类,类名分别为CSwitchView1和CSwitchView2,基类都为CView。(6)在MainFrm.h文件中的protected下定义拆分窗口类对象CSplitterWndm_wndSplitter;在MainFrm.cpp文件的前面加:上一页下一页返回4.7章后实训#include"切换窗口View.h"#include"SwitchView1.h"#include"SwitchView2.h"在视图类“切换窗口View.h”文件的前面加#include"切换窗口Doc.h"。在应用程序类“切换窗口.h”文件的前面加#include"切换窗口Doc.h",并在此文件的public下定义文档类的指针变量:CMyDoc*m_pDoc;上一页下一页返回4.7章后实训(7)在主框架类(MainFrm)添加OnCreateClient()函数,并加代码,实现窗口拆分。BOOLCMainFrame::OnCreateClient(LPCREATESTRUCTlpcs,CCreateContext*pContext){CRectcr;BOOLrc;if(!m_wndSplitter.CreateStatic(this,1,2)){ TRACE0("Failedtocreatesplitbar");returnFALSE;//failedtocreate}上一页下一页返回4.7章后实训GetClientRect(&cr);CSizepaneSize(cr.Width()/4,cr.Height());CSizepaneSize1(3*cr.Width()/4,cr.Height());((CMyApp*)AfxGetApp())->m_pDoc=(CMyDoc*)(pContext->m_pCurrentDoc);pContext->m_pCurrentFrame=this;rc=m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,paneSize,pContext);if(!rc)returnFALSE;上一页下一页返回4.7章后实训pContext->m_pNewViewClass=RUNTIME_CLASS(CSwitchView1);pContext->m_pCurrentDoc=((CMyApp*)AfxGetApp())->m_pDoc;pContext->m_pCurrentFrame=this;rc=m_wndSplitter.CreateView(0,1,pContext->m_pNewViewClass,paneSize1,pContext);m_wndSplitter.RecalcLayout();m_wndSplitter.SetActivePane(0,1);returnrc;//returnCFrameWnd::OnCreateClient(lpcs,pContext);}上一页下一页返回4.7章后实训(8)在视图类“切换窗口View”类中添加WM_PAINT消息映射,并添加下列代码:voidCMyView::OnPaint(){CPaintDCdc(this); dc.TextOut(0,0,"切换窗口0",10);}(9)在CSwitchView1类中添加WM_PAINT消息映射,并添加下列代码:voidCSwitchView1::OnPaint(){CPaintDCdc(this); dc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论