这是一个简易的MFC通讯录,全部功能大部分利用指针实现,对大家的指针使用熟练是一个很好的项目,欢迎大家多多讨论,共同进步。
实验报告步骤及总结
①.整体框架的设计
1)首先,这个就是运行的可视化效果图
2)然后可以看到,我的功能还是比较简单的,首先左边是一个列表框,用于显示添加的人员的名字,然后对于每个人只有三种信息,想要其他功能也是可以添加的,处理人员信息使用了两个编辑框和一个组合框,然后就是实现主要功能的六个按钮了,接下来将一一介绍。
②.编写代码前的准备工作
1)为了方便接下来代码的编写,我们要给编辑框,列表框和组合框分别设置一个成员变量,首先先打开类向导,按下图所示设置就好了呢
2)这里有个小细节需要注意,组合框我们只设置了一个成员变量,因为我们要把他们绑定成一个组,这样在操作其中一个的时候,另一个将自动关闭,绑定的方法如下图,在控件属性的Group那里选上True就好了
③.代码的编写(主要的解释会在每个代码段里呈现)
首先,先新建一个头文件,将要处理的信息以一个结构people表示出来
然后在Dlg.cpp里包含该头文件就可以使用了
额外包含一个fstream为接下来的 保存和读取 提前做好准备
(1)第一个按钮“添加”的执行代码
void CMFCApplication6Dlg::OnBnClickedButton1()
{
UpdateData(TRUE);
people *keda=new people;
strcpy_s(keda->pname, name);
strcpy_s(keda->phone, number);
keda->xingbie = xing;
int nCur = tongxun.AddString(name); //把该名字显示到列表框上去,并返回该项的序号
tongxun.SetItemData(nCur, (DWORD_PTR)keda); //将各项的序号和整个人员信息结构指针相关联
}
(2)列表框的执行代码
这行代码的主要操作是当添加了部分成员后,当我们点击列表框上的任意的成员名字,我们可以在右边看到该成员的具体信息,进而进行其他操作。
使用了GetCuSel() 函数
返回列表框中当前选中的项的下标,如果没有选中项,则返回CB_ERR
void CMFCApplication6Dlg::OnLbnSelchangeList1()
{
int nCur = tongxun.GetCurSel();
CWnd* pButton = GetDlgItem(IDC_BUTTON2); //获取操作删除键的指针
if (nCur != CB_ERR)
{
pButton-> EnableWindow(TRUE);
people * mouren = (people*)tongxun.GetItemData(nCur);
name = mouren->pname;
xing = mouren->xingbie;
number = mouren->phone;
UpdateData(FALSE);
}
else
pButton->EnableWindow(FALSE); //当没有选定删除的内容,将关闭删除键
}
(3)第二个按钮“删除”的执行代码
void CMFCApplication6Dlg::OnBnClickedButton2()
{
int nCur = tongxun.GetCurSel();
if (nCur != CB_ERR)
{
people * pInfo = (people*)tongxun.GetItemData(nCur);
tongxun.DeleteString(nCur);
delete pInfo; //因为我们的创建都是new的指针,因而我们要进行delete防止内存泄露
}
}
(4)第三个按钮“全部清除”的执行代码
void CMFCApplication6Dlg::RemoveLst() //用来将一条条new的删除掉,防止内存泄露
{
int n = tongxun.GetCount(); //返回列表框的列表数目
for (int i = 0; i < n; i++)
{
people * pInfo = (people*)tongxun.GetItemData(i);
delete pInfo;
}
tongxun.ResetContent(); //将列表框的内容全部清除
}
void CMFCApplication6Dlg::OnBnClickedButton5()
{
INT_PTR nRes =MessageBox(L"确定清除?" ,L"警告!!",MB_OKCANCEL | MB_ICONQUESTION);
if(nRes== MB_OKCANCEL)RemoveLst();
}
(5)`在这里第四个按钮“保存”的执行代码
void CMFCApplication6Dlg::OnBnClickedButton3()
{
CFileDialog dlg(FALSE); //文件对话框 :TRUE是打开 FALSE是另存为
//dlg.DoModal(); //模态对话框
if (dlg.DoModal() == IDOK)
{
CString strFile = dlg.GetPathName(); //获得文件保存路径
ofstream out(strFile,ios::binary);
if (out.is_open())
{
int n = tongxun.GetCount(); //把行数写进去,方便后面的读取
out.write((char*)&n, sizeof(int));
for (int i = 0; i < n; i++)
{
people * pInfo = (people*)tongxun.GetItemData(i);
out.write((char*)pInfo, sizeof(people));
}
}
}
}
}
(6)第五个按钮“读取”的执行代码
void CMFCApplication6Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE); //文件对话框
//dlg.DoModal(); //模态对话框
if (dlg.DoModal() == IDOK)
{
CString strFile = dlg.GetPathName(); //获得文件读取路径
ifstream in(strFile, ios::binary);
if (in.is_open())
{
RemoveLst(); //将界面原有的删除掉
int n;
in.read((char*)&n, sizeof(n));
for (int i = 0; i < n; i++)
{
people * pInfo = new people ;
in.read((char*)pInfo, sizeof(people));
int nIndex = tongxun.AddString(name);
tongxun.SetItemData(nIndex, (DWORD_PTR)pInfo);
}
}
else
{
AfxMessageBox(L"打开文件失败!!");
}
}
}
先进行提前全部清除,然后开始读取文件
读取开始:
读取结果:
(7)第六个按钮“最小化”的执行代码
void CMFCApplication6Dlg::OnBnClickedButton6() //特意加的一个小功能
{
AfxGetMainWnd()->CloseWindow();
}
将其缩小到电脑桌面底部
(8)右上角的✖的处理代码
当它关掉通讯录时会把所有new所占用的空间给清除,防止内存泄露!!
对实验结果进行分析
虽然我设计的MFC通讯录,并没有很多花哨的功能,但把所有基本的功能都实现了,从实验的结果来看,实验结果与预期达到一致,实现了输入,删除,读取,保存这些功能,并且都是使用了极为简洁的代码,运用了指针以及内存的动态分布,并且还注重了程序的完美,在每个结构删除的时候,把new所占用的 内存给释放出来,虽然不会影响可视化效果的使用,但这对于程序来说,内存泄露是一件极为可怕的事情。
对本次实验进行总结
1.在做实验的时候,也会遇到一些版本不同的问题,比如字符串如今的代码是使用Unicode编码,所以所有的字符串前加个_T(“”)这样修饰,还有一些函数的使用也是有一定的变化的。还有
2.解决了以上问题后,结合课上老师传授的内容和书本的知识做了这样一个简易的通讯录,通过这样一个比较完整的应用程序的设计,将学过的知识连贯起来,掌握开发了应该实际的应用程序的步骤,同时学会使用开发工具实现界面友好的应用程序。
3.通过这次实验以及实验报告的流程阐述,我对MFC有了更深刻的认识,并且更加熟悉了对话框的功能以及作用。