一、功能
构思确定通讯录的功能
1. 基本功能
- 添加联系人
- 删除联系人
- 修改联系人
- 显示联系人信息
2. 附加功能
- 查找联系人
- 读取保存联系人信息
3. 创意小功能
- 显示备注
- 电话号码必须为11位
- 双击报表视图中联系人即可修改联系人信息
- 查找联系人时报表视图只显示匹配的联系人信息
- 不允许添加重复联系人信息(一名联系人可以有多个电话)
- 未选中报表视图中联系人时修改联系人和删除联系人按钮不可用
- 查找联系人时根据关键字进行查找(即输入名字或电话的一部分或者仅选择群组都可以查找到匹配的联系人)
二、设计布局
1. 主对话框布局
- 左上角为
List Control
控件 - 所有虚线框都为
Group Box
控件 - 备注框为
List Box
控件 - 查找联系人中姓名框和电话框为
Edit Control
控件 - 查找联系人中群组框为
Combo Box
控件 - 查找联系人中姓名、电话和群组为
Static Text
控件 - 其余为
Button
控件
2. 添加联系人和修改联系人子对话框布局(两个对话框)
- 控件与主对话框的控件类型一样(自己判断)
通过点击主对话框中的添加联系人和修改联系人按钮分别弹出子对话框。
新建MFC应用程序的过程省略,类型选择基于对话框。(基本操作默认都会,不会的请自行百度)
子对话框可将自带的确认和取消按钮的Caption
属性改成保存和取消即可。
在资源视图中的Dialog插入两个新的对话框作为上述两个子对话框。
三、设置类、成员变量、命令、及虚函数
通过类向导进行此步操作
1. 类
分别为三个对话框添加类,命名随意即可。MailListtDlg
ContactAdding
ContactModifying
分别为本通讯录的主对话框类、添加联系人子对话框类、修改联系人子对话框类。(右键点击对话框找到添加类)
2. 成员变量
命名随意即可。
- 主对话框的成员变量
第1、2项分别为群组框Combo Box
的控件类别变量和值类别变量,第3、4、5、6项分别为姓名框和电话框Edit Control
的控件类别变量和值类别变量,第7项为备注框List Box
的控件类别变量,第8项为报表视图List Control
的控件类别变量。 - 子对话框的成员变量
第1、2项为群组框Combo Box
的控件类别变量和值类别变量,第3、4、5项分别为姓名框、电话框、备注框Edit Control
的值类别变量。
3. 命令
-
主对话框的命令
所有Button
控件添加单击响应函数BN_CLICKED
,List Control
控件添加消息NM_CLICK
DBLCLK
。 -
子对话框的命令
所有Button
控件添加单击响应函数BN_CLICKED
。(若是将对话框自带的确认和取消按钮的Caption
属性改成保存和取消则不用进行此项操作)
4. 虚函数
只需为两个子对话框各自添加一个初始化函数OnInitDialog
。
四、代码编写
以下代码的类名请根据自己之前的命名进行修改,对象名的命名随意。不懂的函数自行百度(我都是百度看懂的)。代码的顺序按功能的构思思路进行安排。
1. 添加一个类存储联系人各项信息
新建一个头文件将此类写进去,在需要用到此类的cpp文件中include此头文件。
class MyClass {
public:
//姓名,5个字内
char Name[12];
//电话,11个数字
char Phone[13];
//群组
char Group[10];
//群组索引(因为群组是ComboxBox控件,所以需要索引)
//初始化-1是为了当通讯录没有数据进行保存时不会错误将数据写入文件)
int Group_Index = -1;
//备注,50个字以内
char Remark[104];
};
2、添加全局变量统计联系人人数和存储各个联系人
stdafx.h
//统计联系人人数
extern int N;
//存储各个联系人
extern MyClass new_people[100];
-----------------------------------------------------------------------
stdafx.cpp
int N = 0;
MyClass new_people[100];
3、主对话框的初始化函数
实现读取保存联系人信息功能。在头文件中进行read函数的声明,在实现文件中进行read函数的定义;read函数用于读入文件中已有的联系人信息,初始化函数用读入的联系人信息进行初始化主对话框,在报表视图中显示联系人信息。
- read函数
MailListtDlg.h
void read();
-----------------------------------------------------------------------
MailListtDlg.cpp
void CMailListtDlg::Read(){
CStdioFile file;
CString str;
file.Open("test.txt", CFile::modeRead);
int now = 0;
while (file.ReadString(str) != NULL){
int i;
if (now == 0) {
N++;
for (i = 0; i < str.GetLength(); i++) {
new_people[N - 1].Name[i] = str[i];
}
new_people[N-1].Name[str.GetLength()] = '\0';
}
else if (now == 1) {
for (i = 0; i < str.GetLength(); i++) {
new_people[N-1].Phone[i] = str[i];
}
new_people[N-1].Phone[str.GetLength()] = '\0';
}
else if (now == 2) {
strcpy_s(new_people[N-1].Group, str);
}
else if (now == 3) {
new_people[N - 1].Group_Index = _ttoi(str);
}
else if (now == 4) {
for (i = 0; i < str.GetLength(); i++) {
new_people[N - 1].Remark[i] = str[i];
}
new_people[N-1].Remark[str.GetLength()] = '\0';
}
now++;
now %= 5;
}
}
- 初始化函数
BOOL CMailListtDlg::OnInitDialog(){
CDialogEx::OnInitDialog();
//初始化时读取文件内容,自定义的Read函数读取文件
CMailListtDlg Read;
Read.Read();
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
//设置报表视图的头标题
CRect rect;
CListCtrl* pmyListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST4);
LONG dwStyle = GetWindowLong(pmyListCtrl->m_hWnd, GWL_STYLE);
SetWindowLong(pmyListCtrl->m_hWnd, GWL_STYLE, dwStyle | LVS_REPORT);
LONG styles = pmyListCtrl->GetExtendedStyle();
pmyListCtrl->SetExtendedStyle(styles | LVS_EX_FULLROWSELECT |LVS_EX_GRIDLINES | LVS_NOSCROLL);
pmyListCtrl->GetWindowRect(&rect);
pmyListCtrl->InsertColumn(0, "姓名", LVCFMT_CENTER, rect.Width() / 3);
pmyListCtrl->InsertColumn(1, "电话", LVCFMT_CENTER, rect.Width() / 3);
pmyListCtrl->InsertColumn(2, "群组", LVCFMT_CENTER, rect.Width() / 3);
//当导入了联系人信息且联系人信息非空时,报表视图按文本中联系人信息顺序显示
int nlist = m_ListCtrl.GetItemCount();
if (new_people[0].Group_Index != -1) {
CString str;
for (int i = N - 1; i >=