C++ MFC 学习笔记+小型通讯录系统实现
  zhRhucGD3dLm 2023年11月02日 43 0

[MFC 最详细入门教程](https://blog.csdn.net/freeking101/article/details/101013627?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168387812916782427455065%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168387812916782427455065&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-101013627-null-null.142^v87^insert_down28v1,239^v2^insert_chatgpt&utm_term=mfc&spm=1018.2226.3001.4187)



[MFC常用函数总结](https://www.cnblogs.com/jiu0821/p/4606639.html)



[C++ & MFC]https://www.cnblogs.com/gaohongchen01/p/4176963.html



[MFC入门(一)]https://www.cnblogs.com/yangyuqing/p/10283641.html


[MFC快速入门]https://www.cnblogs.com/sea520/p/12582780.html


MFC教程(Visual C++ 6.0)|合集

https://blog.csdn.net/w_lin_jie/article/details/106601523?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168388113516782425197660%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168388113516782425197660&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-2-106601523-null-null.142^v87^insert_down28v1,239^v2^insert_chatgpt&utm_term=vc%2B%2B6.0mfc&spm=1018.2226.3001.4187


MFC简介以及基础使用(小白级别入门讲解)


https://blog.csdn.net/qq_45549336/article/details/109008192?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168414038016800215071583%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=168414038016800215071583&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~hot_rank-1-109008192-null-null.142^v87^insert_down28v1,239^v2^insert_chatgpt&utm_term=mfc&spm=1018.2226.3001.4187




C++ MFC 学习笔记+小型通讯录系统实现_Windows


 C++是一种静态数据类型检查的、支持多重编程范式的程序设计语言,支持过程化程序设计、数据抽象、面向对象程序设计、制作图标等泛型程序设计的多种程序设计风格。


  MFC(Microsoft Foundation Classes),是一个微软公司提供的类库,以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量,同VCL类似,是一种应用程序框架。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。此外MFC的部分类为MFC/ATL 通用,可以在Win32 应用程序中单独包含并使用这些类。


  由于它的易用性,初学者常误认为VC++开发必须使用MFC,这种想法是错误的。作为Application Framework,MFC的使用只能提高某些情况下的开发效率,只起到辅助作用,而不能替代整个Win32 程序设计。



## 从C到C++


  计算机诞生初期,人们要使用计算机必须用机器语言或汇编语言编写程序。


  世界上第一种计算机高级语言诞生于1954年,它是FORTRAN语言。


  BASIC语言是1964年在FORTRAN语言的基础上简化而成的。


  C语言是1972年由美国贝尔实验室的D.M.Ritchie研制成功的。


  C++是由AT&T Bell(贝尔)实验室的Bjarne Stroustrup博士及其同事于20世纪80年代初在C语言的基础上开发成功的,C++保留了C语言原有的所有优点,增加了面向对象的机制。


  面向对象程序设计,是针对开发较大规模的程序而提出来的,目的是提高软件开发的效率。不要把面向对象和面向过程对立起来,面向对象和面向过程不是矛盾的,而是各有用途、互为补充的。学习C++,既要会利用C++进行面向过程的结构化程序设计,也要会利用C++进行面向对象的程序设计。


  如果要用C++创建窗口,我们需要使用到系统API或者使用封装了这些API的一些库,前者如Win32程序设计,后者如MFC、wxWidgets。


  其实我认为学习C++的初期当然是熟悉C++的语法,中期是学习STL等库、系统API以及熟悉C++的面向对象的思想和一般的设计方法;后期是伴随着你C++生涯的一生的,因为它没有终点的,这时候除了要继续加深对C++的理解之外,还需要去学习各种各样的基于C++的库,因为你需要在这些库的帮助下使用C++去实现更具体的东西,比如一些GUI库如MFC、QT、wxWidgets,一些游戏引擎如Ogre、Unreal、Bigworld等,一些网络库如ASIO、RakNet、ACE等。这些库大多有一个特点就是它们都是基于C++,封装了底层的API使得我们可以不必每次都去使用繁杂的API来实现我们想要的功能。当然,你也可以用C++去封装这些API,让自己成为一个库作者,方便他人。


## C++发展历史


C++语言发展大概可以分为三个阶段:


第一阶段


  从80年代到1995年。这一阶段C++语言基本上是传统类型上的面向对象语言,并且凭借着接近C语言的效率,在工业界使用的开发语言中占据了相当大份额;


第二阶段


  从1995年到2000年,这一阶段由于标准模板库(STL)和后来的Boost等程序库的出现,泛型程序设计在C++中占据了越来越多的比重性。当然,同时由于Java、C#等语言的出现和硬件价格的大规模下降,C++受到了一定的冲击;


第三阶段


  从2000年至今,由于以Loki、MPL等程序库为代表的产生式编程和模板元编程的出现,C++出现了发展历史上又一个新的高峰,这些新技术的出现以及和原有技术的融合,使C++已经成为当今主流程序设计语言中最复杂的一员。



## MFC是什么

MFC,也称为Microsoft Foundation Class Library,是微软公司提供的一组用于编写Windows应用程序的C++类库。它是为了简化Windows应用程序开发而创建的,包括用户界面、窗口管理、消息处理、绘图设备、打印、文件系统、多媒体等方面的功能。MFC库由一组C++类和函数组成,使得开发者可以更加轻松地构建复杂的GUI界面、处理消息、调用Windows API函数等操作。MFC被广泛应用于Windows桌面应用程序的开发,例如Microsoft Office Suite等。


MFC还提供了丰富的控件和对话框,包括按钮、编辑框、列表框、组合框、树形视图、选项卡等常见组件,并支持自定义控件。通过继承MFC的框架类,开发者可以快速构建自己的应用程序界面。此外,MFC还提供了一些高级功能,如多线程支持、ATL COM技术、数据库访问等。目前,MFC虽然相对于现代的UI框架来说有些过时,但仍然是许多旧有Windows软件的主要代码库之一,对于一些需要兼容老系统或保持稳定性的项目来说,仍具有很高的价值。




## MFC特点


  编程语言函数本质上全部源于API,因此用它们开发出来的应用程序都能工作在Windows的消息机制和绘图里,遵守Windows作为一个操作系统的内部实现。


  最后要明白MFC不只是一个功能单纯的界面开发系统,它提供的类绝大部分用来进行界面开发,关联一个窗口的动作,但它提供的类中有好多类不与一个窗口关联,即类的作用不是一个界面类,不实现对一个窗口对象的控制(如创建、销毁),而是一些在Windows(用MFC编写的程序绝大部分都在Windows中运行)中实现内部处理的类,如数据库的管理类等。学习中最应花费时间的是消息和设备环境,对C++和MFC。


## MFC编程优势


  C++语言应用极为广泛。尤其在底层编程和系统级编程上更是C++的传统优势应用。在数据库和多媒体方面,C++又以其卓越的稳定性而赢得了荣誉。


  面对底层程序,它能很轻松的与Windows API或驱动程序结合,就是在自己的代码中直接使用API函数,而API和驱动程序的资料都是以C语言为基础的,这使得VC程序员能够更轻松的使用Windows API。这样造成了一个很有意思的现象,即入门时VC程序员要付出更多的努力来学习,但是一旦掌握后,开发其他领域的程序或使用第三方软件时,如工业控制类的程序,由于底层的程序都是用C语言编写,反倒是VC程序员能够更快的掌握该领域的编程技术。而很多其他的编程语言甚至找不到相关的资料。这就说明VC(MFC)实际上是一种入门困难,但是扩展学习却很轻松的语言框架。如果局限于某一领域的话VC毫无优势可言,但是如果开发一个新的领域的应用程序或者该程序涉及多个应用领域的话,可减少重复学习的频率和难度,VC(MFC)的优势会立刻显现出来。


## MFC相关


  MFC使用“Afx”作为所有的全局函数和全局变量的前缀。因为在MFC的早期开发阶段它叫“Application Framework Extensions”缩写为“AFX”。AFX提供了对Windows API的高度抽象,建立了全新的面向对象的AFX API,但它对于新手来说太复杂了,所以AFX小组不得不重新开始。后来他们创建了一组C++类,这就是MFC。MFC这个名字被采用得太晚了以至于没来得及修改这些引用。


  在免费的Express版本的Visual Studio 2005/2008中没有包含MFC。


  MFC作为一个强有力的竞争对手,为Borland的Turbo C++编译器设计OWL(Object Windows Library)在同一时间也发布了。但最后,Borland停止了对OWL的继续开发并且不久就从Microsoft那里购买了MFC头文件,动态链接库等的授权,微软没有提供完整的MFC的集成支持。之后Borland发布了VCL(Visual Component Library)来替换OWL框架。


## MFC扩展DLL


  每个DLL都有某种类型的接口:变量、指针、函数、客户程序访问的类。它们的作用是让客户程序使用DLL,MFC扩展DLL可以有C++的接口。导出的函数可以使用C++/MFC数据类型做参数或返回值,导出一个类时客户端能创建类对象或者派生这个类。同时,在DLL中也可以使用DLL和MFC。


  Visual C++使用的MFC类库也是保存在一个DLL中,MFC扩展DLL动态连接到MFC代码库的DLL,客户程序也必须要动态连接到MFC代码库的DLL。(这里谈到的两个DLL,一个是我们自己编写的DLL,一个装MFC类库的DLL)现在MFC代码库的DLL也存在多个版本,客户程序和扩展DLL都必须使用相同版本的MFC代码DLL。所以为了让MFC扩展DLL能很好的工作,扩展DLL和客户程序都必须动态连接到MFC代码库DLL。而这个DLL必须在客户程序运行的计算机上。





![](2023-05-12-16-14-02.png)



## MFC学习笔记


版权声明:本文为CSDN博主「鲨鱼小猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_45549336/article/details/109008192


一、Windows消息机制


1.1窗口


一个Windows应用程序中至少有一个窗口,称为主窗口。我们在客户区进行图案的绘制。


1.2句柄


一个Windows应用程序是包含图标、光标等许多部件(资源),系统在为这些部件(资源)分配内存后会返回他们的标识号,也就是所谓的句柄。比如在Windows应用程序中,使用窗口句柄来标识每一个窗口。对窗口进行操作时候,首先就是得到这个窗口的标识。


1.3消息与消息队列


Windows是事件驱动方式的程序设计,当一个Windows应用程序开始执行的时候,系统会产生一个消息队列,用于保存这个窗口的消息。eg:当你自己在一个窗口中按下键盘时候(事件),系统会收集到这个按下键盘事情(事件),然后包装成消息,放到这个窗口的消息队列中(窗口过程)。因为队列的先进先出的特点,这时候窗口会一个一个的读取消息,然后进行相应的执行处理。


1.4WinMain函数


控制台DOS中的入口是mian函数,而WinMain函数就是Windows程序的入口函数。启动一个应用程序时候就开始先调用WinMain函数


1.5Windows编程模型


一个应用程序的功能是:创建一个窗口,然后响应键盘或者鼠标消息。


WinMain函数的定义

~~~

创建窗口

消息循环

窗口过程

~~~




MFC程序入口

~~~c

//mfc头文件

#include<afxwin.h>


//1、应用程序类CWinApp,MyAPP派生类

class MyApp : public CWinApp{

public:

    //父类的虚函数,需要派生类进行重写

    //也是MFC函数的入口函数

    virtual BOOL InitInstance();

};


//2、框架类CFrameWnd,MyFrame派生类

class MyFrame : public CFrameWnd{

public:

    //构造函数

    MyFrame();

}


~~~



C++ MFC 学习笔记+小型通讯录系统实现_API_02

C++ MFC 学习笔记+小型通讯录系统实现_Windows_03

C++ MFC 学习笔记+小型通讯录系统实现

MFC.cpp


~~~c

//对应类的头文件

#include "mfc.h"


//有且只有一个的全局应用程序类的对象

MyApp app;


//程序入口

BOOL MyApp::InitInstance(){

    //1、创建类框架

    MyFrame *frame = new MyFrame;

    //2、显示窗口

    frame -> ShowWindow(SW_SHOWNORMAL);

    //3、更新窗口

    frame -> UpdateWindow();

    //4、保存框架类对象指针

    m_pMainWnd = frame;

    return TRUE;

}


//重写构造函数

MyFrame::MyFrame(){

    //创建窗口

    Create(NULL,TEXT("mfc"));

}


~~~


2.3MFC的消息映射

消息映射就是将消息和成员函数相互关联的表。比如,Windows将一个鼠标左击消息放到一个框架窗口消息队列中,然后这个窗口取到这个消息时候,MFC将搜索该窗口的消息映射,如果存在一个处理鼠标左击消息(WM_LBUTTONDOWN)的处理程序,就调用。


下面是如何在一个类中编写一个消息映射


在操作的类中声明消息宏

通过放置标识消息的宏来执行消息映射,相应的类将对BEGIN_MESSAGE_MAP和END_MESSAGE_MAP的调用之间处理消息

mfc.h


~~~c

class MyFrame : public CFrameWnd{

public:

    MyFrame();


    //声明消息宏

    DECLARE_MESSAGE_MAP()

}





//定义消息宏,在类中实现(派生类,父类)

BEGIN_MESSAGE_MAP(MyFrame,CFrameWnd)

    ON_WM_LBUTTONDOWN

END_MESSAGE_MAP()


//重写构造函数

MyFrame::MyFrame(){

    //创建窗口

    Create(NULL,TEXT("mfc"));

}


~~~



对应的处理函数分别在类中声明,类外定义

~~~c

//框架类CFrameWnd,MyFrame派生类

class MyFrame : public CFrameWnd{

public:

    //构造函数

    MyFrame();

    //声明消息宏

    DECLARE_MESSAGE_MAP()

    //函数声明

    dfx_msg void OnLButtonDown(UINT,CPoint);

}


~~~



~~~c

//定义消息宏,在类中实现(派生类,父类)

BEGIN_MESSAGE_MAP(MyFrame,CFrameWnd)

    ON_WM_LBUTTONDOWN

END_MESSAGE_MAP()


//重写构造函数

MyFrame::MyFrame(){

    //创建窗口

    Create(NULL,TEXT("mfc"));

}


//定义具体函数的实现

void OnLButtonDown(UINT,CPoint){

    .......

    .......

}

~~~









C++ MFC 学习笔记+小型通讯录系统实现_API_04









# 利用MFC写一个通讯录系统


## 学习资源推荐

基于MFC的简易通讯录:


https://blog.csdn.net/weixin_43978807/article/details/90725232?spm=1001.2014.3001.5506


面向对象程序设计课程设计——MFC实现同学通讯录管理系统:


https://blog.csdn.net/weixin_44244154/article/details/103733614?spm=1001.2014.3001.5506



1.设计目的


同学通讯录管理程序是为了更好地管理学生信息而开发的数据管理软件。如今,同学与同学、老师与同学联系都是通过电话联系。但是,通常这些数据与其他人的信息混合在一起,同学信息并不方便被整理。

所以,同学通讯录管理程序为用户提供充足的信息和快捷的查询手段,实现学生基本信息的录入,删除,查询,修改,存到文件等几方面的功能,这样能对同学之间的信息进行更好的管理,使老师能更好地管理学生信息,对学生信息出现的变动也能及时进行修改。

与此同时,对所学面向对象的程序设计中所学知识加以利用和巩固:


1) 学习Visual C++的MFC开发程序的步骤。 

2) 综合运用所学的类、继承和多态的知识。

3) 进一步掌握程序的调试方法。


2. 设计内容



1 利用MFC的向导,创建基于对话框的应用程序,添加按钮、编辑框等控件;

2 设计通讯录的数据结构(如:以数组或者动态链表)和相应的类;

3 完成对通讯录中记录的增加、修改、删除和显示。

4 将通讯录存入文件。能够打开并显示其中所存的同学信息,并可以进行后续的操作。

在设计同学通讯录管理程序时,我们小组采用对话框形式来进行处理,因为对话框窗口操作简单,更重要的是能更好的向使用者表达程序所要表达的信息。

在主界面进行设计时,我们小组分别设计了学号,姓名,系别,邮箱,电话等五个输入输出框,分别对学生的信息进行输入与输出。其次,设计了一个列表框使学生信息能更好的向用户展示,同时也更加方便了以后的操作。

最后,分别设计了添加记录、查询记录、删除记录、修改记录、保存信息、读取信息、清空所有数据和退出八个按钮,分别实现各自所对应的功能。


3.基本功能描述

3.1. 编辑框

**学号,姓名,系别,邮箱,电话静态文本后的输入输出框实现了对学生信息数据的输入输出。


3.2. 列表框

实现了对学生各个信息的显示,同时通过点击列表中的某一项来实现查看、修改等功能。



3.3. 按钮


1) 添加记录:用户在输入输出框中输入信息,然后通过点击添加记录按钮,添加到列表框中。

2) 查询记录:在除了系别这一信息外任意输入某一项或某几项信息后,点击查询记录按钮,程序将以姓名、电话、邮箱、学号的优先级递减顺序来查找符合条件的学生并将查询到的学生信息显示在输入输出框中。

3) 删除记录:通过选中列表框中某一项,点击删除记录按钮删除所对应的学生数据,但不影响文件中的数据。

4) 修改记录:通过选中列表框中某一项,在对话框中修改所对应的学生某项数据,然后点击修改记录按钮,修改列表框中所对应的数据信息,但不影响文件中的数据。

5) 保存信息:将列表框中的信息全部保存到,目录下的“学生信息.txt”文件中,只有生成文件按钮才会通过程序影响文件中的内容。

6) 读取信息:首先将列表中的已经显示的信息全部清空,再将储存在文件中的信息读取中列表中。

7) 清空所有数据:删除全部学生信息,清空所有记录,同时也将文件中的信息清空。

8) 退出:点击退出后弹出消息框“是否确认退出?”,若点击确认则退出程序,点击取消则返回当前程序**


4.设计思路

4.1. 窗口的设计

新建对话框程序,在对话框程序中添加各个控件,实现各个功能。


首先创建一般Student类,其中有共有CString公有数据成员name,number,phone,email,yuanxi,分别实现对学生邮箱,姓名,学号,电话,系别的存储。

~~~c

class Student{

public:

CString name;

CString number;

CString phone;

CString email;

CString yuanxi;

};

~~~

再声明自定义类型Student的向量stu(初始容量为零)和用以确定列表控件行数的全局变量n(初始值为-1)。

为对话框创建CClassAddresslistDlg类,并设置各个变量与对话框各个窗口相关联。

通过编写点击各个按钮对应函数来完成各个按钮的功能:

添加记录:void CClassAddresslistDlg::OnBUTTONincrease();

查询记录:void CClassAddresslistDlg::OnBUTTONSearch();

删除记录:void CClassAddresslistDlg::OnBUTTONdelete();

修改记录:void CClassAddresslistDlg::OnBUTTONchange();

保存信息:void CClassAddresslistDlg::OnBUTTONpreserve();

读取信息:void CClassAddresslistDlg::OnBUTTONduqu();

清空所有数据:void CClassAddresslistDlg::OnBUTTONqingkong();

退出:void CClassAddresslistDlg::OnButtontuichu();

5.软件设计

5.1. 设计步骤

1) 打开VC++6.0,新建MFC AppWizard[EXE]工程,在对话框中添加各个控件,完成程序窗口外观设计

2) 在MFC ClassWizard中建立对话框类,并命名为CClassAddresslistDlg

3) 在MFC ClassWizard中建立一般类,并命名为Student

4) 在CStudentDlg类编写时,创建全局变量int n = -1(代表行数),通过n的值来方便为列表和按钮建立联系

5) 在MFC ClassWizard为CStudentDlg中添加各个控件,并通过函数编写,实现具体的功能

6) 调试与运行


5.2界面设计

界面由选项框区、通讯录信息区以及列表控件区三个区域组成。其中,通讯录信息区由有五个静态控件用来显示“学号”“姓名”“系别”“邮箱”“电话”字样,与各个静态控件相对应的是五个编辑框,实现了对学生信息的输入输出。列表框区用来显示当前已经存储的学生信息,选项框区有八个按钮,分别对应各自的功能。


6.关键功能的实现

*添加纪录:

首先用户需要在五个编辑框中分别输入信息。点击“添加纪录”按钮后,对应的函数首先声明将编辑框控件中的内容同步到变量中,接着声明了一个变量int flag = 1,用来选择性地执行接下来的if语句。接下来判断当前状态下用户是否输入了信息以及用户输入的信息是否已经在列表中,如果输入了合理的信息则执行接下来的if语句进行查找,反之则改变flag的值以避开用于加入新元素的if语句。随后将信息栏当中的关联变量置零,进行下一次操作时信息栏当中不再显示上次学生的信息。

保存信息:

将保存信息按钮与Dlg类相关联,用户点击保存信息后,利用IO流对数据进行输入和输入,采用ofstream新建一个对象out来打开一个文本文档,采取ios::trunc对文本文件中已有数据进行覆盖,并将变量中的信息利用out来储存到文本文件当中去,每输入一个学生的信息进行换行操作。由于CString是MFC中,而ofstream是ATL中,ofstream能写入的需要char ,因此需要进行类型的转化,来实现信息的保存。

读取信息:

将读取信息按钮与Dlg类相关联,用户点击读取信息后利用IO流对数据进行输入和输入,采用ifstream新建一个对象fin来打开一个文本文档,先利用list控件中的函数将列表清空,

同样需要进行类型的转化,再利用fin将文档中的内容输出到列表中,并与变量的数据相关联,将其同步到变量当中去,来实现信息的读取。

列表控件:

单击列表中的某一行,再左侧信息栏中对应出现相应的学生信息。将列表栏与Dlg类相关联,获得相应的学生信息后将其同步到信息栏的关联变量当中,实现列表栏与信息栏的同步。


7.核心代码实现


7.1列表控件与编辑框控件的关联:

~~~c

void CClassAddresslistDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)   //使选中哪一行的信息编辑框出现哪一行的信息

{

    POSITION pos=m_list.GetFirstSelectedItemPosition(); //获得选中元素的位置

    n=m_list.GetNextSelectedItem(pos); //获得选中元素的索引

    CString x;

    x=m_list.GetItemText(n,0);

    m_Number=x;

    x=m_list.GetItemText(n,1);

    m_Name=x;

    x=m_list.GetItemText(n,2);

    m_Xibie=x;

    x=m_list.GetItemText(n,3);

    m_Email=x;

    x=m_list.GetItemText(n,4);

    m_Phone=x;

    UpdateData(false);

    *pResult = 0;  

}

~~~

7.2 添加纪录:

~~~c

void CClassAddresslistDlg::OnBUTTONincrease()

{

    int flag = 0;//以便于选择性执行if语句

    UpdateData(true);

    if(m_Name==""||m_Number==""||m_Xibie==""||

        m_Phone==""||m_Email=="")

    {

        flag = 1;

        MessageBox("输入信息不完善,请重新输入!");

    }

    if (flag==0)

        for (int i = 0;i < stu.size();i++)

    {

        if ( stu[i].name == m_Name&&stu[i].phone == m_Phone&&stu[i].email == m_Email&&stu[i].number == m_Number&&stu[i].yuanxi == m_Xibie)      

        {  

            flag = 1;

            MessageBox("该学生信息已经添加!");

            break;

        }

    }

        if (flag==0)

    {

        int n=m_list.GetItemCount();

            m_list.InsertItem(n,"");

            m_list.SetItemText(n,0,m_Number);

            m_list.SetItemText(n,1,m_Name);

            m_list.SetItemText(n,2,m_Xibie);

            m_list.SetItemText(n,3,m_Email);

            m_list.SetItemText(n,4,m_Phone);

        stu.reserve(stu.size()+1);//增加容量以防止溢出

        Student s1;

        s1.name = m_Name;

        s1.number = m_Number;

        s1.yuanxi = m_Xibie;

        s1.email = m_Email;

        s1.phone = m_Phone;

        stu.push_back(s1);//往向量末尾加新信息

            MessageBox("添加成功!");

    m_Name="";

    m_Number="";

    m_Xibie="";

    m_Phone="";

    m_Email="";  //清空编辑框

    UpdateData(false);

    }  

}


~~~

7.3 保存信息:

~~~c

void CClassAddresslistDlg::OnBUTTONpreserve()

{

    ofstream fout("ZHM.txt",ios::trunc);


    int n=m_list.GetItemCount();

    for(int i=0;i<n;++i){

        string str = CString(stu[i].number);   //由于CString是MFC中,而ofstream是ATL中,ofstream能写入的需要char *

        string str1 = CString(stu[i].name);

        string str2 = CString(stu[i].yuanxi);

        string str3 = CString(stu[i].email);

        string str4 = CString(stu[i].phone);


        fout<<str.c_str()<<" "

            <<str1.c_str()<<" "

            <<str2.c_str()<<" "

            <<str3.c_str()<<" "

            <<str4.c_str()<<endl;

        if (fout.fail())  

            break;

    }

    fout.close();

    MessageBox("保存成功!");

}

~~~




7.4 读取信息:

~~~c

void CClassAddresslistDlg::OnBUTTONduqu()

{

    m_list.DeleteAllItems(); // 全部清空

    ifstream fin("ZHM.txt",ios_base::in);

    string a,b,c,d,e;

    fin>>a>>b>>c>>d>>e;

    for(int i=0;!fin.fail();++i){

        int n=m_list.GetItemCount();

        m_list.InsertItem(n,a.data());

        m_list.SetItemText(n,1,b.data());

        m_list.SetItemText(n,2,c.data());

        m_list.SetItemText(n,3,d.data());

        m_list.SetItemText(n,4,e.data());

         MessageBox("读取成功!");

        Student s1;

        s1.number=a.data();

        s1.name=b.data();

        s1.yuanxi=c.data();

        s1.email=d.data();

        s1.phone=e.data();

        stu.reserve(stu.size()+1);//增加容量以防止溢出

    stu.push_back(s1);

    fin>>a>>b>>c>>d>>e;

    }

    fin.close();

}

~~~






### 其他


用C++的MFC编写一个通讯录系统,可以采用对话框为主界面,配合列表控件(CListCtrl)显示联系人信息。以下是一个简单的思路和基本的代码实现:


1. 创建MFC项目,并选择基于对话框的应用程序。


2. 在对话框中放置一个列表控件(ID为IDC_LIST_CONTACTS),并设置其属性以显示网格线和全行选中。在对话框类中添加成员变量`CListCtrl m_listContacts;`与该控件关联。


3. 为了方便管理,我们可以创建一个Contact结构体,包含姓名、电话等成员。


4. 在初始化对话框时,添加列表控件的列标题。


5. 添加功能按钮,如添加、删除、修改联系人。


以下是一个简单代码示例:


```cpp

// ContactManagerDlg.h

#pragma once

#include "afxcmn.h"


struct Contact {

    CString name;

    CString phone;

};


class CContactManagerDlg : public CDialogEx {

public:

    CContactManagerDlg(CWnd* pParent = NULL);


    enum { IDD = IDD_CONTACTMANAGER_DIALOG };


protected:

    virtual void DoDataExchange(CDataExchange* pDX);


protected:

    HICON m_hIcon;


    virtual BOOL OnInitDialog();

    afx_msg void OnPaint();

    afx_msg HCURSOR OnQueryDragIcon();

    DECLARE_MESSAGE_MAP()


public:

    CListCtrl m_listContacts;

    std::vector<Contact> m_contacts;


    afx_msg void OnBnClickedButtonAdd();

    afx_msg void OnBnClickedButtonDelete();

    afx_msg void OnBnClickedButtonEdit();

};

```


```cpp

// ContactManagerDlg.cpp

#include "stdafx.h"

#include "ContactManager.h"

#include "ContactManagerDlg.h"


#ifdef _DEBUG

#define new DEBUG_NEW

#endif


CContactManagerDlg::CContactManagerDlg(CWnd* pParent /*=NULL*/)

    : CDialogEx(IDD_CONTACTMANAGER_DIALOG, pParent) {

    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}


void CContactManagerDlg::DoDataExchange(CDataExchange* pDX) {

    CDialogEx::DoDataExchange(pDX);

    DDX_Control(pDX, IDC_LIST_CONTACTS, m_listContacts);

}


BEGIN_MESSAGE_MAP(CContactManagerDlg, CDialogEx)

    ON_WM_PAINT()

    ON_WM_QUERYDRAGICON()

    ON_BN_CLICKED(IDC_BUTTON_ADD, &CContactManagerDlg::OnBnClickedButtonAdd)

    ON_BN_CLICKED(IDC_BUTTON_DELETE, &CContactManagerDlg::OnBnClickedButtonDelete)

    ON_BN_CLICKED(IDC_BUTTON_EDIT, &CContactManagerDlg::OnBnClickedButtonEdit)

END_MESSAGE_MAP()


BOOL CContactManagerDlg::OnInitDialog() {

    CDialogEx::OnInitDialog();


    SetIcon(m_hIcon, TRUE);

    SetIcon(m_hIcon, FALSE);


    m_listContacts.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 100);

    m_listContacts.InsertColumn(1, _T("Phone"), LVCFMT_LEFT, 100);


    return TRUE;

}


void CContactManagerDlg::OnPaint() {

    if (IsIconic()) {

        CPaintDC dc(this);


        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);


        int cxIcon = GetSystemMetrics(SM_CXICON);

        int cyIcon = GetSystemMetrics(SM_CYICON);

        CRect rect;

        GetClientRect(&rect);

        int x = (rect.Width() - cxIcon + 1) / 2;

        int y = (rect.Height() - cyIcon + 1) / 2;


        dc.DrawIcon(x, y, m_hIcon);

    } else {

        CDialogEx::OnPaint();

    }

}


HCURSOR CContactManagerDlg::OnQueryDragIcon() {

    return static_cast<HCURSOR>(m_hIcon);

}


void CContactManagerDlg::OnBnClickedButtonAdd() {

    // 实现添加联系人功能

}


void CContactManagerDlg::OnBnClickedButtonDelete() {

    // 实现删除选中联系人功能

}


void CContactManagerDlg::OnBnClickedButtonEdit() {

    // 实现编辑选中联系人功能

}

```


上述代码实现了一个基本的通讯录界面和对应的数据结构。需要注意这里并未实现具体的添加、删除和编辑功能,你可以根据需要进一步完善。此外,为了持久化通讯录数据,还可以考虑将联系人信息保存到文件或数据库中,并在启动时加载。




接下来,我们将实现添加、删除和编辑联系人的功能。首先需要创建一个新的对话框用于输入联系人信息(如姓名和电话),可以命名为`CContactDlg`


`CContactDlg`中,添加两个编辑框控件分别用于输入姓名和电话,为它们分别添加成员变量`m_strName``m_strPhone`


然后,在`CContactManagerDlg`类中实现添加、删除和编辑功能:


```cpp

void CContactManagerDlg::OnBnClickedButtonAdd() {

    CContactDlg dlg;

    if (dlg.DoModal() == IDOK) {

        Contact newContact;

        newContact.name = dlg.m_strName;

        newContact.phone = dlg.m_strPhone;


        m_contacts.push_back(newContact);


        int nIndex = m_listContacts.GetItemCount();

        m_listContacts.InsertItem(nIndex, newContact.name);

        m_listContacts.SetItemText(nIndex, 1, newContact.phone);

    }

}


void CContactManagerDlg::OnBnClickedButtonDelete() {

    POSITION pos = m_listContacts.GetFirstSelectedItemPosition();

    if (pos) {

        int nSelected = m_listContacts.GetNextSelectedItem(pos);

        m_listContacts.DeleteItem(nSelected);

        m_contacts.erase(m_contacts.begin() + nSelected);

    }

}


void CContactManagerDlg::OnBnClickedButtonEdit() {

    POSITION pos = m_listContacts.GetFirstSelectedItemPosition();

    if (pos) {

        int nSelected = m_listContacts.GetNextSelectedItem(pos);


        CContactDlg dlg;

        dlg.m_strName = m_contacts[nSelected].name;

        dlg.m_strPhone = m_contacts[nSelected].phone;


        if (dlg.DoModal() == IDOK) {

            m_contacts[nSelected].name = dlg.m_strName;

            m_contacts[nSelected].phone = dlg.m_strPhone;


            m_listContacts.SetItemText(nSelected, 0, dlg.m_strName);

            m_listContacts.SetItemText(nSelected, 1, dlg.m_strPhone);

        }

    }

}

```


现在,你已经实现了一个基本的通讯录系统。接下来可以考虑优化和新增功能,例如:


1. 将联系人信息保存到文件或数据库中,并在启动时加载。

2. 添加搜索功能,允许用户搜索联系人。

3. 支持按姓名、电话等字段排序联系人列表。

4. 改进UI,使其更美观易用。


根据自己的需求和兴趣,你可以不断完善这个通讯录系统,使其更加强大和实用。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  mcbWRrRPlhs5   2023年11月30日   26   0   0 访问令牌API应用程序
zhRhucGD3dLm