mfc通讯录管理系统(精选6篇)
目录
一、引言.................................................1
二、需求分析.............................................1
三、整体设计.............................................2
1、系统框图...........................................2
2、模块功能...........................................2
四、代码编写.............................................2
1、定义一个Cperson类.................................2
2、定义文档类数据成员m_StudengtList...................3
3、初始化文档类成员...................................4
4、建立文档类和视图类数据成员之间的关系...............5
五、测试结果............................................10
1、编译并连接源程序,执行程序后显示的初始界面........10
2、添加王豆豆的信息显示的界面........................11
3、删除通讯录中的信息................................11
4、修改通讯录中的信息................................12
六、设计小结............................................12
一、引言
21世纪是IT普及的世界,到处都存在IT的身影,实时通讯已是占据它不可或缺的地位。一个好的、强大的通讯录系统的好坏,不但可以直接影响到企业、个人的人际关系,而且会间接的影响到企业、个人经济利益和社会地位。随着社会的发展,科技的进步,计算机的应用在社会各领域中都得到了普及,越来越多的人都感受到利用计算机进行各类管理的科学和便捷,利用计算机进行通讯管理已经是一种趋势。
MFC是Microsoft Foundation Class Library(微软基础类库)的缩写形式。它是C++的类集,提供面向对象框架,利用这个框架,程序员可以轻松的创建Windows应用程序。基于MFC的通讯管理系统具有美观的窗口界面、充足可靠的信息数据、简单方便的维护手段和灵活多变的查询方式以及快捷而准确的查询结果。
二、需求分析
通讯录使我们每个人必不可少的一个工具,利用通讯录我们可以对同学、朋友、同事等信息进行有效的管理,包括查询、添加、删除和修改等。
此通讯录系统利用本着人性化的设计,此系统包括了联系人的姓名、电话、地址、E-mail、和备注等信息,利用此系统可以对联系人进行查询、增加、修改、删除等操作,基本上可以满足我们对通讯录的需要。
基于MFC简易通讯录管理系统具有以下特点:1,操作简单,所有人不需学习就可以使用的系统;2,输入简单,输入框都有相关提示,我们可以按照提示输入相关信息;3,界面显示信息完整,界面上每一个编辑框显示一条联系人信息,很清楚地显示了联系人的全部信息。数据库的操作与运行相比文件较复杂,一般对安全性较高的大型信息管理系统采用数据库方式,这里我们采用文件存取方式即可。
三、整体设计
1、系统框图
通讯录管理系统查询记录添加记录 修改记录查询记录删除单条记录清除整组记录向前浏览 向后浏览
2、模块功能
(1)添加记录:可以增加通讯录相关信息;(2)修改记录:可以修改通讯录相关信息;(3)查询记录:可以查找通讯录中每个人的信息;(4)删除记录:可以删除通讯录单条个人信息;(5)清除记录:可以清除通讯录整个组信息;
四、代码编写
1、定义一个Cperson类
程序中处理的学生信息是一个数据序列,即线性表结构。以Coject为基类,公有派生Cperson类。Person.h中的代码:
class CPerson:public CObject { public: DECLARE_SERIAL(CPerson)//对类进行串行化宏定义 CPerson();virtual ~CPerson();
CString m_Name;//姓名 CString m_Phone;//电话 CString m_Company;//公司 CString m_Email;//Email public: };Person.cpp中编辑的初始化的代码 CPerson::CPerson(){
} //初始化人员信息(m_Name,m_Phone,m_Company,m_Email)m_Name=“";//姓名 m_Phone=”“;//电话 m_Company=”“;//公司 m_Email=”“;//Email virtual void Serialize(CArchive& ar);
2、定义文档类数据成员m_StudengtList 在AddressBookview.h中编写代码: class CAddressBookView : public CFormView { protected: // create from serialization only CAddressBookView();
DECLARE_DYNCREATE(CAddressBookView)public: CAddressBookDoc* GetDocument();public: virtual ~CAddressBookView();protected: POSITION m_Position;//指向链表中当前结点的指针 CObList *m_PersonViewList;//指向文档类成员(双向链表)的指针
protected: };DECLARE_MESSAGE_MAP()
3、初始化文档类成员
#include ”stdafx.h“ #include ”AddressBook.h“ #include ”Person.h“ #include ”AddressBookDoc.h“ #include ”AddressBookView.h“ void CAddressBookView::OnInitialUpdate(){
CFormView::OnInitialUpdate();GetParentFrame()->RecalcLayout();ResizeParentToFit();CAddressBookDoc *pDoc=GetDocument();//获得文档类指针
m_PersonViewList=&(pDoc->m_PersonList);//视图类指针指向文档类对象 m_Position=m_PersonViewList->GetHeadPosition();//获得头结点位置 CPerson*pListDoc=(CPerson *)m_PersonViewList->GetAt(m_Position);//获得头一个数据 m_strName=pListDoc->m_Name;
m_strPhone=pListDoc->m_Phone;m_strCompany=pListDoc->m_Company;m_strEmail=pListDoc->m_Email;//将表头结点数据赋给视图类成员变量 UpdateData(false);//刷新窗口
((CDialog*)this)->GotoDlgCtrl(GetDlgItem(IDC_EDIT_NAME));//将光标停在姓名编辑框 }
4、建立文档类和视图类数据成员之间的关系
编写命令按钮代码:(1)添加记录
void CAddressBookView::OnButtonAdd(){
//界面
((CButton*)GetDlgItem(IDC_CHECK_MODIFY))->EnableWindow(false);((CButton*)GetDlgItem(IDC_BUTTON_CLEAR))->EnableWindow(false);((CButton*)GetDlgItem(IDC_BUTTON_PREVIOUS))->EnableWindow(false);((CButton*)GetDlgItem(IDC_BUTTON_NEXT))->EnableWindow(false);((CButton*)GetDlgItem(IDC_BUTTON_ADD))->SetWindowText(_T(”继续添加“));((CButton*)GetDlgItem(IDC_BUTTON_DELETE))->SetWindowText(_T(”添加完毕“));((CEdit*)GetDlgItem(IDC_EDIT_NAME))->EnableWindow(true);
((CEdit*)GetDlgItem(IDC_EDIT_EMAIL))->EnableWindow(true);((CEdit*)GetDlgItem(IDC_EDIT_PHONE))->EnableWindow(true);((CEdit*)GetDlgItem(IDC_EDIT_COMPANY))->EnableWindow(true);m_strName=”“;m_strPhone=”“;m_strCompany=”“;
m_strEmail=”“;//清空编辑框 UpdateData(false);//刷新界面 CPerson *pListDoc=new CPerson();m_Position=m_PersonViewList->AddTail(pListDoc);//新建空人员信息添加至链表,并将当前位置移至该处
CAddressBookDoc *pDoc=GetDocument();//获得文档指针 pDoc->SetModifiedFlag();//设置文档被修改标置
((CDialog*)this)->GotoDlgCtrl(GetDlgItem(IDC_EDIT_NAME));//姓名编辑框获得焦点
}(2)删除记录
void CAddressBookView::OnButtonDelete(){
除
delete pOld;//释放空间
if(m_PersonViewList->IsEmpty())//链表若为空,则调用添加生成CString str;GetDlgItem(IDC_BUTTON_DELETE)->GetWindowText(str);if(str==”删除记录(&D)“){
CObject *pOld;//临时对象指针
pOld=m_PersonViewList->GetAt(m_Position);//使其指向当前指针 m_PersonViewList->RemoveAt(m_Position);//将当前结点从列表中删// TODO: Add your control notification handler code here
一个新结点
{ CAddressBookDoc *pDoc=GetDocument();//获得文档指针
}
} pDoc->OnNewDocument();m_Position=m_PersonViewList->GetHeadPosition();CAddressBookDoc *pDoc=(CAddressBookDoc*)GetDocument();pDoc->SetModifiedFlag();//获得文档指针,标志文档已被修改 OnInitialUpdate();//显示列表第一个结点
else {
AfxMessageBox(”添加完毕!“);((CButton*)GetDlgItem(IDC_CHECK_MODIFY))->EnableWindow(true);((CButton*)GetDlgItem(IDC_BUTTON_CLEAR))->EnableWindow(true);((CButton*)GetDlgItem(IDC_BUTTON_PREVIOUS))->EnableWindow(true);((CButton*)GetDlgItem(IDC_BUTTON_NEXT))->EnableWindow(true);((CButton*)GetDlgItem(IDC_BUTTON_ADD))->SetWindowText(_T(”添加记录(&A)“));((CButton*)GetDlgItem(IDC_BUTTON_DELETE))->SetWindowText(_T(”删除记录(&D)“));
}(3)清除记录
void CAddressBookView::OnButtonClear(){ if(m_PersonViewList->GetCount()==1)//链表若为空,则调用添加生成} // TODO: Add your control notification handler code here((CEdit*)GetDlgItem(IDC_EDIT_NAME))->EnableWindow(false);((CEdit*)GetDlgItem(IDC_EDIT_EMAIL))->EnableWindow(false);((CEdit*)GetDlgItem(IDC_EDIT_PHONE))->EnableWindow(false);((CEdit*)GetDlgItem(IDC_EDIT_COMPANY))->EnableWindow(false);
一个新结点
{
} AfxMessageBox(”没有可清空的记录!“);return;if(MessageBox(”所有的记录将被清空!“,”清空警告“,MB_YESNO)==IDYES)
{ CAddressBookDoc *pDoc=GetDocument();//获得文档指针 pDoc->OnNewDocument();
m_Position=m_PersonViewList->GetHeadPosition();} }
(4)向前浏览
void CAddressBookView::OnButtonPrevious(){
POSITION m_templeposition;//定义一个临时位置指针
m_templeposition=m_Position;//并使其指向当前结点的前驱结点 m_PersonViewList->GetPrev(m_templeposition);//获得当前结点位置的前一个
CPerson*pListDoc=(CPerson*)m_PersonViewList->GetAt(m_Position);//获得前一个人员的信息 if(m_templeposition==NULL){//若到链表头结点
} else { m_Position=m_templeposition;//当前指针定位到前一个 AfxMessageBox(_T(”已到表头!“));
} m_strName=pListDoc->m_Name;m_strPhone=pListDoc->m_Phone;m_strCompany=pListDoc->m_Company;m_strEmail=pListDoc->m_Email;//赋值给视图类数据成员 UpdateData(false);//刷新窗口
(5)向后浏览
void CAddressBookView::OnButtonNext(){
POSITION m_templeposition;//定义一个临时位置指针
m_templeposition=m_Position;//并使其指向当前结点的前驱结点 m_PersonViewList->GetNext(m_templeposition);//获得当前结点位置的后一个
CPerson*pListDoc=(CPerson*)m_PersonViewList->GetAt(m_Position);
} //获得前一个人员的信息 m_strName=pListDoc->m_Name;m_strPhone=pListDoc->m_Phone;m_strCompany=pListDoc->m_Company;m_strEmail=pListDoc->m_Email;//赋值给视图类数据成员 UpdateData(false);//刷新窗口 if(m_templeposition==NULL){//若到链表尾结点
} else { m_Position=m_templeposition;//当前指针定位到后一个 AfxMessageBox(_T(”已到表尾!"));
// TODO: Add your control notification handler code here }(6)释放链表对象空间
class CAddressBookDoc : public CDocument { protected: // create from serialization only CAddressBookDoc();DECLARE_DYNCREATE(CAddressBookDoc)// Attributes public: CObList m_PersonList;//文档类成员
public: virtual ~CAddressBookDoc();protected: DECLARE_MESSAGE_MAP()};
五、测试结果
1、编译并连接源程序,执行程序后显示的初始界面
2、添加王豆豆的信息显示的界面
3、删除通讯录中的信息
4、修改通讯录中的信息
六、设计小结
在做这个小课题之前,先参考一些书,对整个Windows程序内部运行机制先做一定的了解,整个Windows程序的运行机制是:1,创建窗口:设计一个窗口
类、注册窗口类、创建窗口、显示及更新窗口;2,消息循环;3,窗口过程函数,其中窗口过程函数是关键,根据我们的需要来进行编写。
MFC(Microsoft Foundation Class,微软的基础类库),它是微软为了简化程序员的开发工作所开发的一套C++类的集合,是一套面向对象的函数库,以类的方式提供给用户使用,利用这些类可以有效地帮助程序员完成Windows应用程序的开发,而MFC AppWizard 是一个辅助我们生成源代码的向导工具,它可以帮助我们自动生成基MFC框架的源代码。该向导的的每一个步骤中,我们都可以根据需要来选择各种特性,从而实现定制应用程序。
对于基于MFC的简易通讯录管理系统的设计,需要对联系人的信息进行管理,需要调用MFC类中的函数,对于这个MFC的应用程序,主要的类有CPerson、CAddressBookView、CAddressBookDoc等几个类,里面封装了一些函数和一些变量,例如CPerson是由Cobject派生出来的,CPerson中的构造函数CPerson()对人员的信息进行初始化;CAddressBookView类封装了函数OnButtonAdd()、OnButtonDelete()、OnButtonPrevious()、OnChangeEditCompany()等函数,实现对人员信息的添加,删除,信息的查询,改变工作信息;CAddressBookDoc类封装了OnNewDocument()、DeleteContents()函数,实现对文档类成员的初始化和对文档成员的删除。
1 系统实现
1.1 需求分析
通讯录主要提供联系人的通讯数据的存取以及查找这些功能,所实现的系统应该具备通讯数据在数据库中的存取及查找的功能,并能将这些数据反映到用户界面中。
1.2 数据库设计
由于通讯录中的数据比较简单,不涉及复杂的数据关系,因此使用一张数据表即可。使用Access 2003来创建数据库telbook mdb,数据表名为telbook,所需字段有:姓名,性别,生日,邮箱,固定电话,移动电话,关系(即与用户的关系)。其中除生日为日期类型外,其余均为文本类型。
1.3 用户界面设计
为了使实现的通讯录既富有个性又实用,因而用户界面采用不规则的窗口,同时搭配列表视图来显示数据。首先实用Visua C++创建一个基于对话框的MFC工程,并将对话框属性中的System Menu和Title Bar属性改为false,这样做的目的主要是为了在进行窗口裁剪时不受标题栏的约束。为姓名,性别,生日,邮箱,固定电话,移动电话,关系这些字段拖拽出相应的标签与文本框来编辑数据。然后进行用户界面的裁剪,要实现的是一个类似掌上游戏机形状的界面,如图1。为了达到这种效果,编写一个newShape方法,具体代码如下:
首先创建了一个椭圆形的区域rgn1和一个矩形区域rgn2。椭圆形区域位于原对话框窗口下半部,宽度与原对话框相同。矩形区域位于上半部,宽度为原对话框宽度的一半,且居中放置。然后将两个区域合并为区域dlgRgn,并使用SetWindowRgn((HRGN)dlgRgn,TRUE)将窗口区域设置为dlgRgn,然后在OnInitDialog函数中调用newShape函数。这样用户界面就完成了。
1.4 连接数据库
使用ADO技术实现应用程序与数据库的连接是一种非常简单且功能强大的解决方案。ADO技术使得程序员能够编写通过OLE DB提供者对在数据库服务器中的数据进行访问和操作的应用程序,其主要优点是易于使用、速度快、耗内存少和节省磁盘空间。
为了存储和使用数据库中的数据首先需要建立应用程序到数据库的连接,不过由于ADO技术是基于COM的,因而在建立连接之前应该先初始化COM库。具体方法为在stdafx.h头文件中添加#import“C:Program FilesCommon FilesSystemadomsado15.dll”no_namespace rename(“EOF”,“ADOEOF”),然后在正式使用ADO之前调用AfxOleInit()函数初始化COM库。之后就可以创建到数据库的连接,声明_ConnectionPtr类型的对象m_pConnection,使用如下代码建立连接:
这样数据库连接就建立起来了。为了使用数据库实现存储和查询的功能,还需要数据集对象。声明_RecordsetPtr类型的对象m_pRecordset,使用类似_ConnectionPtr的方法来初始化数据集对象。代码如下:
然后就可以使用数据集对象的Open方法来取得数据库中的数据,例如取得整个通讯录表中的数据存入数据集中的代码为:
要取得各条记录中的数据,先要使用m_pRecordset的Move(ADO_LONGPTR num)方法移动到对应的记录行上,然后使用GetCollect(_variant_t&index)方法将这一行中各个域的数据取出并存放到变量中。而添加数据到数据库的方法为首先调用m_pRecordset->AddNew()来插入一行,之后使用PutCollect(_variant_t&index,_variant_t&value)方法来填充此行的各个域。结合使用这些方法就能灵活方便的将这个通讯录程序的各个功能加以完善,这样一个高效的数据管理程序就完成了。
2 总结
使用MFC建立用户界面结合使用ADO技术来管理数据库的方法非常简单高效并且不失灵活性。这种技术的关键在于理清ADO中三大部分_ConnectionPtr,_RecordsetPtr,_CommandPtr之间的关系,并且能够根据实际情况灵活的结合这三部分功能实现强大的数据库管理功能。值得注意的是MFC中各个类的层次结构往往是限制程序功能一个重要因素,因此在掌握ADO技术的同时还应深入MFC内部机理的研究,这样才能写出高效的功能强大的数据管理程序。
摘要:使用MFC实现的应用程序通常效率高、速度快而且灵活性大,然而其对于数据库的支持却不是很好,不过自从微软推出A-DO技术以后这一缺憾也被弥补了。结合使用这两种技术能够方便快捷的实现各类信息管理软件。通讯录程序虽然功能简单,但是要用到这两种技术的很多精髓部分,因而非常适宜用来阐述MFC和ADO技术。
关键词:数据库,用户界面,ADO,MFC,Access
参考文献
[1]黄承安.Visual C++.NET经典开发案例[M].北京:中国铁道出版社,2003.
[2]侯俊杰.深入浅出MFC[M].武汉:华中科技大学出版社,2001.
[3]Jeff P.MFC Windows程序设计[M].北京:清华大学出版社,2001.
[4]John E.Swanke.Visual C++MFC扩展编程实例[M].北京:机械工业出版社,2000.
[5]Gunderloy M.ADO与ADO.NET编程指南[M].北京:电子工业出版社,2002.
[6]刘晓华.精通MFC[M].北京:电子工业出版社,2004.
[7]David S.ADO编程技术[M].北京:清华大学出版社,2001.
如果你不希望把打印机、复印机、扫描仪、传真机等外设产品都挤在一个本不宽裕的办公环境中,那么了解一下兄弟公司最新发布的MFC-3360C,或许这就是一个很好的解决方案。MFC-3360C看上去非常像一台传统的传真机,它的体积小巧,占用桌面的面积也不大,你完全不需要对设备的摆放发愁,MFC-3360C可以非常舒服地融入小型办公环境之中。值得一提的是,MFC-3360C还提供了电话听筒并且在控制面板上配置了用于拨号的数字键盘,这样既能符合大多数用户收发传真的习惯,还能作为一部电话独立使用,同时进一步减小了桌面空间占用。除了造型紧凑以外,MFC-3360C的功能也十分丰富,打印、扫描、复印、传真四项主要功能样样齐备,而且它还配置了20页容量的ADF(自动送稿器),能非常便捷地处理多页文档,几乎所有日常办公用得上的功能MFC-3360C都有提供。
你可以将MFC-3360C当作一台复印、扫描或传真设备单独进行使用,并且操作起来与传统的单功能设备十分类似,更为方便的是,MFC-3360C还能通过USB连接在PC上利用PC FAX驱动直接发送传真。由于MFC-3360C的扫描单元采用的是馈纸式而不是平板式结构,因此它不能处理一些较厚的介质,不过我们认为能连续输入多页文档的馈纸式扫描单元也很实用,更适合普通用户的日常办公需求,毕竟大多数用户需要处理特殊介质的机会并不多。设备的安装和初始化过程简单、易用,基本上不需要用户进行干预。对比上一代产品,MFC-3360C还在产品的易用性方面进行了改进,墨水盒的安装位置转移到了机器的右前侧,用户可以方便地在设备的前端完成更换耗材的操作。安装好4色分体式墨盒,连接上USB打印电缆,然后在向导程序中选择好你的连接方式,其余的工作安装程序都会自动完成。
出于产品的定位以及相对低廉的售价,要求MFC-3360C还能有非常出色的打印性能也是不现实的。不过从测试的结果来看,MFC-3360C的表现还算尚可,它完成全部的测试项目用时19分钟左右,它的打印速度虽然算不上出类拔萃,但足以满足打印量不是很大的个人或小型办公用户的打印需求。MFC-3360C的文字打印效果不错,6磅大小的英文字符目测距离可以轻松辨识,美中不足的是打印文字的边缘处理得不是非常平滑,尤其是在打印小字体时显得有些毛糙。默认设置下MFC-3360C的图形打印效果不错,各种图形线条清晰,颜色过渡自然没有明显色阶,并且大面积色彩填充也十分均匀,几乎观察不到双向打印产生的条带。办公之余打印几张照片,MFC-3360C也能较为出色地完成,在选择使用brother专用照片纸后,可以使用最小1.5pl的墨滴,更小的墨滴尺寸使得打印照片的颗粒感明显减少,同时画面也更加细腻,接近普通冲印照片的感觉。另外,在默认色彩控制的情况下,打印的照片有些轻微的偏色并且色彩饱和度也稍微欠缺一些,如果不喜欢这种风格可以尝试在驱动中将色彩管理设置为鲜明,打印的结果会生动不少。
尽管MFC-3360C的整体性能并不算抢眼,但对于平时打印量不是很大的普通个人或小型企业用户而言,MFC-3360C则是一个十分合理的选择对象,你不需要花费过多的预算即可获得日常办公所需要的几乎全部功能。
brother MFC-5460CN
与MFC-3360C主要强调传真应用的特点不同,这款MFC-5460CN的造型则更加接近我们通常意义上的多功能一体机。同样的MFC-5460CN也采用的是超薄型机身设计,除了位于顶部的ADF略微有些凸出以外,其它所有功能都被整合到非常紧凑的机身之中(440×392×226mm),即便你的桌面已经拥挤不堪,它也能够十分从容地进行摆放。别看MFC-5460CN身材小巧,但它所提供的功能却着实不少,它配置了能扫描较厚或特殊介质的平板扫描单元,提供了便于连续处理多页文档的35页容量的自动送稿器(ADF),同时MFC-5460CN还内置了传真调制解调器,既可以当作一台传真机独立进行使用,还能够通过PC-FAX驱动在电脑上更为便捷地收发传真。值得一提的是,MFC-5460CN标配了网络连接能力,我们只需将它连接到办公室的网络环境中,就能便捷地进行打印以及传真,另外,借助MFC-5460CN的网络连接,我们还可以将文档扫描至目标计算机或通过电子邮件发送出去。
扫描单元的下方是功能丰富的控制面板,面板的中央配有一个能显示中文的显示屏幕,尽管只能显示单行文字,但同样可以为操作带来很好的提示作用,同时菜单的设置和按键也配合得比较协调,设置起来并不麻烦,而一些例如喷嘴检查、墨头校正等常规的设备维护功能也都可以在控制面板上直接调用,减小了对电脑的依赖。不过,MFC-5460CN的供纸能力比较有限,只有100页容量的纸盒容量并不充裕,不太适合日常打印量较大的用户选择。
和MFC-3360的情形类似,MFC-5460CN的安装设置过程也十分简便,跟随向导程序的指示既可,不需要过多的设置既可完成驱动安装工作。而且类似纸盘、托架等附件也都集成在机身上,可以折叠收放,不需要用户再进行额外的装配。MFC-5460CN的墨水盒采用的是各色分离设计,可以用完一色更换一色,能减少墨水浪费,并能有效降低设备的使用成本。而且MFC-5460CN还采用了前端墨盒设计,只需打开位于一体机前端右侧的侧门,就能轻松完成耗材更换工作。
MFC-5460CN在有限的采购成本下提供了相当丰富的功能特性,因此我们也无需对它的性能有过多的苛求,毕竟产品需要在功能、性能以及造价这三者之间进行权衡。总体来看,MFC-5460CN默认设置下的性能与MFC-3360C基本相当,完成全部测试项目大致在20分钟左右,应付一些小批量的打印作业不成问题。MFC-5460CN的文字和图形打印效果不错,层次过渡自然,而且纯色填充也比较均匀,主要的不足是在打印非常细小的线条时显得略欠精致,并且文字的边缘也不够锐利。MFC-5460CN打印的照片看上去很不错,在最高精度下照片的打印精度很好,并且墨滴的痕迹也较为轻微,画面细腻,接近一般冲印照片的效果。只不过照片的反差一般,色彩饱和度不够。
06a13526
余思远
时间过得很快,历时一个月的短学期即将结束,我们小组的mfc课题也基本完成。虽然只有短短的一个月,但却带给我很多。在小组成员的共同努力下,基本解决了计划中的一个个问题,要实现一个功能并不算复杂的计算器,也没有想象中那么简单。
Mfc涉及的概念很多,语法也与以前有些许不同,在c++基础上新增的内容也有许多。从开始编辑一个简单的界面,通过这段时间的学习,终于感到掌握了些许了,但想更加熟练的使用,也必须付出更多的时间吧。我发现在编程过程中,并不能只想着眼前所负责的这一块,许多对许多综合多方面进行考虑,需要与自己队友进行配合,作出合理的计划和安排。
一、创建对话框对象
1.首先利用资源编辑器创建对话框资源,并针对该对话框资源定义一个对话框类:classCTestDlg :public CDialog
2.创建话话框对象
模态对话框的创建:
如:
CTestDlgdlg;
dlg.DoModal();
非模态对话框创建:
如:
CTestDlgdlg;
dlg.Create(IDD_DIALOG, this);
但这样是得不到一个正常显示的非模态对话框的。因为模态与非模态对话框的实现方式并不相同,这里我们还要注意几点。
非模态对话框创建完成后是隐藏着的,必须调用ShowWindow来进行显示。
对于模态对话框,当执行到DoModal 函数以创建对话框时,程序会暂停执行,直至模态对话框关闭。所以创建模态对话框可以采用局部对象。
但是,对于非模态对话框,当执行Create函数时并不会暂停执行,当执行到大括号“}后Dlg局部对象被销毁生命周期结束,于是异常出现了。
解决方法有两个:
一、在View类中定义一个CTestDlg 成员变量。
二、动态创建一个CTestDlg 变量,并重写CTestDlg 类的 PostNcDestroy函数,在该函数里销毁对象 deletethis;
无论创建的是模态对话框,还是非模态对话框,当我们单击确定或取消按钮后对话框都会消失。但这时低层的操作却是不同的。
对于模态对话框,此时对话框对象的确是被销毁了,但对于非模态对话框,这时只是隐藏起来不再显示。这需要我们自己调用DestoryWindow函数来进行销毁工作。
这时我们必须重写 CTestDlg 的 OnOK、OnCancel 两个函数(这两个是基类CDialog的虚函数),在这两个函数内调用DestroyWindow函数,并注意不再调用基类CDialog相应的函数。正确地创建非模态对话框的代码如下:
CTestDlg*pDlg = new CTestDlg;
pDlg->Create(IDD_DIALOG, this);
pDlg->ShowWindow(SW_SHOW);
同时,在CTestDlg 类的 PostNcDestroy函数中销毁对象:deletethis;
二、动态创建按钮
1.在对话框类CTestDlg 中定义一个 CButton 类对象,作为其成员变量。
2.在相应的消息处理中,调用 CButton类的Create函数创建按钮。
要注意两点:
如果在调用CButton::Create创建按钮时没有指定WS_VISIBLE 风格,那么随后一定要调用这个按钮对象的ShowWindow函数,来将该按钮显示出来。
为防止该CButton关联多个按钮,这里需要进行一些设置,如下:
if(!m_btn.m_hwnd)
{
// CButton 对象m_btn 未关联一个按钮
m_btn.Create(....);
}
else
{
// CButton 对象m_btn 已关联一个按钮
其他操作...}
当然,方法并不只这一种。但这是最漂亮的方法。
三、设置控件文本文字
1.下面列举几个用来设置控件文本文字的函数:
// 取得对话框中指定控件的窗口句柄。控件通过ID标识来指定
CWnd*GetDlgItem(int nID)const;
void CWnd::GetDlgItem(int nID, HWND* phWnd)const;
// 取得窗口文本
intGetWindowText(LPTSTR lpszStringBuf, int nMaxCount)const;
voidGetWindowText(CString& rString)const;
// 设置窗口文本
voidSetWindowText(LPCTSTR lpszString);
// 取得指定控件窗口文本。控件通过ID标识来指定
intGetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount)const;
intGetDlgItemText(int nID, CString& rString)const;
// 设置指定控件窗口文本。控件通过ID标识来指定
void SetDlgItemText(int nID, LPCTSTR lpszString);
// 取得指定控件窗口文本,并转化为UINT 类型返回。控件通过ID标识来指定
UINT GetDlgItemInt(int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE)const;// 设置指定控件窗口文本,由UINT类型转化为字符。控件通过ID标识来指定
voidSetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE);
2.可以为对话框控件关联一个变量,在CTestDlg 类的DoDataExchange来完成数据的更新与交换。这里我们需要重点说明 DoDataExChange 函数:
首先引用MSDN的一段解释吧:Called by the framework to exchange and validate dialog data。意指框架调用此函数来改写与确认对话框数据。
其实DoDataExChange函数主要是通过DDX_TEXT(....)或 DDX_CONTROL(....)来实现数据的实时关联的。
我从我的MSDN中随便拿来一个定义:
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, BYTE& value);
其实这个要关联的话也很简单,没有那么复杂。如下:
value = GetDlgItemInt(nIDC);
SetDlgItemInt(nIDC, value);
而DoDataExchange 函数是在UpdateData函数内部调用的。
该函数只有一个布尔型参数,b31.org 它决定了数据传送的方向:
调用UpdateData(TRUE),将数据从对话框的控件中传送到对应的数据成员中。
调用UpdateData(FALSE),则将数据从数据成员中传送给对应的控件。
UpdateData(FALSE)是将变量的值传到控件.UpdateData(TRUE)是从控件中取值到关联的变量
四、对话框伸缩功能的实现
只关联到两个函数:
// 取得指定窗口边框折尺寸
void GetWindowRect(LPRECT lpRect)const;
// 设置指定窗口(控件)的位置同尺寸
BOOL SetWindowPos(const CWnd* pWndInsertAfter, intx, inty, int cx, intcy, UINTnFlags);
五、逃跑按钮的实现
1.创建一个基于对话框的MFC 程序,删除原有的控件后,再添加两个按钮,更改两按钮名为”你能抓到我吗?“
2.打开类视图,定义一个新类CNewButton,这个新类的基类为CButton。并为此类添加一个成员变量:CNewButton*m_pbtn;
3.打开资源视图,分别为两个按钮创建两个CNewButton类关联变量:m_btn1, m_btn2;
4.在CXXXDlg中改写其OnInitDialog函数。主要添加:
m_btn1.m_pbtn = &m_btn2;
m_btn2.m_pbtn = &m_btn1;
5.对于CNewButton 类,必定其OnMouseMove函数。主要添加:
ShowWindow(SW_HIDE);
m_pbtn->ShowWindow(SW_SHOW);
编译,连接。OK
六、属性页、属性表单与向导的建立
1.创建属性页
打开资源编辑器,点击Dialog 资源并在列出的选项中,选择:IDD_PROPPAGE_LARGE。建立属性页资源。
之后,我们就可以其上添加其他控件来完善我们的属性页。关于属性页的完善操作我们在后面会谈到。
属性页资源完善后,再为每一个属性页关联一个类。
2.创建属性表单
打开类视图,添加新类CPropSheet,其基类为CPropertySheet。
之后再为其添加属性页类对象,并在其构造函数中利用AddPage函数将属性页添加到表单上。
3.消息响应
再主菜单的最后再增加一个菜单项,并为此菜单添加消息响应函数。
在此响应函数中创建属性表单:
CPropSheetpropSheet(TEXT(”属性表单"));
propSheet.DoModal();
4.向导的创建
创建一个向导类型的对话框,应该遵循创建一个标准属性表单的步骤来实现。
但在调用属性表单对象的DoModal函数之前,应该先调用SetWizardMode函数,来声明建立的是一个作为向导的属性表单。
所以,应在DoModal函数之前添加如下代码:
propSheet.SetWizardMode();
5.属性页的完善操作
首先我们要注意到属性页,澳门新濠天地官网66bb.org 在三个不同时期的关键性操作:当属性表单中的某属性页被选中,从而成为一个活动的页面时,应用程序框架就会调用OnSetActive函数。
OnSetActive 是其基类的一个虚函数,我们可以重写这个函数并在其中进行一些操作。
假设当前我们处于属性表单中的某属性页,当我们点击下一步并将进入下一个属性页时,应用程序框架会调用OnWizardNext函数。
OnWizardNext 是其基类的一个虚函数,我们可以重写这个函数并在其中进行一些操作。类似的还有OnWizardBack 同 OnWizardFinish函数。
当一个属性页被创建时,会调用其OnInitDialog函数。
我在刚开始接触Windows编程时, 从Visual Basic开始, 从MFC开始, 虽然写出了程序, 但自己都不知道程序是如何运行的, 从而造成写程序“容易”修改难, 设计程序“容易”维护难的状况.经过MFC Windows程序设计的学习之后,明白了有关知识。
API函数是Windows提供给应用程序的编程接口, 任何用户应用程序必须运行在API函数之上.直接使用API编程是了解操作系统运行细节的最佳方式, 而且熟知API函数也是对程序开发者的一个最基本的要求.这课程以API函数作为起点介绍Windows编程, 使我撇开C++的特性专心熟悉Win32编程思路和消息驱动机制.但是, 在开发大型系统的时候, 往往并不完全直接使用API函数, 而是使用MFC类库框架程序.MFC对90%以上的API函数进行了面向对象化包装, 完全体现了对象化程序设计的特点, 是目前流行的类库.当我熟悉最基本的API函数编程以后, 就可以学习更高级的MFC编程了.但是, 虽然MFC仅仅是对API函数的简单封装, 由于我之前对C++语言的了解不够, 不清楚框架程序的工作机制, 即便是有经验的程序员在MFC复杂的结构面前也显得非常困惑.他们会“用”MFC, 却不知道为什么这么“用”, 在运行程序出错时这种现象带来的问题就很明显, 他们不会改.面对一个大的项目, 代码往往需要手工添加和修改, 而很少能够依靠VC++的向导.为此, 这门课程介绍了设计MFC中的类.函数和宏定义.通过对MFC类库的分析和了解, 不仅能够使我更好地使用MFC类库, 同时, 对于自己设计和实现框架和类, 无疑也有相当大的帮助.之后, 这课程还讲述了Windows系统编程中当前最为热门的话题--DLL注入技术.远程进程技术.HOOKAPI技术等, 并配有完整而具体的实例.从这门MFC Windows 应用程序设计,我掌握了 :.Windows应用程序的基础知识
Windows应用程序是靠消息来驱动的,消息是一个描述事件的结构。
在Windows应用程序的主函数中,首先要注册窗口类,然后创建并显示窗口。创建窗口后程序就进入消息循环,在消息循环中,程序不断地获得消息并将消息派送给对应的窗口函数进行处理。
窗口函数是处理事件的地方,它为switch-case结构,每一个case对应一段消息相应代码。
用函数对Windows应用程序进行封装可以使程序的结构更为清晰。
Windows应用程序的类封装
CWinApp类是MFC对Windows主函数的封装,通过派生 CWinApp可以得到自己的应用程序类,在应用程序类中主要实现了全局初始化操作,应用程序类创建了主窗口后便进入了消息循环。
应用程序的主窗口一般都是CFrameWnd的派生类,可以通过派生该类得到自己的主窗口类。
Windows应用程序的窗口函数封装到CCmdTarget类中,所有希望相应消息的类都应该以CCmdTarget为基类来派生。
MFC是用消息映射表来实现消息与消息相应函数之间的映射的。MFC通过四个
宏来声明和实现消息映射表。MFC的这种表驱动的机制使消息处理结构变
得更加清晰,明了。.MFC应用程序框架
应用程序类,框架窗口类,试图类,文档类构成了应用程序的框架,框架的功能是通过各类之间的协调工作实现的类。
MFC采用文档/试图结构来实现数据和数据表现的分离,文档试图的分离有利于数据和数据表现的单独改变。
MFC用类信息存储了动态创建类对象时所需要的消息。图形
Windows提供了图形用户接口使用户得以在窗口中绘图。
在MFC中使用CDC类的派生类来向窗口和打印机等输出设备绘图。每个设备环境中包含笔画.画刷,位图,调色板,字体等GDI对象。
可以通过创建GDI对象并将其选入设备环境来实现所需要的绘图操作。5MFC的通用类
在MFC中,仍然可以使用Windows及C的所有数据类型。但是,为了把数据与对数据的操作方法封装在一起,MFC又定义了一些和数据相关的类从而使得数据的使用更加方便。习惯上人们把这些类叫做通用类。
简单的数据类CPoint,CSize和CRect;
字符串类CString;
集合数据类的基本概念及CArray类;
文档类和视图类之间的数据传递。
视图类对象用成员函数GetDocument获得文档类对象指针,然后视图对象通过这个指针来访问文档对象中的数据。Windows应用程序的界面的设计
Windows应用程序的界面有单文档界面和多文档界面的区别,目前多文档界面已经不被人们所喜欢。
每次绘图操作结束后调用视图类成员函数InvalidateRect启动OnDraw函数以更新显示。
文档/视图类型的应用程序可以实现一个文档多个显示,但是在文档的内容发生改变的时候,要对所有的视图进行更新。
在需要时,应用程序的界面可以设计为带有滚动条的窗口形式。但在设计时要注意文档坐标与视图坐标之间的转换。
7鼠标和键盘
在应用程序的界面上,可以通过鼠标左击,右击,移动等事件来对用户的鼠标输入进行处理。
鼠标消息有用户区鼠标消息和非用户区鼠标消息两种,在应用程序中主要使用用户区鼠标消息。
可以用消息捕获函数来捕获窗口外的鼠标消息,以完成某些特殊的操作。可以通过处理字符消息,按键等键盘消息对用户的键盘操作进行相应。在计算机的显示器屏幕上,如果有多个窗口存在的话,则具有焦点的窗口所对应的应用程序是具有接收用户消息能力的程序,这个程序叫做“正在活动状态的应用程序”。可以用鼠标单击窗口使它具有焦点,当应用程序的窗口获得输入焦点时,会发出WM_SETFOCUS消息;而当窗口失去输入焦点时,会发出WM_KILLFOCUS消
息。资源
资源是供Windows应用程序使用的数据,它们驻留在执行文件中。程序运行时,随着程序的需要,这些数据可以被动态地加载进入内存。资源是程序用户界面的重要组成部分。常用资源有菜单,加速键,图标,位图。程序所需要的资源使用资源描述文件来说明,并在资源头文件中用标识符唯一地标识。资源可以使用VisualC++的资源编辑器来创建和编辑,也可以使用文本编辑器来编辑。菜单的使用与Windows的命令消息WM_COMMAND相关。
菜单项消息映射宏的格式是:
ON_COMMAND
菜单项动态修改的消息映射宏的格式是:
ON_UPDATE_COMMAND_UI
在文档/视图结构的程序中,资源的加载是由应用程序类的InitInstance函数通过构造CDocTemplate(包括其派生类)对象来完成的。
加速键在资源描述文件中与所对应的菜单项关联。
图标使用Visual C++开发环境的菜单ProjectAdd To Project/Files添加。
位图要用CBitmap对象来保存,由成员函数LoadBitmap来加载,在显示时需先绘制到内存DC中,然后再用BitBlt函数把它由内存DC复制到显示设备的DC上。MFC的文件处理机制
文件是存储在永久性存储介质上的数据的集合。在面向对象的应用程序中也涉及对象存盘的问题。对象存盘使用序列化的机制实现。
序列化就是把对象的当前状态以文件的形式写入永久性存储体中,在需要的时候从文件中读取它,并在应用程序中重建对象的过程。使用序列化机制把对象存盘称为对象的永久化,这样的对象称为永久性对象。
MFC通过宏DECLARE_SERIAL和IMPLEMENT_SERIAL给类添加动态重建对象和序列化操作的代码。宏DECLARE_SERIAL用在类声明中,宏IMPLEMENT_SERIAL用在类实现中。同时,该类必须从CObject类或其派生类派生,并重载Serialize函数。Serialize函数借助类CArchive对象实现对象的序列化。CArchive对象是一种I/O,它借助CFile对象完成磁盘文件数据的存取操作。MFC把文件的打开,关闭,读写操作封装在类CFile中。CFile对象代表一个磁盘文件,使用CFile对象可以直接对文件进行操作。控件
控件是应用程序窗口的子窗口。MFC的控件类封装了Windows的标准控件和通用控件,这些控件类都派生于类CWnd。
静态文本控件由类CStatic封装,按钮控件由类CButton封装,编辑控件由类CEdit封装,进度条控件由类CProgessCtrl封装,微调器控件由类CSpinButtonCtrl封装,图象列表控件由类CImageList封装,列表视图控件由类CListCtrl封装。控件类的使用与窗口类CWnd的使用基本相同。
控件自己有特有的行为特点,在各自的类中由相应的成员函数实现。
控件颜色的设置在Windows消息WM_CTLCOLOR的消息响应函数OnCtlColor中完成。其消息映射宏是ON_WM_CTLCOLOR()。
11对话框
对话框是Windows应用程序与用户交互的重要手段,分为模态对话框和非模态
对话框。对话框的基本行为由类CDialog封装,对话框的外观由模版资源定义。对话框模版资源可以使用Visual C++的资源编辑器来创建和编辑。
掌握了对话框模版资源描述文件,对话框的定义及使用,对话框的数据交换和检验,对话框的应用程序,通用对话框,非模态对话框,属性页方面的知识。12 进程与线程的管理
进程是一个正在运行的应用程序的实例,拥有应用程序的所有资源,进程由一个或多个线程组成。线程是进程中一个独立的执行路径。Windows按照一定的规则,如优先级和先后次序,给线程分配CPU时间。
还掌握了工作线程和用户界面线程,线程同步,线程通信。动态链接库
动态链接库(DLL)是程序运行时装载和连接的一种二进制文件,主要是通过它的各种导出函数,类和资源来向外界提供服务并允许同时被多个不同的进程所共享。
DLLMain是Windows的动态链接库的入口函数,主要作用是调用动态链接库时,完成初始化工作。
声明为导出函数有两种方法:在.def文件中用函数的名称来声明;使用关键字_declspec(dllexport)来声明。
在VisualC++中,动态链接库分为非MFC DLL,常规型DLL和扩展型DLL三种。创建第一种动态链接库使用向导Win32 Dynamic-Link Library,创建第二和第三种使用MFC AppWizard(dll)。
动态链接库的导出函数被其他程序模块调用,在这些程序模块中称之为导入函数。应用程序使用DLL文件中的导出函数有两种方式:隐式链接和显式链接。14 组件对象模型基础
掌握了组件对象模型(COM)概述;使用DOM组件;组件的包含和聚合;进程外组件;使用ATL设计COM组件。
15用MFC开发ActiveX应用
掌握了ActiveX技术的基本概念;ActiveX容器;ActiveX服务器;自动化;ActiveX控件与ActiveX文档的有关知识。
ActiveX是一种为了适应互联网需要而发展起来的基于COM的技术。16 用MFC设计数据库应用程序
数据库系统一般由数据库,数据库管理系统和数据库应用系统构成。数据库是存放数据的仓库。为使一个数据库应用系统适用于所有的数据库管理系统,人们在数据库应用系统和数据库管理系统之间增加一个公认的标准接口。ODBC和DAO是两个常用的标准接口。
MFC有两组数据库类:一组是基于ODBC的,一组是基于DAO的。
【mfc通讯录管理系统】推荐阅读:
通讯管理06-11
即时通讯系统集成06-19
通讯安全管理制度07-01
邮政通讯业务管理10-02
通讯费用管理制度02-08
网络通讯管理制度12-28
矿井通讯系统管理制度12-17
公司通讯员管理办法07-03
a320通讯系统总结11-24
×公司管理人员通讯费用暂行规定02-01