周一晚上十点整!! 完工了, 从上周五晚上做到现在。
先上一个最终效果图:
12-19周二下午更新(修复了两个bug) 一个是修改的时候队列位置的错位问题, 一个是备注信息显示错乱的问题。
另外做了一个应用的图标。
首先说说一下总结, 虽然整个程序做完了, 但是还是有很多缺陷, 比如写了很多没有用的代码。 因为很多地方都不会, 直接去百度, 找到一个解决的办法就用了, 实际上会有更优的办法。 还有就是对于类的理解不够深刻, 很多想实现的东西还是用竞赛代码的思想去实现, 真正的工程代码肯定不会是我这种代码的格式。
之前从来没接触过工程,遇到了很多问题, 所以边做边记录。 做的过程中遇到的问题我基本都写在了里面并附有解决方法和参考的博客链接, 我想许多第一次写mfc的人应该也会遇到同样的问题, 所以应该会有一些帮助吧。 仅供参考, 没办法作为教程, 写的很散乱, 步骤可能也很跳跃。 毕竟是两者同时进行的时候, 写代码为主, 写博客为辅。
工程是周五晚开始做的, 这个记录是周六上午开始写的, 所以刚开始就没什么记录。 之后都是解决一个问题写一点记录一点, 会比较详细。
周五晚上弄了一下基本框架。 我用的是纯对话框做的。 我也不知道正确的顺序是啥, 一点点来吧。 首先是框架。
添加联系人框架
然后开始搞主框架, 首先解决的左边信息的显示问题, 刚开始我用的是列边框, 也就是listbox
, 其实是错的, 应该用列表控件 listctrl。
这才是我想要的, 能够显示信息。
紧接着是解决列表控件的初始化问题, 就是想要实现打开程序后, 通讯录的自动加载以及上面的分栏。
- 解决分栏问题:在OnInitDialog()函数中添加代码:
CListCtrl* pmyListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_TOT); //获取列表控件
DWORD dwStyle = GetWindowLong(pmyListCtrl->m_hWnd, GWL_STYLE);
SetWindowLong( pmyListCtrl->m_hWnd, GWL_STYLE, dwStyle | LVS_REPORT);
DWORD styles = pmyListCtrl->GetExtendedStyle();
pmyListCtrl->SetExtendedStyle(styles|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);//设置listctrl可以整行选择和网格条纹
CRect rect;
pmyListCtrl->GetWindowRect(&rect);
m_list.InsertColumn(0,"姓名",LVCFMT_CENTER,rect.Width()/6);//设置标题
m_list.InsertColumn(1,"电话",LVCFMT_CENTER,rect.Width()/6*2);
m_list.InsertColumn(2,"邮箱",LVCFMT_CENTER,rect.Width()/6*2);
m_list.InsertColumn(3,"分组",LVCFMT_CENTER,rect.Width()/6);
z这样列表的设置问题就解决了, 发现了一个博客, 里面写的很详细, listctrl总结。 顺便搞了一下在控制窗口的输出。最后用读文件应该也是用这种方法显示。
int nRow = m_list.InsertItem(0, "严嘉豪");// 插入行
m_list.InsertItem(1, "谭瑞");// 插入行
m_list.InsertItem(2, "马博");
m_list.SetItemText(nRow, 1, "110");// 设置其它列数据
m_list.SetItemText(nRow, 2, "87*****@qq.om");
m_list.SetItemText(nRow, 3, "无");
刚刚发现自己新建的窗口不对, 昨天创建的是非模式对话框(多个窗口是活动的), 但是我是想创建模式对话框(只有当前窗口是活动的)。
完全删除类的方法:
MFC Wizard中创建的类用类向导删除后并不能删除源文件,可以通过以下简单的几步完全删除:
1:从workspace中的fileview中删除对应的.h和.cpp文件。
2.再关闭项目,从实际的文件夹中删除对应的.h和.cpp文件。
3.再删除.clw文件。
再打开重新编译即可!
重新解决了添加按钮的对话框模式, 首先在资源视图的Dialog右键添加Dialog, 新建的窗口自己命名并且设置ID, 利用class wizard 自动添加类, 在主窗口#include”ADD.h” 包含文件, 在添加按钮中加入代码
void CZbookDlg::OnButtonAdd()
{
ADD dlg;
dlg.DoModal();
// TODO: Add your control notification handler code here
}
实现点击添加联系人按钮打开新的添加窗口。忙活了半天, 基本上是把昨晚上做的翻工了一遍。。。
半个小时又过去了, 基本的框架都已经想好了。主界面大概是这个样子:
有两个子窗口, 一个是添加联系人窗口, 一个是修改联系人窗口, 并且这两个窗口的布局基本相同。
机房吹空调好干啊。。 出去买点喝的透透气,回来继续写。
解决了分组下拉栏问题。 在里面添加了5个分组:全部、无、家人、同事、朋友。
方法是右键打开组合框(下拉栏)属性, 在,在数据栏添加初始数据, 用ctrl +enter换行, 取消分类, 不然系统会自动排序。 然后在initDialog() 函数初始化默认选项, 因为我把全部排在第一个, 所以下标是0。 添加代码
m_Flist.SetCurSel(0);//初始化分组选择下拉栏的默认选项。
效果如下
同理, 给添加联系人窗口和修改联系人窗口的下拉栏也初始化, 当然要注意的是, 没有了全部分组, 因为全部分组是查找的时候用的。
对于添加对话框的初始化函数, 需要用class wizard 来添加。 详见这里
因为删除函数需要读取选中的信息,现在我还没有初始化, 先不动修改和删除这两个模块。
CString strtemp;
//strtemp.Format("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);
strtemp.Format("bababalalal");
用来测试程序用的弹窗代码。
实现:在主窗口, 当没有选择联系人的时候, 无法点击删除和修改按钮, 当选中联系人后, 按钮可以点击。
效果:
。
添加方法:
首先给listctrl添加NM_CLICK消息函数(用class wizard) 在对应的函数里编辑:
DWORD dwPos = GetMessagePos();//通过查看点击位置 确定修改和删除按钮是否可点。
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
m_list.ScreenToClient(&point);
LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;
int nItem = m_list.SubItemHitTest(&lvinfo);
if(nItem != -1)// 选择了联系人
{
GetDlgItem(IDC_BUTTON_DEL)-> EnableWindow(TRUE);// 删除窗口可以点击 (传入的是按钮控件的ID)
GetDlgItem(IDC_BUTTON_CHANGE)-> Enab