在《【mfc】利用文件的读写,theApp全局变量来现实登录帐号管理系统》(点击打开链接)中,虽然也使用到文件的打开与保存,但这是在用户打开与关闭对话框的时候就自动进行的。现在设置一个“打开”按钮与一个“保存”按钮,可以让用户自由选择保存的文件的位置,输入文件名,但是,保存的文件格式只能是我们指定的.ifo,因为以后打开文件,我们只接受.ifo的打开。本文亦是《【mfc】不同对话框之间互相操控、全局变量与日期控件》(点击打开链接)的进一步工作,上次只完成了“添加”与“删除”按钮,继续完成“打开”与“保存”按钮。
一、基本目标
如下图所示,用户在添加了一些学生信息之后,我们不再给用户自动保存,当然,这里更加人性化地应该在用户点击关闭按钮的时候加个警告弹窗,这里可以在OnCancel函数里面写。用户手动保存自己的信息,然后下次进入这个界面,可以打开自己上次保存的信息。保存的文件格式统一为.ifo。
二、制作过程
其实主要是对CFileDialog进行操作,CFileDialog的返回值能够形成找到文件的具体路径,之后的文件操作与在《【mfc】利用文件的读写,theApp全局变量来现实登录帐号管理系统》(点击打开链接)中的一模一样。CFileDialog是系统自带的类,一定义直接使用即可,没什么难的,主要是CFileDialog初始化的参数设置好就可以了。
1、由于涉及文件操作,我们与上次一样,要定义一个全局变量的结构体,其实全局变量的定义不用像上次那样复杂,直接如下图打开StdAfx.h来写入全局变量就可以了,这与上次设置theApp的一模一样
写入如下图所示的结构体作为全局变量:
struct SInfo{
char user[20];//保存学生姓名
int classnames;//保存学生班级
char birth[20];//保存学生出生日期
};
这里的学生日期虽然是时间类型,但是完全可以转化为字符串来保存哦!
2、之后就是打开按钮的消息映射函数:
void CInfoDlg::OnButton4()
{
// TODO: Add your control notification handler code here
// 系统文件选择对话框,自带,参数为TRUE,标题为“打开”,隐藏那些只读文件
// 文件名中没有扩展名,则自动保存为.ifo格式,在文件名后面自动补充.ifo
// 第三个参数是默认的文件名,在文件名一栏会自动填上第三个参数
// "学生信息(*.ifo)|*.ifo|代表打开文件类型的选择,学生信息(*.ifo)是显示信息,*.ifo其决定作用
CFileDialog dlg(TRUE,"ifo","",OFN_HIDEREADONLY,"学生信息(*.ifo)|*.ifo||");
// 用户在系统文件选择对话框中选择“取消”,那么则dlg.DoModal()的返回值为IDCANCEL
if(IDCANCEL==dlg.DoModal()){
return;
}
// 取得要操作文件的路径
CString filename=dlg.GetPathName();
CFile file;
// 读出来的东西必须与结构体的大小相匹配,不匹配,要么读完,要么读取出错
if(!file.Open(filename,CFile::modeRead|CFile::shareDenyNone)){
AfxMessageBox("打开文件失败");
return;
}
// 先清空列表,在把文件读出来的东西一个一个添加到列表控件里面去
m_List.DeleteAllItems();
SInfo info;
CString str;
// 读出来的东西必须与结构体的大小相匹配,不匹配,要么读完,要么读取出错
for(int i=0;file.Read(&info,sizeof(info))==sizeof(info);i++){
m_List.InsertItem(i,info.user);
str.Format("%d",info.classnames);
m_List.SetItemText(i,1,str);
m_List.SetItemText(i,2,info.birth);
}
file.Close();
}
3、最后是保存按钮的消息映射函数:
void CInfoDlg::OnButton5()
{
// TODO: Add your control notification handler code here
// 系统文件选择对话框,自带,参数为FALSE,标题为“另存为”
// 文件名中没有扩展名,则自动保存为.ifo格式,在文件名后面自动补充.ifo
// 第三个参数是默认的文件名,在文件名一栏会自动填上第三个参数
// OFN_OVERWRITEPROMPT覆盖前提示
// "学生信息(*.ifo)|*.ifo|代表保存文件类型的选择,学生信息(*.ifo)是显示信息,*.ifo其决定作用
CFileDialog dlg(FALSE,"ifo","",OFN_OVERWRITEPROMPT,"学生信息(*.ifo)|*.ifo|所有文件(*.*)|*.*||");
if(IDCANCEL==dlg.DoModal()){
return;
}
// 打开当前目录的一个user.dat文件,没有则创建
CString filename=dlg.GetPathName();
CFile file;
if(!file.Open(filename,CFile::modeCreate|CFile::modeWrite)){
AfxMessageBox("创建文件失败");
return;
}
SInfo info;
int nCount=m_List.GetItemCount();
for(int i=0;i<nCount;i++){
m_List.GetItemText(i,0,info.user,sizeof(info.user));
info.classnames=atoi(m_List.GetItemText(i,1));
m_List.GetItemText(i,2,info.birth,sizeof(info.birth));
file.Write(&info,sizeof(info));
}
file.Close();
}
好了,至此,同时也把整个学生信息管理系统做完。连同《【mfc】用对话框的切换实现重新登录》( 点击打开链接)、《【mfc】利用文件的读写,theApp全局变量来现实登录帐号管理系统》( 点击打开链接)、《【mfc】不同对话框之间互相操控、全局变量与日期控件》( 点击打开链接)就是一个非常完整的学生管理系统。虽然在网络OS的今天,这样的系统的需求已经越来越少见,但是,通过这个系统的制作,真正让我学到了,如何写出一个完整的Win32程序。当然,之后mfc还有很多特性需要研究。