C课程设计MFC

上传人:鲁** 文档编号:589906760 上传时间:2024-09-12 格式:PPT 页数:148 大小:5.42MB
返回 下载 相关 举报
C课程设计MFC_第1页
第1页 / 共148页
C课程设计MFC_第2页
第2页 / 共148页
C课程设计MFC_第3页
第3页 / 共148页
C课程设计MFC_第4页
第4页 / 共148页
C课程设计MFC_第5页
第5页 / 共148页
点击查看更多>>
资源描述

《C课程设计MFC》由会员分享,可在线阅读,更多相关《C课程设计MFC(148页珍藏版)》请在金锄头文库上搜索。

1、C+课程设计课程设计内容及要求内容及要求1/64主要内容主要内容1.1.课程设计基本要求课程设计基本要求2.2.Windows Windows 编程基础编程基础3.3.什么是什么是C+C+的的MFCMFC4.4.什么是什么是MFCMFC编程编程5.5.MFCMFC应用程序的开发流程应用程序的开发流程6.单文档【ClassView】面板7.7.登录对话框与单文档视图联接登录对话框与单文档视图联接8.8.单文档中菜单项与对话框联接单文档中菜单项与对话框联接9.9.实例介绍实例介绍2一、课程设计基本要求一、课程设计基本要求自学自学MFC(2MFC(2学时学时) )知识扩充知识扩充C+C+:了解并掌握

2、:了解并掌握MFCMFC程序结构、消息映射机制、程序结构、消息映射机制、MFCMFC类库中的类库中的常用类(对话框、各种常用控件)。常用类(对话框、各种常用控件)。软件开发的基本知识软件开发的基本知识结合设计任务清楚软件开发的基本流程、各个阶段的目标和主结合设计任务清楚软件开发的基本流程、各个阶段的目标和主要工作。要工作。上机调试程序(上机调试程序(3030学时)学时)其他(其他(1414学时)学时)程序调试的基本方法和论文撰写要求(程序调试的基本方法和论文撰写要求(2 2学时)学时)掌握调试程序的方法与技巧。掌握调试程序的方法与技巧。清楚论文组织结构、格式编排等相关知识清楚论文组织结构、格式

3、编排等相关知识学生资料查阅与自主学习(学生资料查阅与自主学习(2 2学时)学时)代码编写(代码编写(1010学时)学时)3二、二、Windows 编程基础编程基础Windows Windows 编程编程就是基于就是基于Windows Windows 的应用程序。的应用程序。2 2种重要的种重要的WindowsWindows应用程序应用程序基于基于对话框对话框的应用程序的应用程序基于基于文档文档/ /视图视图结构的应用程序结构的应用程序主要特点主要特点具有标准的图形用户界面具有标准的图形用户界面具有与硬件无关的特性具有与硬件无关的特性采用采用“消息传递,事件驱动消息传递,事件驱动”的运行机制,即

4、根据的运行机制,即根据WindowsWindows发发送的消息来处理用户的输入送的消息来处理用户的输入编写编写WindowsWindows应用程序的主要方法(应用程序的主要方法(2 2种)种)使用使用WindowsWindows提供的应用程序提供的应用程序接口(接口(APIAPI)函数)函数使用使用MicrosoftMicrosoft提供的微软提供的微软基础类基础类(MFC)(MFC)4三、什么是三、什么是C+的的MFCMFC(MicrosoftMFC(Microsoft Foundation Class Library Foundation Class Library,基础类库,基础类库)

5、) 是微软提供的用来编写是微软提供的用来编写WindowsWindows应用程序的应用程序的C+C+类库类库;封装了封装了APIAPI(WindowsWindows的接口函数)的接口函数), ,是是Win APIWin API与与C+C+的结合。的结合。MFCMFC大约有大约有200200多个类,封装了多个类,封装了WindowsWindows的大部分编程对象以及与它的大部分编程对象以及与它们有关的操作。即它由几百个执行文件和源代码文件组成。们有关的操作。即它由几百个执行文件和源代码文件组成。 注意注意C+C+和和VC+VC+的区别的区别C+C+是是一种程序设计语言一种程序设计语言, ,是一种

6、大家都承认的软件编制的通用规是一种大家都承认的软件编制的通用规范,即范,即C+C+是一套语法规则的名字,类似汉语,英语。是一套语法规则的名字,类似汉语,英语。 VC+VC+是一个软件是一个软件IDEIDE(编译、编辑、调试编译、编辑、调试 )集成开发环境)集成开发环境 MFC MFC是一个非外挂式的是一个非外挂式的软件包软件包, ,类库类库, MFC, MFC类是微软为类是微软为VC+VC+专配的。专配的。5四、什么是四、什么是MFC编程编程MFCMFC编程编程指的就是使用指的就是使用VC+VC+进行开发,并且是在使用进行开发,并且是在使用VC+VC+提供提供的各种向导的情况下的的各种向导的情

7、况下的MFCMFC编程。编程。在在VC+VC+中可以创建中可以创建3 3类类典型的典型的WindowsWindows应用程序应用程序基于对话框的应用程序基于对话框的应用程序单文档界面(单文档界面(SDISDI)应用程序)应用程序多文档界面(多文档界面(MDIMDI)应用程序)应用程序文档文档/视图视图u文档对象:文档对象:u用来保存数据。用来保存数据。u视图对象:视图对象:u用来显示和编辑数用来显示和编辑数据。据。 6五、五、MFC应用程序的开发流程应用程序的开发流程应用程序编程的基本步骤:应用程序编程的基本步骤:(1 1)根据应用程序的特性在)根据应用程序的特性在MFC MFC AppWiz

8、ardexeAppWizardexe 应用程应用程序中序中选择合适的应用程序框架选择合适的应用程序框架。(2 2)利用)利用资源编辑器编辑资源资源编辑器编辑资源,如菜单等。,如菜单等。(3 3)利用类向导()利用类向导(ClassWizardClassWizard)或手工)或手工添加类添加类、成员成员变量、成员函数变量、成员函数声明。声明。(4 4)编写具体的)编写具体的成员函数代码成员函数代码。(5 5)编译、链接程序)编译、链接程序检查程序中是否存在语法错误。检查程序中是否存在语法错误。(6 6)调试应用程序。)调试应用程序。7六、单文档【ClassView】面板CAboutDlgCAbo

9、utDlg( (关于对话框类关于对话框类) )管理关于对话框。管理关于对话框。CFrameWndCFrameWnd( 框架窗口类)框架窗口类)CWxling_27AppCWxling_27App(应用程序类)(应用程序类)用来处理消息。用来处理消息。CWxling_27Doc CWxling_27Doc (文档类)(文档类)MFCMFC中的数据是存储在类文档中。中的数据是存储在类文档中。文档类负责管理和维护数据本身。文档类负责管理和维护数据本身。CWxling_27ViewCWxling_27View(视图类)(视图类)结果的显示是在视图类中。结果的显示是在视图类中。视图类负责处理用户鼠标和键

10、盘的操作。视图类负责处理用户鼠标和键盘的操作。8七、登录对话框与单文档视图联接七、登录对话框与单文档视图联接1.1.新建单文档工程:新建单文档工程:TEXTTEXT(注意此名由设计者自己任取);(注意此名由设计者自己任取);2.2.在在ResourceViewResourceView, 单击单击Insert DialogInsert Dialog,插入一对话框,插入一对话框IDD_DIALOG1IDD_DIALOG1(默认(默认IDID号);号);3.3.右键选中新建的对话框,利用类向导建立一个新类右键选中新建的对话框,利用类向导建立一个新类Create a new classCreate a

11、 new class,名称为:名称为:C Cdlg_logindlg_login ;4.4.在在MainFrm.cppMainFrm.cpp文件的前面,语句文件的前面,语句#include “#include “MainFrm.hMainFrm.h”的后面的后面添加新类添加新类的头文件:的头文件:#include #include dlg_login.hdlg_login.h 5.5.在在FileViewFileView中点击中点击source filessource files,双击,双击MainFrm.cppMainFrm.cpp。找到:。找到:CMainFrame:OnCreate(LP

12、CREATESTRUCTCMainFrame:OnCreate(LPCREATESTRUCT lpCreateStructlpCreateStruct) ),这是窗体框架创建函数。在该函数的后面(在这是窗体框架创建函数。在该函数的后面(在return 0 ;return 0 ;的前面)加入语句(注意大的前面)加入语句(注意大小写):小写):Cdlg_loginCdlg_login dlgdlg; ; / /定义一个登录对话框对象定义一个登录对话框对象dlgdlgdlg.DoModaldlg.DoModal();(); / /让对话框对象以有模式形式显示出来让对话框对象以有模式形式显示出来6.6

13、.此时对话框与单文档联接完成。此时对话框与单文档联接完成。7.7.下载下载“格式工厂格式工厂3.011”3.011”将自己的照片转换成将自己的照片转换成BMPBMP格式,通过插入格式,通过插入BitmapBitmap命命令,将照片引入至资源中,并添加至对话框中。令,将照片引入至资源中,并添加至对话框中。9七续、登录对话框退出按钮代码七续、登录对话框退出按钮代码/确定按钮确定按钮void void CDlg_login:OnOKCDlg_login:OnOK() () / TODO: Add extra validation / TODO: Add extra validation herehe

14、rethis-this-UpdateData(trueUpdateData(true););if(thisif(this-m_namem_name=wxlwxl & & this-this-m_pawm_paw=1234)=1234)CDialog:OnOKCDialog:OnOK();();elseelse MessageBoxMessageBox(登录有误登录有误););ExitProcess(0); /ExitProcess(0); /退出退出 /CDialog:OnOKCDialog:OnOK();(); /取消按钮取消按钮void void CDlg_login:OnCancelCD

15、lg_login:OnCancel() () / TODO: Add extra cleanup / TODO: Add extra cleanup herehereExitProcess(0); ExitProcess(0); /退出退出 10八、单文档中菜单项与对话框联接八、单文档中菜单项与对话框联接1.1.新建单文档工程:新建单文档工程:Ys1Ys1(注意此名由设计者自己任取);(注意此名由设计者自己任取);2.2.在在ResourceViewResourceView, 单击单击Insert DialogInsert Dialog,插入一对话框,插入一对话框IDD_DIALOG1IDD_

16、DIALOG1(默认(默认IDID号);号);3.3.右键选中新建的对话框,利用类向导建立一个新类右键选中新建的对话框,利用类向导建立一个新类Create a new classCreate a new class,名称为:,名称为:C Cdlg_jcdlg_jc( (自己命名自己命名) ) ,如右图,如右图1 1所示所示;4.4.在在/ Ys1View.cpp :/ Ys1View.cpp :文件中语句文件中语句#include Ys1View.h#include Ys1View.h的后面的后面添加新类的头文件:添加新类的头文件:#include #include dlg_jc.hdlg_j

17、c.h 5.5.编辑主菜单如图编辑主菜单如图2 2所示:所示:6.6.在主菜下通过在主菜下通过“建立类向导建立类向导”命令,命令,从从“Class name”Class name”组合框中选择组合框中选择CYs1ViewCYs1View, ,如如图图3,43,4所示,并在函数所示,并在函数OnJcOnJc()()编写代码如下:编写代码如下:void CYs1View:OnJc() void CYs1View:OnJc() / TODO: Add your command handler code here/ TODO: Add your command handler code here C

18、Cdlg_jcdlg_jc jcjc; ; /定义一个求阶层对话框对象定义一个求阶层对话框对象jcjcjc.DoModaljc.DoModal();(); /让对话框对象以有模式形式显示出来让对话框对象以有模式形式显示出来 7.7.此时单文档菜单项与对话框联接完成。此时单文档菜单项与对话框联接完成。111.求阶层按钮的代码求阶层按钮的代码使用使用MFCMFC进行程序设计时进行程序设计时, ,如输出结果是如输出结果是单值单值, ,可用以下代码作为模板可用以下代码作为模板: :void void Cdlg_jc:OnOKCdlg_jc:OnOK() () / TODO: Add extra val

19、idation here/ TODO: Add extra validation hereUpdateData(TRUEUpdateData(TRUE); ); /更新控件值更新控件值 double double i,jszi,jsz=1.0;=1.0;for(ifor(i=1;i=1;i=m_srs;im_srs;i+)+)jszjsz*=i; *=i; /求阶乘求阶乘 m_jsz.Formatm_jsz.Format ( %f , ( %f ,jszjsz);); /将双精度型转换为字符,将双精度型转换为字符,f f 对应浮点数对应浮点数/其中其中m_jszm_jsz为输出编辑框的成员变量

20、名为输出编辑框的成员变量名UpdateData(FALSEUpdateData(FALSE); ); /控件值更新编辑框显示控件值更新编辑框显示/CDialog:OnOKCDialog:OnOK();(); 12/续上续上for(ifor(i= =a;ia;i=b;ib;i+)+) for(jfor(j=2;j=2;j-TextOut(x,y,sTextOut(x,y,s); ); /在指定位置输出文本在指定位置输出文本 else else pDCpDC-TextOut(x,y,sTextOut(x,y,s); ); /在指定位置输出文本在指定位置输出文本x=x+30; x=x+30; 2.求

21、素数按钮的代码求素数按钮的代码void void Cdlg_zss:OnOKCdlg_zss:OnOK() () / TODO: Add extra validation here/ TODO: Add extra validation hereUpdateData(TRUEUpdateData(TRUE); ); /更新控件更新控件值值 CDC *CDC *pDCpDC= =GetDCGetDC();();/获取视图初始的客户区获取视图初始的客户区DCDC/DC/DC表示设备环境表示设备环境intint a= a=m_szqzm_szqz; ;intint b= b=m_szzzm_szzz

22、; ;intint i,j,ni,j,n=0;=0;intint x=70,y=220; x=70,y=220;CStringCString s; s;if(bif(b=100) MoveTo(100,100);-MoveTo(100,100);pDCpDC-LineTo(300,500);-LineTo(300,500); 154.单文档菜单项中画矩形代码单文档菜单项中画矩形代码菜单项菜单项“画矩形画矩形”按钮代码:按钮代码:void CWxling_28View:OnHjx() void CWxling_28View:OnHjx() / TODO: Add your command han

23、dler code here/ TODO: Add your command handler code hereCClientDCCClientDC dc(thisdc(this););CPenCPen pen; pen; /定义画笔定义画笔/创建红色创建红色3 3号粗细实线画笔号粗细实线画笔pen.CreatePen(PS_SOLID,3,RGB(pen.CreatePen(PS_SOLID,3,RGB(255255,0,0);,0,0);CPenCPen * *oldpenoldpen= =dc.SelectObject(&pendc.SelectObject(&pen););CBrush

24、CBrush brush; brush; /定义画刷定义画刷/创建绿色画刷创建绿色画刷brush.CreateHatchBrush(HS_CROSS,RGB(0,brush.CreateHatchBrush(HS_CROSS,RGB(0,255255,0);,0);dc.SelectObject(&brushdc.SelectObject(&brush););dc.Rectangle(dc.Rectangle(300,300,400,500300,300,400,500); ); /画矩形画矩形 165.单文档菜单项中画椭圆代码单文档菜单项中画椭圆代码菜单项菜单项“画椭圆画椭圆”按钮代码:按钮

25、代码:void CWxling_28View:OnHty() void CWxling_28View:OnHty() / TODO: Add your command handler code here/ TODO: Add your command handler code hereCClientDCCClientDC dc(thisdc(this););CPenCPen pen; pen; /设置画笔设置画笔pen.CreatePen(PS_SOLID,3,RGB(0,255,0);pen.CreatePen(PS_SOLID,3,RGB(0,255,0);CPenCPen * *oldp

26、enoldpen= =dc.SelectObject(&pendc.SelectObject(&pen););dc.Ellipse(300,100,600,300); dc.Ellipse(300,100,600,300); /画椭圆画椭圆 /*(/*(intint x1,int y1,int x2,int y2) x1,int y1,int x2,int y2)(x1,y1)(x1,y1)和和(x2,y2)(x2,y2)表示所画椭圆外切矩形的左上角和右下角坐标表示所画椭圆外切矩形的左上角和右下角坐标* */ /176.单文档菜单项中画单文档菜单项中画sin曲线代码曲线代码在在/ / Wxl_

27、30View. Wxl_30View. cppcpp中加入头文件:中加入头文件: #include #include math.hmath.h“菜单项菜单项“画画sinsin曲线曲线”按钮代码:按钮代码:void CWxl_30View:OnSin() void CWxl_30View:OnSin() / TODO: Add your command handler code here/ TODO: Add your command handler code hereCClientDCCClientDC dc(thisdc(this););CRectCRect rectrect; ; /定义矩

28、形对象定义矩形对象GetClientRect(rectGetClientRect(rect););intint x0=rect.Width()/2; x0=rect.Width()/2;intint y0=rect.Height()/2; y0=rect.Height()/2;dc.MoveTo(20,y0);dc.MoveTo(20,y0);dc.LineTo(rect.Width()-20,y0);dc.LineTo(rect.Width()-20,y0);dc.MoveTo(x0,20);dc.MoveTo(x0,20);dc.LineTo(x0,rect.Height()-20);dc

29、.LineTo(x0,rect.Height()-20);double double setpsetp=3.14159/100;=3.14159/100;for(intfor(int i=-200;i200;i+) i=-200;imessage = WM_KEYDOWN) -message = WM_KEYDOWN) /键盘消息键盘消息 if(pMsgif(pMsg - - wParamwParam = VK_ESCAPE) = VK_ESCAPE) /键盘上的键盘上的EscEsc键键return TRUE;return TRUE; if(pMsgif(pMsg - - wParamwPar

30、am = VK_RETURN) = VK_RETURN) /键盘上的回车键键盘上的回车键return TRUE;return TRUE; return return CDialog:PreTranslateMessage(pMsgCDialog:PreTranslateMessage(pMsg);); 228.常见问题解决方法常见问题解决方法1.1.建好建好MFCMFC之后之后( (基于对话框的基于对话框的) ),然后点击,然后点击Insert-New ClassInsert-New Class2.2.弹出对话框之后,弹出对话框之后,Class Class Type:MFCType:MFC C

31、lass Class3.3.在在Base Base Class:CRecordsetClass:CRecordset类,点击类,点击OkOk的时候,会弹出要你添加数据库的的时候,会弹出要你添加数据库的对话框你就可以添加了。对话框你就可以添加了。 (9 9)如何为)如何为MFC MFC 应用程序添加应用程序添加ODBC ODBC 功能?功能? (1 1)在文件)在文件Stdafx.hStdafx.h 文件末尾添加下面一行:文件末尾添加下面一行: #include#include / MFC ODBC database classes / MFC ODBC database classes (2

32、2)在文本模式下编辑)在文本模式下编辑RC RC 文件(利用文件(利用File-Open As text File-Open As text 方式)方式) 在下面的程序行(共有两处)在下面的程序行(共有两处) #include #include l.chsafxprint.rcl.chsafxprint.rc / printing/print preview / printing/print preview resources resources 添加下一行:添加下一行: #include #include l.chsafxdb.rcl.chsafxdb.rc / Database resou

33、rces / Database resources 239.特殊效果特殊效果(1 1)如何给)如何给MFCMFC单文档添加背景单文档添加背景?为为CTestViewCTestView类添加一个变量类添加一个变量CBrush m_brushBackground; /CBrush m_brushBackground; /定义定义画刷用于画背景画刷用于画背景在在CTestViewCTestView的构造函数中加入如下代码的构造函数中加入如下代码CBitmapCBitmap bmp; bmp;bmp.LoadBitmap(IDB_BITMAP1); /bmp.LoadBitmap(IDB_BITMAP

34、1); /加载位图加载位图m_brushBackground.CreatePatternBrush(&bmpm_brushBackground.CreatePatternBrush(&bmp); /); /创建位图画刷创建位图画刷在在OnDrawOnDraw函数中画出来代码如下函数中画出来代码如下CRectCRect rectrect; ;GetClientRect(rectGetClientRect(rect); /); /取得客户区域取得客户区域pDCpDC-FillRect(rect,&m_brushBackgroundFillRect(rect,&m_brushBackground);

35、 /); /用背景画刷填充区域用背景画刷填充区域为了避免背景的闪烁,使显示更完美,添加为了避免背景的闪烁,使显示更完美,添加WM_ERASEBKGNDWM_ERASEBKGND消息的处理函数,并取消息的处理函数,并取消调用父类的处理函数,代码如下消调用父类的处理函数,代码如下BOOL BOOL CTestView:OnEraseBkgnd(CDCCTestView:OnEraseBkgnd(CDC* * pDCpDC) ) return TRUE; return TRUE; 编译运行该程序!编译运行该程序!249.特殊效果特殊效果(2 2)在工程调用其他可执行的文件()在工程调用其他可执行的文

36、件(.EXE).EXE)在在w1View.cpp :w1View.cpp :中加入头文件:中加入头文件:#include #include windows.hwindows.h 在编辑好的菜单项中编写代码如下在编辑好的菜单项中编写代码如下void CW1View:OnWord() void CW1View:OnWord() / TODO: Add your command handler code here/ TODO: Add your command handler code hereWinExec(CLOCKYS.exe,NULLWinExec(CLOCKYS.exe,NULL););

37、/调用可执行文件调用可执行文件 注意:将可执行文件拷贝至本工程所在的文件夹下,否则要获取文注意:将可执行文件拷贝至本工程所在的文件夹下,否则要获取文件的路径。若要打开其他类型的文件,见本片的下面的备注。件的路径。若要打开其他类型的文件,见本片的下面的备注。259.特殊效果特殊效果(3 3)在工程调用其他任意文件菜单项按钮代码)在工程调用其他任意文件菜单项按钮代码void CW12View:OnYy() void CW12View:OnYy() / TODO: Add your command handler code here/ TODO: Add your command handler c

38、ode hereCStringCString path; path; /返回文件所在的路径,含该文件名返回文件所在的路径,含该文件名GetModuleFileNameGetModuleFileName( (NULL, NULL, /要获取文件名的模块句柄(要获取文件名的模块句柄(见备注见备注),),nullnull表示当前模块表示当前模块 path.GetBufferSetLength(MAX_PATH+1), path.GetBufferSetLength(MAX_PATH+1), /存放取得的文件名存放取得的文件名MAX_PATH MAX_PATH /存放取得的文件名参数的长度存放取得的文

39、件名参数的长度); ); path.ReleaseBufferpath.ReleaseBuffer(); (); /字符串的缓冲区长度锁定解除字符串的缓冲区长度锁定解除 intint pos = pos = path.ReverseFindpath.ReverseFind(); (); /从后向前查找从后向前查找 path = path = path.Left(pospath.Left(pos) )path = path = path.Left(pospath.Left(pos); ); /取左取左, ,参数为字符串的个数参数为字符串的个数/MessageBox(pathMessageBox(

40、path); ); /调试程序时用来显示查找到的当前运行程序所在目录调试程序时用来显示查找到的当前运行程序所在目录 ShellExecute(NULL,open,pathShellExecute(NULL,open,path+2013+2013年年C+C+课程设计任务书课程设计任务书wxl.docwxl.doc,NULL,NULL, SW_SHOWNORMAL);NULL,NULL, SW_SHOWNORMAL); 269.特殊效果特殊效果(4 4)仅修改工程中某个对话框的图标)仅修改工程中某个对话框的图标对对应的对话框添加初始化函数对对应的对话框添加初始化函数OnInitDialogOnIn

41、itDialog()(), ,并添加以下代码:并添加以下代码:BOOL BOOL Cdlg_login:OnInitDialogCdlg_login:OnInitDialog() () CDialog:OnInitDialogCDialog:OnInitDialog();();/ TODO: Add extra initialization here/ TODO: Add extra initialization hereHICON HICON m_hIconm_hIcon; ;/IDR_ICON1/IDR_ICON1为图标资源名为图标资源名 m_hIconm_hIcon = = AfxGet

42、AppAfxGetApp()-LoadIcon(IDI_ICON1);()-LoadIcon(IDI_ICON1);SetIcon(m_hIconSetIcon(m_hIcon, TRUE); , TRUE); / Set big icon/ Set big iconSetIcon(m_hIconSetIcon(m_hIcon, FALSE); , FALSE); / Set small icon/ Set small iconreturn TRUE; return TRUE; / return TRUE unless you set the focus to a control/ retur

43、n TRUE unless you set the focus to a control/ EXCEPTION: OCX Property Pages should return FALSE/ EXCEPTION: OCX Property Pages should return FALSE279.特殊效果特殊效果如何去掉单文档界面中主框架的如何去掉单文档界面中主框架的“无标题无标题”? ?修改修改IDR_MAINFRAMEIDR_MAINFRAME字符串资源中字符串资源中第第2 2个参数个参数( (共有共有7 7个个参数参数) ),分别以,分别以nn结束,即如下格式:结束,即如下格式:nnn

44、filtennnnnnnnnnypeNamen例例, ,将主框架标题改为将主框架标题改为”我的应用程序我的应用程序”28在程序中使用对话框 (4) 用鼠标将新添加的菜单项拖到“查看”和“帮助”菜单项 之间,结果如图所示。 菜单项“对话框”拖放后的位置(5) 选择“查看”“建立类向导”菜单命令或直接按Ctrl+W快捷键,则出现MFC ClassWizard对话框,该对话框会自动切换到Message Maps页面。(6) 从“Class name”组合框中选择CMainFrame,在Object Ids列表中选择ID_TEST_DLG,然后在Messages框中选择COMMAND消息。 29在程序

45、中使用对话框 (7) 单击Add Function按钮或双击COMMAND消息,出现“Add Member Function”对话框以输入成员函数的名称。系统默认的函数名为OnTestDlg,如图所示。该函数是对菜单项ID_TEST_DLG的映射,也就是说,当在应用程序运行时,用户选择“对话框”,则该函数OnTestDlg被调用,执行函数中的代码。 30在程序中使用对话框(8) 单击OK按钮,在ClassWizard的“Member functions”列(9)表中将列出新增加的成员函数。选择此函数,单击Edit Co(10)de按钮(或直接在函数名双击鼠标),在此成员函数中添加下(11)列代

46、码:void CMainFrame:OnTestDlg() CFirstDlg dlg;/ 定义对话框类对象 dlg.DoModal();/ 显示对话框 代码中,DoModal是CDialog基类成员函数,它是用来显示和终止模式对话框。31在程序中使用对话框(9) 在OnTestDlg函数的实现文件MainFrm.cpp的前面添加CFirstDlg类的头文件包含,即:#include Ex_SDI.h#include MainFrm.h#include FirstDlg.h“(10) 编译并运行。在应用程序菜单上,选择“测试” “对话框”菜单项,将出现如图的对话框,这个对话框就是刚才添加的对话

47、框。 32几种常见的几何图形绘制。几种常见的几何图形绘制。利用利用MFC AppWizardMFC AppWizard建立一个建立一个SDISDI应用程序,在应用程序,在OnDrawOnDraw()()函数中添加如下程序代码:函数中添加如下程序代码: void void CMyGraphView:OnDraw(CDCCMyGraphView:OnDraw(CDC* * pDCpDC) ) CTexthtDocCTexthtDoc* * pDocpDoc = = GetDocumentGetDocument();();ASSERT_VALID(pDocASSERT_VALID(pDoc););/

48、 TODO: add draw code for native data here/ TODO: add draw code for native data here for(intfor(int xPosxPos=20;xPos100;xPos+=10)=20;xPosSetPixel(xPos,30,RGB(0,0,0); / -SetPixel(xPos,30,RGB(0,0,0); / 绘制像素点绘制像素点 POINT polylpt5=10,100,50,60,120,80,80,150,30,130;POINT polylpt5=10,100,50,60,120,80,80,150

49、,30,130; pDCpDC-Polyline(polylpt,5); / -Polyline(polylpt,5); / 绘制绘制4 4条折线条折线 POINT polybpt4=150,160,220,60,300,180, 330,20;POINT polybpt4=150,160,220,60,300,180, 330,20; pDCpDC-PolyBezier(polybpt,4); / -PolyBezier(polybpt,4); / 绘制贝塞尔曲线绘制贝塞尔曲线 CBrushCBrush * *pBrhOldpBrhOld; ; pBrhOldpBrhOld=(=(CBrus

50、hCBrush*)*)pDCpDC-SelectStockObjectSelectStockObject( LTGRAY_BRUSH); / ( LTGRAY_BRUSH); / 使用浅灰色堆使用浅灰色堆画刷画刷 pDCpDC-RoundRect(400,30,550,100,20,20); / -RoundRect(400,30,550,100,20,20); / 绘制圆角矩形绘制圆角矩形 pDCpDC-Arc(20,200,200,300,200,250,20,200); / -Arc(20,200,200,300,200,250,20,200); / 绘制椭圆弧绘制椭圆弧 pDCpDC-

51、Pie(220,200,400,380,380,270,240,220); / -Pie(220,200,400,380,380,270,240,220); / 绘制扇形绘制扇形 pDCpDC-Chord(420,120,540,240,520,160,420,180); / -Chord(420,120,540,240,520,160,420,180); / 绘制弦形绘制弦形 POINT polygpt5=450,200,530,220,560,300,480,320,430,280;POINT polygpt5=450,200,530,220,560,300,480,320,430,280

52、; pDCpDC-Polygon(polygpt,5); / -Polygon(polygpt,5); / 绘制五边形绘制五边形 pDCpDC-SelectObject(pBrhOldSelectObject(pBrhOld); / ); / 恢复系统默认的画刷恢复系统默认的画刷 33绘制效果绘制效果34九、实例介绍九、实例介绍实例实例1 1静态控件的使用静态控件的使用实例实例2 2编辑框应用编辑框应用实例实例3 3单选钮应用程序单选钮应用程序实例实例4 4简易时钟应用程序简易时钟应用程序实例实例5 5计算器应用程序计算器应用程序实例实例6 6调用自定义对话框调用自定义对话框实例实例7 7数据

53、库编程实例数据库编程实例返回返回目录目录35/64实例实例1静态控件的使用静态控件的使用创建步骤:创建步骤:1.1.建立建立基于对话框基于对话框的的MFCMFC应用程序框架;应用程序框架;2.2.设置对话设置对话放置控件;放置控件;在菜单或工具栏的空白处,单击右键,弹出控件在菜单或工具栏的空白处,单击右键,弹出控件工具栏,再选择所需控件;工具栏,再选择所需控件;设置控件属性;设置控件属性;3.3.调试程序调试程序36步骤步骤1:建立:建立基于对话框基于对话框应用程序框架应用程序框架(1 1)创建工程:)创建工程:TEST1TEST137步骤步骤2、3:放置控件;调试程序:放置控件;调试程序(1

54、 1)删除现有控件)删除现有控件(2 2)设置对话框标题)设置对话框标题利用利用“属性属性”设置设置(3 3)添加组框)添加组框设置属性设置属性(4 4)添加静态文本框)添加静态文本框设置属性设置属性(5 5)添加图片)添加图片单击单击“插入插入/ /资源资源”命令,通过命令,通过菜单菜单引入:引入:(位图(位图(BMPBMP或或DIBDIB)、)、图标(图标(IconIcon)、图元文件)、图元文件(wMFwMF )图片控件图片控件属性属性对对话框中的类对对话框中的类型、图像进行设置型、图像进行设置控件属性控件属性控件控件IDID号号标题标题作用作用对话框对话框默认默认静态控件使静态控件使用

55、用用户视图用户视图组框组框默认默认示例示例将一组相关控件将一组相关控件框起来框起来图片图片默认默认点缀点缀静态文静态文本本默认默认同学们好!同学们好!显示文本信息显示文本信息返回返回实例实例38特殊效果特殊效果对话框中设置静态文本框字体及颜色对话框中设置静态文本框字体及颜色操作步骤:操作步骤:1. 1. 添加添加对话框类对话框类声明中字体和颜色变量声明中字体和颜色变量 class CDHK2013Dlg : public class CDHK2013Dlg : public CDialogCDialog / Construction/ Constructionpublic:public:CFo

56、ntCFont m_myFontm_myFont; ; / / 字体对象字体对象 COLORREF COLORREF m_myColorm_myColor; ; / / 颜色对象颜色对象.2. 2. 在在对话框初始化函数对话框初始化函数OnInitDialogOnInitDialog()()中对字体和颜色进行初始化中对字体和颜色进行初始化m_myFont.CreatePointFont(m_myFont.CreatePointFont(150150, _T(“, _T(“华文彩云华文彩云”); ); /150/150是字体大小是字体大小m_myColorm_myColor = RGB(255,

57、 0, 255); = RGB(255, 0, 255);39续上:续上:3. 3. 为为对话框类对话框类添加添加WM_CTLCOLORWM_CTLCOLOR消息响应函数,并在其消息响应函数消息响应函数,并在其消息响应函数OnCtlColorOnCtlColor()()中添加中添加代码代码/ / 消息响应函数实现消息响应函数实现 HBRUSH CDHK2013Dlg:OnCtlColor( CDC* HBRUSH CDHK2013Dlg:OnCtlColor( CDC* pDCpDC, , CWndCWnd* * pWndpWnd, UINT , UINT nCtlColornCtlColor

58、 ) ) HBRUSH HBRUSH hbrhbr = = CDialog:OnCtlColor(pDCCDialog:OnCtlColor(pDC, , pWndpWnd, , nCtlColornCtlColor); ); / TODO: Change any attributes of the DC here (/ TODO: Change any attributes of the DC here (在此更改在此更改 DC DC 的任何属性的任何属性) ) if(pWndif(pWnd-GetDlgCtrlIDGetDlgCtrlID()=IDC_STATIC_1) ()=IDC_ST

59、ATIC_1) pDCpDC-SelectObject(&m_myFontSelectObject(&m_myFont); ); / / 设置字体设置字体 pDCpDC-SetTextColor(m_myColorSetTextColor(m_myColor); ); / / 设置颜色设置颜色 / TODO: Return a different brush if the default is not desired/ TODO: Return a different brush if the default is not desired(如果默认的不是所需画笔,(如果默认的不是所需画笔,则返

60、回另一个画笔则返回另一个画笔 )return return hbrhbr; ; 40实例实例2编辑框应用编辑框应用创建步骤:创建步骤:1.1.建立建立基于对话框基于对话框的的MFCMFC应用程序应用程序框架;框架;2.2.设置对话设置对话放置控件;放置控件;设置控件属性;设置控件属性;3.3.为控件连接变量,即为控件命为控件连接变量,即为控件命名;名;4.4.添加并且编写消息处理函数;添加并且编写消息处理函数;5.5.调试程序。调试程序。41步骤步骤1,2:建立框架、添加控件:建立框架、添加控件控件属性控件属性控件控件IDID号号标题标题变量类型变量类型连接变量连接变量范围范围 特别属性特别属

61、性对话框对话框默认默认编辑框应用编辑框应用组框组框默认默认成绩计算成绩计算静态文本框静态文本框默认默认数学数学静态文本框静态文本框默认默认语文语文静态文本框静态文本框默认默认英语英语静态文本框静态文本框默认默认平均分平均分 扩展样式扩展样式静态文本框静态文本框IDC_AVERAGEIDC_AVERAGECstringCstringm_avgm_avg编辑框编辑框IDC_SXIDC_SXintintm_sxm_sx01000100编辑框编辑框IDC_YWIDC_YWintintm_ywm_yw01000100编辑框编辑框IDC_YYIDC_YYintintm_yym_yy01000100按钮按钮

62、IDC_JSIDC_JS计算平均分计算平均分按钮按钮IDC_OKIDC_OK退出退出(1 1)创建工程:)创建工程:TEST2TEST2(2 2)添加控件,并)添加控件,并设置控件相关设置控件相关属性属性42步骤步骤3:连接变量:连接变量(1 1)单击)单击“建立类向导建立类向导”命令,启动类向导;命令,启动类向导;(2 2)选择)选择“成员变量成员变量”选取项卡,连接变量;选取项卡,连接变量;(3 3)结果如右图所示)结果如右图所示43BOOL CTEST2Dlg:OnInitDialog() CDialog:OnInitDialog(); / Add About. menu item to

63、 system menu.m_avg=0.0;UpdateData(FALSE);/省略省略步骤步骤4:进行消息映射:进行消息映射(1 1)初始化对话框(是程序运行时的开始)初始化对话框(是程序运行时的开始状态的设定)状态的设定)进入进入ClassWiZardClassWiZard(类向导),(类向导),Message Message MapsMaps,在,在Object IDsObject IDs里选择要添加里选择要添加OnInitDialogOnInitDialog()()函数的对话框类,在函数的对话框类,在MessagesMessages里选择里选择WM_INITDIALOGWM_INI

64、TDIALOG, ,单击单击Add FunctionAdd Function(增(增加函数),此时对话框类就新增了一个加函数),此时对话框类就新增了一个函数是函数是OnInitDialogOnInitDialog()()。(2 2)编辑初始化代码:)编辑初始化代码:44void CTEST2Dlg:OnJs() / TODO: Add your control notification handler code hereUpdateData(TRUE); /更新控件值更新控件值 double avg=double(m_sx+m_yw+m_yy)/3.0;m_avg.Format (%6.2f,

65、avg);UpdateData(FALSE); /控件值更新控件值更新编辑框编辑框显示显示步骤步骤5:编写代码:编写代码_对对“计算平均分计算平均分”按按钮钮(1 1)双击)双击“计算平均分计算平均分”按钮,为按钮,为IDC_JSIDC_JS添加添加BN_CLICKEDBN_CLICKED消息映射:消息映射:(2 2)编写代码。)编写代码。45步骤步骤6:编写代码:编写代码_对对“退出退出”按钮按钮(1 1)双击)双击“退出退出”按钮,为按钮,为IDC_OKIDC_OK添加添加BN_CLICKEDBN_CLICKED消消息映射:息映射:(2 2)编写代码。)编写代码。void CTEST2Dl

66、g:OnOk() / TODO: Add your control notification handler code hereOnOK();46步骤步骤7:调试程序:调试程序_运行运行注意:注意:对话框中平均分显示对话框中平均分显示部分是在设置属性时,部分是在设置属性时,选择了选择了“扩展样式扩展样式”选项卡中的选项卡中的“客户边客户边缘缘”选项的效果。选项的效果。返回返回实例实例47实例实例3单选钮应用程序单选钮应用程序设计如右图所示的程序。设计如右图所示的程序。基本步骤:基本步骤:1.1.创建工程创建工程TESTp246TESTp246, ,并进行并进行界面设计;界面设计;2.2.为编辑

67、框连接到为编辑框连接到CStringCString类类型的添加成员变量型的添加成员变量m_xmm_xm,其余控件不需连接;其余控件不需连接;3.3.为控件编辑为控件编辑IDID4. 4. 对单选钮编写对单选钮编写初始化函数初始化函数代码代码5. 5. 对对话框的对对话框的“确定确定”按钮按钮编写代码编写代码48步骤步骤13:建立框架,连接变量,编辑:建立框架,连接变量,编辑ID注意注意对组框对组框1 1中中2 2个单选按钮,在个单选按钮,在设置第一个按钮(男)的属设置第一个按钮(男)的属性时,需选定性时,需选定“组组”选项,选项,表示此组默认第表示此组默认第1 1个按钮;个按钮;同理对组框同理

68、对组框2 2中中3 3个单选按钮,个单选按钮,在设置第一个按钮(教授)在设置第一个按钮(教授)的属性时,需选定的属性时,需选定“组组”选选项,表示此组默认第项,表示此组默认第1 1个按个按钮;钮;组框本身的属性不要选中组框本身的属性不要选中“组组”选项。选项。49步骤步骤4:单选钮初始化函数代码单选钮初始化函数代码BOOL CTESTp246Dlg:OnInitDialog()BOOL CTESTp246Dlg:OnInitDialog() CDialog:OnInitDialogCDialog:OnInitDialog();();CheckRadioButton(IDC_RADIO1,IDC

69、_RADIO2,CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO1IDC_RADIO1););CheckRadioButton(IDC_RADIO3,IDC_RADIO5,CheckRadioButton(IDC_RADIO3,IDC_RADIO5,IDC_RADIO3IDC_RADIO3););/ Add About. menu item to system menu./ Add About. menu item to system menu.表示为默认表示为默认按钮按钮50步骤步骤5:对话框的对话框的“确定确定”按钮代码按钮代码void CT

70、ESTp246Dlg:OnButton1() void CTESTp246Dlg:OnButton1() / TODO: Add your control notification handler code here/ TODO: Add your control notification handler code hereUpdateData(TRUEUpdateData(TRUE););CStringCString s; s;s=s=s+m_xms+m_xm; ;if(IsDlgButtonChecked(IDC_RADIO1)if(IsDlgButtonChecked(IDC_RADIO

71、1)s=s+s=s+男男;elseelses=s+s=s+女女;if(IsDlgButtonChecked(IDC_RADIO3)if(IsDlgButtonChecked(IDC_RADIO3)s=s+s=s+教授教授;else if(IsDlgButtonChecked(IDC_RADIO4)else if(IsDlgButtonChecked(IDC_RADIO4)s=s+s=s+副教授副教授;elseelses=s+s=s+讲师讲师;AfxMessageBox(sAfxMessageBox(s);); 返回返回实例实例51实例实例4简易时钟简易时钟程序程序基于对话框基于对话框基本步骤:

72、基本步骤:1.1.创建工程(基于基本对话框的)创建工程(基于基本对话框的)CLOCKYS(CLOCKYS(时钟演示时钟演示) )2.2.添加新类添加新类CClockExCClockEx,实现时钟控件类。实现时钟控件类。3.3.添加消息响应及函数,来建立时钟控件的轮廓。添加消息响应及函数,来建立时钟控件的轮廓。4.4.时钟设计时钟设计时钟元素时钟元素5.5.创建时钟基类创建时钟基类CClockElementCClockElement6.6.添加时针类、分针类、秒针类添加时针类、分针类、秒针类7.7.编译执行。编译执行。步骤步骤1 1:创建工程:创建工程CLOCKYSCLOCKYS返回返回实例实例

73、52步骤步骤2:创建一个新类创建一个新类CClockEx从从CStaticCStatic(静态控件)类派生出类(静态控件)类派生出类CClockExCClockEx来实现时钟控件类,这样,就可以继承来实现时钟控件类,这样,就可以继承MFCMFC静态控件的静态控件的很多已经具备的功能和特点很多已经具备的功能和特点. .53步骤步骤3:添加消息响应添加消息响应建立时钟控件的轮廓建立时钟控件的轮廓时钟控件的轮廓时钟控件的轮廓单击单击“查看查看 建立类向导建立类向导” ” 调出调出Class WizardClass Wizard,在,在class nameclass name中选择刚建立的新类中选择刚

74、建立的新类CClockExCClockEx,进行如下,进行如下工作:工作:1. 重载虚函数重载虚函数PreSubClassWindow对时钟控件的基本初始化工作对时钟控件的基本初始化工作将在该函数中进行。将在该函数中进行。2. 添加添加WM_PAINT消息响应消息响应用于完成时钟的绘制工作。用于完成时钟的绘制工作。3. 添加添加WM_SIZE消息响应消息响应以便设计的时钟控件能自动适以便设计的时钟控件能自动适应其大小的变化。应其大小的变化。4. 添加添加WM_TIMER的的消息响应消息响应定时刷新时钟控件让它走动。定时刷新时钟控件让它走动。5.此时,时钟控件的轮廓已建好此时,时钟控件的轮廓已建

75、好。效效果如图所示。果如图所示。54步骤步骤4:时钟设计时钟设计时钟元素时钟元素时钟绘制的具体实现。时钟绘制的具体实现。时钟大致由:时钟背景、时针、分针、秒针时钟大致由:时钟背景、时针、分针、秒针4 4个部分构成。这个部分构成。这4 4个个部分可看作部分可看作4 4个不同的对象,可以考虑建立类来分别实现。个不同的对象,可以考虑建立类来分别实现。 。CClockBackgroundCClockBackground ( (背景)背景)CClockHourHandCClockHourHand(时针)(时针)CClockMinHandCClockMinHand(分针)(分针)CClockSecHand

76、CClockSecHand(秒针)(秒针)这这4 4个类有它们的共同点:个类有它们的共同点:都有自己的绘图函数;都有自己的绘图函数;都有自己的绘图颜色;都有自己的绘图颜色;都应有颜色设置函数;都应有颜色设置函数;都有绘图区域和区域设置函数等等。都有绘图区域和区域设置函数等等。因此,可以为它们的共性建立一个基类,命名为因此,可以为它们的共性建立一个基类,命名为: :CClockElementCClockElement(时钟元素)。(时钟元素)。55步骤步骤4续续:创建时钟基类创建时钟基类CClockElementCClockElement先建各个组成类的基类:先建各个组成类的基类:CClockE

77、lementCClockElement方法:方法:右键单击右键单击ClassViewClassView的工程的工程选择选择New ClassNew Class;在在ClassTypeClassType里面选择里面选择GenenricGenenric Class Class,类;,类;CClockElementCClockElement不需要从其不需要从其它类派生,所以它类派生,所以Base ClassBase Class可以不填,效果如右图所示。可以不填,效果如右图所示。56步骤步骤4续续:创建时钟基类创建时钟基类CClockElementCClockElement代代码码对类对类CClock

78、ElementCClockElement的源代码进行编写。的源代码进行编写。1.1.添加头文件添加头文件 #include#include 因后面的绘图中需要用到因后面的绘图中需要用到sinsin和和coscos这两个数学计算公式。这两个数学计算公式。为后面计算使用,定义数学常量为后面计算使用,定义数学常量 PIPI(3.14159265353.1415926535)。2.2.在基类中定义绘图区域变量在基类中定义绘图区域变量时钟的每个组成部分都有绘图区域区域,可定义颜色变量。时钟的每个组成部分都有绘图区域区域,可定义颜色变量。为了是颜色不显得单调,这里为每个控件设置两种颜色为了是颜色不显得单调

79、,这里为每个控件设置两种颜色(如果想使程序更加绚丽,可以设置更多颜色)。(如果想使程序更加绚丽,可以设置更多颜色)。3.3.增加接口函数增加接口函数这些变量需增加接口函数来进行访问。这些变量需增加接口函数来进行访问。4.4.每个组成部分都应该有的每个组成部分都应该有的DrawDraw(绘图)函数(绘图)函数也需在基类中定义,但是,该函数对于基类来说是无需函数也需在基类中定义,但是,该函数对于基类来说是无需函数实现的,因此可定义为实现的,因此可定义为纯虚函数纯虚函数。57步骤步骤4续续:创建时钟基类创建时钟基类CClockElementCClockElement代代码码/ / ClockElem

80、ent.hClockElement.h: : interface for the interface for the CClockElementCClockElement class. class. CClockElementCClockElement的实现的头文件代码如下:的实现的头文件代码如下:#if !defined(AFX_CLOCKELEMENT_H_08A9DFB3_95C0_4D70_9BC0_96D3BACAB74A_INCLUDED_)#if !defined(AFX_CLOCKELEMENT_H_08A9DFB3_95C0_4D70_9BC0_96D3BACAB74A_IN

81、CLUDED_)#define AFX_CLOCKELEMENT_H_08A9DFB3_95C0_4D70_9BC0_96D3BACAB74A_INCLUDED_#define AFX_CLOCKELEMENT_H_08A9DFB3_95C0_4D70_9BC0_96D3BACAB74A_INCLUDED_#if _MSC_VER 1000#if _MSC_VER 1000# #pragmapragma once once# #endifendif / _MSC_VER 1000 / _MSC_VER 1000#include #include #define PI 3.1415926535#

82、define PI 3.1415926535class class CClockElementCClockElement public:public:void void SetColor(COLORREFSetColor(COLORREF crMaincrMain, COLORREF , COLORREF crOthercrOther););/设置颜色设置颜色void void SetTime(constSetTime(const CTimeCTime & &tmCurtmCur););/设置当前时间设置当前时间void void SetRegion(LPRECTSetRegion(LPREC

83、T lprcRectlprcRect);); /设置绘图区域设置绘图区域virtual void virtual void Draw(CDCDraw(CDC * *pDCpDC) = 0;) = 0; /绘图函数绘图函数, ,此函数是一虚函数此函数是一虚函数CClockElementCClockElement();();virtual virtual CClockElementCClockElement();();protected:protected:COLORREFCOLORREF m_crMainm_crMain; ; /主要颜色主要颜色COLORREFCOLORREF m_crOthe

84、rm_crOther; ; /辅助的其他颜色辅助的其他颜色CTimeCTimem_tmCurm_tmCur; ; /当前时刻当前时刻CRectCRectm_rcRegionm_rcRegion; ;/绘图区域绘图区域intintm_nRadiusm_nRadius; ;/时钟半径时钟半径;58CClockElement的实现的源文件关键代码如下:的实现的源文件关键代码如下:/ / ClockElement.cppClockElement.cpp: :CClockElement:CClockElementCClockElement:CClockElement() () /时钟基类构造函数时钟基类

85、构造函数 m_nRadiusm_nRadius = 0; = 0; /时钟半径时钟半径m_crMainm_crMain = RGB(255, 255, 255); = RGB(255, 255, 255); /主要颜色主要颜色m_crOtherm_crOther = RGB(128, 128, 128); = RGB(128, 128, 128);/辅助的其他颜色辅助的其他颜色 CClockElement:CClockElementCClockElement:CClockElement() () /时钟基类析构函数时钟基类析构函数/设置绘图区域函数设置绘图区域函数void void CCloc

86、kElement:SetRegion(LPRECTCClockElement:SetRegion(LPRECT lprcRectlprcRect) ) m_rcRegionm_rcRegion = = lprcRectlprcRect; ; /区域取值区域取值m_nRadiusm_nRadius = = m_rcRegion.Widthm_rcRegion.Width() / 2; () / 2; /半径取值半径取值if (if (m_rcRegion.Widthm_rcRegion.Width() () m_rcRegion.Heightm_rcRegion.Height()()/半径的宽度

87、和顶点比较半径的宽度和顶点比较 m_nRadiusm_nRadius = = m_rcRegion.Heightm_rcRegion.Height() / 2;() / 2; /设置当前时间函数设置当前时间函数void CClockElement:SetTime(const CTime &tmCur)void CClockElement:SetTime(const CTime &tmCur) m_tmCur = tmCur;m_tmCur = tmCur; /设置颜色函数设置颜色函数void CClockElement:SetColor(COLORREF crMain, COLORREF cr

88、Other)void CClockElement:SetColor(COLORREF crMain, COLORREF crOther) m_crMain = crMain;m_crMain = crMain; /获取主获取主颜色颜色m_crOther = crOther;m_crOther = crOther; /获取其他获取其他颜色颜色 59步骤步骤5:创建时钟背景类创建时钟背景类CClockBackground时钟背景类时钟背景类CClockBackgroundCClockBackground操作方法:操作方法:在在ClassViewClassView的工程名上面点右键,选择的工程名上面

89、点右键,选择New ClassNew Class,在在ClassTypeClassType里面选择里面选择GenenricGenenric Class Class,选择类选择类Base ClassBase ClassCClockElementCClockElement类类因CClockBackground需从类CClockElement派生效果如图所示。效果如图所示。60步骤步骤5续续:创建时钟背景类创建时钟背景类CClockBackgroundCClockBackgroundCClockBackground只需实现基类的虚函数只需实现基类的虚函数DrawDraw即可,因此即可,因此这里重载基

90、类的虚函数这里重载基类的虚函数DrawDraw,其头文件实现代码如下(不,其头文件实现代码如下(不用编写,由系统生成):用编写,由系统生成):#include #include ClockElement.hClockElement.h class class CClockBackgroundCClockBackground : public : public CClockElementCClockElement public:public:CClockBackgroundCClockBackground();();virtual virtual CClockBackgroundCClockBa

91、ckground();();61CClockBackground源文件代码如下:源文件代码如下:/ / ClockBackground.cppClockBackground.cpp: :/时钟背景函数时钟背景函数CClockBackground:CClockBackgroundCClockBackground:CClockBackground()() /为时钟背景定义默认的颜色设置为时钟背景定义默认的颜色设置m_crMainm_crMain = RGB(0, 255, 0); = RGB(0, 255, 0); /主颜色为绿色主颜色为绿色m_crOtherm_crOther = RGB(0,

92、128, 0); = RGB(0, 128, 0); /其他颜色为深绿色其他颜色为深绿色 CClockBackground:CClockBackgroundCClockBackground:CClockBackground()() 62CClockBackgroundCClockBackground源文件代码如下(续源文件代码如下(续1 1):):/Draw /Draw 绘图函数绘图函数void void CClockBackground:Draw(CDCCClockBackground:Draw(CDC * *pDCpDC) ) /准备准备设备环境设备环境(也称设备上下文(也称设备上下文,

93、,简称简称DCDC), ,是图形设备的主要接口是图形设备的主要接口CPenCPen penMain(PS_SOLIDpenMain(PS_SOLID, 1, , 1, m_crMainm_crMain), /), /创建一支主颜色为绿色能画实线(创建一支主颜色为绿色能画实线(SOLIDSOLID)1 1号粗细的画笔号粗细的画笔penOther(PS_SOLIDpenOther(PS_SOLID, 1, , 1, m_crOtherm_crOther); /); /创建一支其他颜色为深绿色能画实线创建一支其他颜色为深绿色能画实线1 1号粗细的画笔号粗细的画笔CBrushCBrush brMain

94、(m_crMainbrMain(m_crMain), ), brOther(m_crOtherbrOther(m_crOther); ); /创建主画刷和其他画刷创建主画刷和其他画刷/将其他画笔选入内存将其他画笔选入内存DCDC,同时暂时挤出并保存原画笔,同时暂时挤出并保存原画笔 CPenCPen * *pOldPenpOldPen = = pDCpDC-SelectObject(&penOtherSelectObject(&penOther); ); /将主画刷选入内存将主画刷选入内存DCDC,同时暂时挤出并保存原画刷,同时暂时挤出并保存原画刷CBrushCBrush * *pOldBrus

95、hpOldBrush = = pDCpDC-SelectObject(&brMainSelectObject(&brMain););/绘制绘制6060个小圆点,表示分针和秒针的刻度个小圆点,表示分针和秒针的刻度CPoint ptCenter = m_rcRegion.CenterPoint(); CPoint ptCenter = m_rcRegion.CenterPoint(); /创建画点对象并初始化创建画点对象并初始化int nRadius = m_nRadius - 8;int nRadius = m_nRadius - 8; /定义半径的初值定义半径的初值for(int i=0; i

96、60; i+)for(int i=0; iEllipse(rcDot);pDC-Ellipse(rcDot); 63CClockBackgroundCClockBackground源文件代码如下(续源文件代码如下(续2 2):):/绘制绘制1212个小方框,表示个小方框,表示1212个正点个正点pDC-SelectObject(&penMain); pDC-SelectObject(&penMain); /恢复内存恢复内存DCDC中原有的主画笔中原有的主画笔pOldBrush = pDC-SelectObject(&brOther);pOldBrush = pDC-SelectObject(&

97、brOther);for(i=0; i12; i+)for(i=0; iRectangle(rcDot);pDC-Rectangle(rcDot); /还原设备环境还原设备环境pDC-SelectObject(pOldPen);pDC-SelectObject(pOldPen); /恢复内存恢复内存DCDC中原有的画笔中原有的画笔pDC-SelectObject(pOldBrush); pDC-SelectObject(pOldBrush); /恢复内存恢复内存DCDC中原有的画刷中原有的画刷64步骤步骤6:创建时针类创建时针类CClockHourHand实现实现实现时针类实现时针类CCloc

98、kHourHandCClockHourHand该类新建的过程与该类新建的过程与CClockBackgroundCClockBackground一样。一样。选择类选择类Base ClassBase ClassCClockElementCClockElement类类因CClockHourHand需从类CClockElement派生CClockHourHandCClockHourHand同样只需实现基类的虚函数同样只需实现基类的虚函数DrawDraw即可即可其头文件实现代码如下:其头文件实现代码如下:#include #include ClockElement.hClockElement.h cla

99、ss class CClockHourHandCClockHourHand : public : public CClockElementCClockElement public:public:CClockHourHandCClockHourHand();();virtual virtual CClockHourHandCClockHourHand();();virtual void virtual void Draw(CDCDraw(CDC * *pDCpDC););65CClockHourHand源文件代码如下:源文件代码如下:CClockHourHand:CClockHourHandCC

100、lockHourHand:CClockHourHand()() /定义默认颜色定义默认颜色m_crMainm_crMain = RGB(0, 255, 100); = RGB(0, 255, 100);m_crOtherm_crOther = RGB(128, 128, 0); = RGB(128, 128, 0); CClockHourHand:CClockHourHandCClockHourHand:CClockHourHand()() void void CClockHourHand:Draw(CDCCClockHourHand:Draw(CDC * *pDCpDC) ) /初始化设备环

101、境初始化设备环境CPenCPen penMain(PS_SOLIDpenMain(PS_SOLID, 1, , 1, m_crMainm_crMain), ), penOther(PS_SOLIDpenOther(PS_SOLID, 1, , 1, m_crOtherm_crOther););CBrushCBrush brMain(m_crMainbrMain(m_crMain), ), brOther(m_crOtherbrOther(m_crOther););CPenCPen * *pOldPenpOldPen = = pDCpDC-SelectObject(&penOtherSelect

102、Object(&penOther););CBrushCBrush * *pOldBrushpOldBrush = = pDCpDC-SelectObject(&brMainSelectObject(&brMain););/确定当前指针的弧度确定当前指针的弧度intint nTimenTime = ( = (m_tmCur.GetHourm_tmCur.GetHour() % 12) * 3600;() % 12) * 3600;nTimenTime += += m_tmCur.GetMinutem_tmCur.GetMinute() * 60;() * 60;nTimenTime += +=

103、m_tmCur.GetSecondm_tmCur.GetSecond();();double double fRadianfRadian = 2 * PI * = 2 * PI * nTimenTime / 3600 / 12; / 3600 / 12; 66CClockHourHand源文件代码如下(续):源文件代码如下(续):/确定绘制菱形指针所需的四个角的坐标确定绘制菱形指针所需的四个角的坐标CPointCPoint ptDiamond4; ptDiamond4;for(intfor(int i=0; i4; i+) i=0; i-Polygon(ptDiamondPolygon(ptD

104、iamond, 4);, 4);/恢复设备环境恢复设备环境pDCpDC-SelectObject(pOldPenSelectObject(pOldPen););pDCpDC-SelectObject(pOldBrushSelectObject(pOldBrush);); 67步骤步骤7:创建分针类创建分针类CClockMinHand实现实现实现分针类实现分针类CClockMinHandCClockMinHand该类新建的过程与该类新建的过程与CClockHourHandCClockHourHand一样,类的实现也一样,类的实现也基本相似,其头文件实现代码如下:基本相似,其头文件实现代码如下:C

105、ClockMinHandCClockMinHand类类因CClockMinHand需从类CClockElement派生CClockMinHandCClockMinHand同样只需实现基类的虚函数同样只需实现基类的虚函数DrawDraw即可即可#include ClockElement.h#include ClockElement.hclass CClockMinHand : public CClockElement class CClockMinHand : public CClockElement public:public:CClockMinHand();CClockMinHand();v

106、irtual CClockMinHand();virtual CClockMinHand();virtual void Draw(CDC *pDC);virtual void Draw(CDC *pDC);68CClockMinHand源文件代码如下:源文件代码如下:CClockMinHand:CClockMinHandCClockMinHand:CClockMinHand()() /定义默认颜色定义默认颜色m_crMainm_crMain = RGB(0, 255, 100); = RGB(0, 255, 100);m_crOtherm_crOther = RGB(128, 128, 0);

107、 = RGB(128, 128, 0); CClockMinHand:CClockMinHandCClockMinHand:CClockMinHand()() void void CClockMinHand:Draw(CDCCClockMinHand:Draw(CDC * *pDCpDC) ) /初始化设备环境初始化设备环境CPenCPen penMain(PS_SOLIDpenMain(PS_SOLID, 1, , 1, m_crMainm_crMain), ), penOther(PS_SOLIDpenOther(PS_SOLID, 1, , 1, m_crOtherm_crOther);

108、);CBrushCBrush brMain(m_crMainbrMain(m_crMain), ), brOther(m_crOtherbrOther(m_crOther););CPenCPen * *pOldPenpOldPen = = pDCpDC-SelectObject(&penOtherSelectObject(&penOther););CBrushCBrush * *pOldBrushpOldBrush = = pDCpDC-SelectObject(&brMainSelectObject(&brMain););/确定分针所在位置的弧度确定分针所在位置的弧度intint nTime

109、nTime = = m_tmCur.GetMinutem_tmCur.GetMinute() * 60;() * 60;nTimenTime += += m_tmCur.GetSecondm_tmCur.GetSecond();();double double fRadianfRadian = 2 * PI * = 2 * PI * nTimenTime / 3600; / 3600;69CClockMinHand源文件代码如下(续):源文件代码如下(续):/确定绘制菱形指针所需的四个角的坐标确定绘制菱形指针所需的四个角的坐标CPointCPoint ptDiamond4; ptDiamond

110、4;for(intfor(int i=0; i4; i+) i=0; i-Polygon(ptDiamondPolygon(ptDiamond, 4);, 4);/恢复设备环境恢复设备环境pDCpDC-SelectObject(pOldPenSelectObject(pOldPen););pDCpDC-SelectObject(pOldBrushSelectObject(pOldBrush);); 70步骤步骤8:创建秒针类创建秒针类CClockSecHand实现实现实现秒针类实现秒针类CClockSecHandCClockSecHand此类与此类与CClockHourHandCClockHo

111、urHand一样建立,类的实现也基本相似一样建立,类的实现也基本相似其头文件实现代码如下:其头文件实现代码如下:#include #include ClockElement.hClockElement.h class class CClockSecHandCClockSecHand : public : public CClockElementCClockElement public:public:CClockSecHandCClockSecHand();();virtual virtual CClockSecHandCClockSecHand();();virtual void virtua

112、l void Draw(CDCDraw(CDC * *pDCpDC););71CClockSecHand源文件代码如下:源文件代码如下:CClockSecHand:CClockSecHandCClockSecHand:CClockSecHand()() /设定秒针的默认颜色设定秒针的默认颜色m_crMainm_crMain = RGB(0, 200, 200); = RGB(0, 200, 200);m_crOtherm_crOther = RGB(0, 200, 200); = RGB(0, 200, 200); CClockSecHand:CClockSecHandCClockSecHan

113、d:CClockSecHand()() void void CClockSecHand:Draw(CDCCClockSecHand:Draw(CDC * *pDCpDC) ) intint nTimenTime = = m_tmCur.GetSecondm_tmCur.GetSecond();();CPointCPoint ptStartptStart = = m_rcRegion.CenterPointm_rcRegion.CenterPoint();();CPointCPoint ptEndptEnd = = ptStartptStart; ;intint nRadiusnRadius =

114、 = m_nRadiusm_nRadius - 10; - 10;ptEnd.Offset(int)(nRadiusptEnd.Offset(int)(nRadius * sin(2 * PI * * sin(2 * PI * nTimenTime / 60), / 60), ( (int)(-nRadiusint)(-nRadius * cos(2 * PI * * cos(2 * PI * nTimenTime / 60); / 60);CPenCPen penMain(PS_SOLIDpenMain(PS_SOLID, 1, , 1, m_crMainm_crMain););CPenCP

115、en * *pOldPenpOldPen = = pDCpDC-SelectObject(&penMainSelectObject(&penMain););pDCpDC-MoveTo(ptStartMoveTo(ptStart););pDCpDC-LineTo(ptEndLineTo(ptEnd););pDCpDC-SelectObject(pOldPenSelectObject(pOldPen);); 72步骤步骤9:组装。:组装。到目前为止,时钟的各个部件都已经设计完毕,现在该把它们组装起来了。到目前为止,时钟的各个部件都已经设计完毕,现在该把它们组装起来了。刚才建立的刚才建立的4 4个类

116、个类CClockBackgroundCClockBackground、CClockHourHandCClockHourHand、CClockMinHandCClockMinHand、CClockSecHandCClockSecHand要为要为CClockExCClockEx服务,正如服务,正如CClockElementCClockElement为它们服务一样,不过服务的方式发生了变化,刚才是以为它们服务一样,不过服务的方式发生了变化,刚才是以继承的方式使用,现在需要将上面继承的方式使用,现在需要将上面4 4个类实例化供个类实例化供CClockExCClockEx使用。因此,首先应该在类使用。因

117、此,首先应该在类CClockExCClockEx为上为上4 4个类分别建立对象。个类分别建立对象。在在CClockExCClockEx的头文件的头文件中恰当位置加入以下代码:中恰当位置加入以下代码:#include #include ClockBackground.hClockBackground.h #include #include ClockHourHand.hClockHourHand.h #include #include ClockMinHand.hClockMinHand.h #include #include ClockSecHand.hClockSecHand.h class

118、 class CClockExCClockEx : public : public CStaticCStatic private:private:CClockBackgroundCClockBackgroundm_clockBKm_clockBK; ;/时钟背景时钟背景CClockHourHandCClockHourHandm_clockHourm_clockHour; ;/时指针时指针CClockMinHandCClockMinHand m_clockMinm_clockMin; ; /分指针分指针CClockSecHandCClockSecHand m_clockSecm_clockSec

119、; ;/秒指针秒指针为了存储绘图区域的大小,需要在为了存储绘图区域的大小,需要在CClockExCClockEx中加入一个变量中加入一个变量m_rcClientm_rcClient: CRectCRect m_rcClientm_rcClient; ;/客户区域客户区域73在在PreSubclassWindowPreSubclassWindow函数中进行时钟的初始化工作。函数中进行时钟的初始化工作。首先得为各个部件设定区域大小;首先得为各个部件设定区域大小;然后启动定时刷新的定时器(然后启动定时刷新的定时器(100100毫秒的定时器已经足够)。毫秒的定时器已经足够)。由于每个部件都有自己的默认

120、颜色配置,因此这里暂且先使用由于每个部件都有自己的默认颜色配置,因此这里暂且先使用默认配置,当然也可以自定义颜色:默认配置,当然也可以自定义颜色:GetClientRect(m_rcClientGetClientRect(m_rcClient); ); /获取当前客户区域获取当前客户区域m_clockBK.SetRegion(m_rcClientm_clockBK.SetRegion(m_rcClient););m_clockHour.SetRegion(m_rcClientm_clockHour.SetRegion(m_rcClient););m_clockMin.SetRegion(m_r

121、cClientm_clockMin.SetRegion(m_rcClient););m_clockSec.SetRegion(m_rcClientm_clockSec.SetRegion(m_rcClient););SetTimer(1, 100, NULL);SetTimer(1, 100, NULL); /每每100100毫秒刷新一次毫秒刷新一次74当控件大小发生变化时,控件状态要能够自动更新:当控件大小发生变化时,控件状态要能够自动更新:void void CClockEx:OnSize(UINTCClockEx:OnSize(UINT nTypenType, , intint cxcx

122、, , intint cy) cy) CStatic:OnSize(nTypeCStatic:OnSize(nType, , cxcx, cy);, cy); GetClientRect(m_rcClientGetClientRect(m_rcClient););m_clockBK.SetRegion(m_rcClientm_clockBK.SetRegion(m_rcClient););m_clockHour.SetRegion(m_rcClientm_clockHour.SetRegion(m_rcClient););m_clockMin.SetRegion(m_rcClientm_clo

123、ckMin.SetRegion(m_rcClient););m_clockSec.SetRegion(m_rcClientm_clockSec.SetRegion(m_rcClient);); 每个定时器时间触发时,需要刷新控件以保证时钟的走动:每个定时器时间触发时,需要刷新控件以保证时钟的走动:void void CClockEx:OnTimer(UINTCClockEx:OnTimer(UINT nIDEventnIDEvent) ) Invalidate(FALSEInvalidate(FALSE););CStatic:OnTimer(nIDEventCStatic:OnTimer(nI

124、DEvent);); 75实现时钟的绘制实现时钟的绘制下面实现时钟的绘制,由于控件在不断刷新,按一般方式绘图,屏幕下面实现时钟的绘制,由于控件在不断刷新,按一般方式绘图,屏幕会不断闪烁,因此此处使用双缓冲绘图会不断闪烁,因此此处使用双缓冲绘图就是在内存中绘图,绘制就是在内存中绘图,绘制完毕时再完毕时再CopyCopy到屏幕上,这样可以有效的防止屏幕闪烁:到屏幕上,这样可以有效的防止屏幕闪烁:void void CClockEx:OnPaintCClockEx:OnPaint() () CPaintDCCPaintDC dc(thisdc(this); ); / device context f

125、or painting/ device context for painting/实现双缓冲绘图实现双缓冲绘图防止屏幕闪烁防止屏幕闪烁CDC CDC dcMemdcMem; ; /建立一个和建立一个和pDCpDC兼容的内存兼容的内存DC: DC: dcMemdcMemdcMem.CreateCompatibleDC(&dcdcMem.CreateCompatibleDC(&dc););CBitmapCBitmapbmp; bmp; /建立一个位图对象,其建立一个位图对象,其宽度宽度和和高度高度用当前绘图区的用当前绘图区的bmp.CreateCompatibleBitmap(&dcbmp.Cre

126、ateCompatibleBitmap(&dc, , m_rcClient.Widthm_rcClient.Width(),(), m_rcClient.Heightm_rcClient.Height() );() );dcMem.SelectObject(&bmpdcMem.SelectObject(&bmp); ); /将将bmpbmp选入到选入到dcMemdcMem中中DrawClock(&dcMemDrawClock(&dcMem););/绘制时钟绘制时钟dc.BitBlt(0, 0, dc.BitBlt(0, 0, m_rcClient.Widthm_rcClient.Width()

127、, (), m_rcClient.Heightm_rcClient.Height(), &(), &dcMemdcMem, 0, 0, SRCCOPY);, 0, 0, SRCCOPY); /将将dcMemdcMem中的图拷贝到中的图拷贝到pDCpDC上进行显示上进行显示。 76DrawClock的函数实现:的函数实现:将绘图函数放在一个单独的将绘图函数放在一个单独的函数函数DrawClockDrawClock中。并写入到文件中。并写入到文件CLOCKYS.cppCLOCKYS.cpp 中,另外,在中,另外,在ClockEx.hClockEx.h的头文件的头文件中添加函数声明如下中添加函数声明

128、如下图所示。图所示。/ / CLOCKYS.cppCLOCKYS.cpp void void CClockEx:DrawClock(CDCCClockEx:DrawClock(CDC * *pDCpDC) ) CTimeCTime tmCurtmCur = = CTime:GetCurrentTimeCTime:GetCurrentTime();();m_clockBK.SetTime(tmCurm_clockBK.SetTime(tmCur););m_clockHour.SetTime(tmCurm_clockHour.SetTime(tmCur););m_clockMin.SetTime(

129、tmCurm_clockMin.SetTime(tmCur););m_clockSec.SetTime(tmCurm_clockSec.SetTime(tmCur););m_clockBK.Draw(pDCm_clockBK.Draw(pDC););m_clockMin.Draw(pDCm_clockMin.Draw(pDC););m_clockHour.Draw(pDCm_clockHour.Draw(pDC););m_clockSec.Draw(pDCm_clockSec.Draw(pDC);); 77步骤步骤5:添加:添加Static控件控件打开资源编辑器,在对话打开资源编辑器,在对话框

130、中拖入一个框中拖入一个StaticStatic控件,控件,调整外观至合适,将其调整外观至合适,将其IDID改为改为IDC_CLOCKIDC_CLOCK。如图效果。如图效果所示:所示:测试看时钟的实现效果。测试看时钟的实现效果。78步骤步骤6: 为为IDC_CLOCK控件映射变量控件映射变量打开打开Class WizardClass Wizard,为,为IDC_CLOCKIDC_CLOCK映射一个变量,映射一个变量,变量类型为变量类型为CClockExCClockEx。如下图效果所示:。如下图效果所示:79步骤步骤7: 编译执行编译执行在对话框类的头文件中加入头文件:在对话框类的头文件中加入头文

131、件:#include #include ClockEx.hClockEx.h 。程序代码基本编写完毕。编译整个工程,执行可程序代码基本编写完毕。编译整个工程,执行可执行程序,就可以看到整个时钟控件的效果图了。执行程序,就可以看到整个时钟控件的效果图了。80实例实例5简易简易计算器程序计算器程序 基本步骤:基本步骤:1.1.创建工程创建工程MyCalMyCal(CalculatorCalculator)及)及可视化设计可视化设计2.2.为控件编辑为控件编辑IDID3.3.为控件(为控件(IDC_0 , IDC_1 )插入消息映射及)插入消息映射及函数函数4.4.为编辑框添加成员变量为编辑框添加成

132、员变量m_resultm_result5.5.对主要成员函数编写代对主要成员函数编写代码码81步骤步骤1:创建工程并进行可视化设计:创建工程并进行可视化设计 创建工程(基本对话框)创建工程(基本对话框)MyCalMyCal(工程名)(工程名)可视化设计(计算器界面设计)可视化设计(计算器界面设计)添加控件添加控件添加计算器中的数字、运算符添加计算器中的数字、运算符等按钮和数字显示编辑框,如等按钮和数字显示编辑框,如右图。右图。控件的两个要素控件的两个要素IDID标识符标识符CaptionCaption文本文本编辑框编辑框IDC_DISPLAYIDC_DISPLAY用于显示数据输入输出用于显示数

133、据输入输出82步骤步骤2:为控件编辑:为控件编辑ID按钮名称按钮名称ID用途用途按钮名称按钮名称ID用途用途0IDC_0按键按键0.IDC_dian按键按键 .1IDC_1按键按键1+/-IDC_zhengfu正负正负2IDC_2按键按键2+IDC_jia加加3IDC_3按键按键3-IDC_jian减减4IDC_4按键按键4*IDC_cheng乘乘5IDC_5按键按键5/IDC_chu除除6IDC_6按键按键6CEIDC_qinglin清零清零7IDC_7按键按键7sqrtIDC_sqrt开方开方8IDC_8按键按键8x*xIDC_pingfang平方平方9IDC_9按键按键9=IDC_den

134、gyu等于等于编辑框编辑框IDC_DISPLAY显示显示83步骤步骤3:为控件插入消息映射及函数:为控件插入消息映射及函数进入进入ClassWizardClassWizard界面选择界面选择Message MapsMessage Maps为控件插入消息为控件插入消息映射及消息函数,实现控件命映射及消息函数,实现控件命令功能。令功能。右键单击控件右键单击控件“0 0”,”,选择选择“建建立类向导立类向导”, ,单击单击“ADD ADD FunctionFunction”按钮按钮, ,如图所示如图所示, ,输输入成员函数名入成员函数名, ,单击单击“OKOK”按钮;按钮;单击单击“Edit cod

135、eEdit code”按钮,直接按钮,直接进入函数体编辑,如图所示。进入函数体编辑,如图所示。其他控件操作类似其他控件操作类似注意:编辑控件注意:编辑控件( (IDC_DISPLAY) )不要插入消息不要插入消息映射及函数映射及函数84步骤步骤4:为编辑框添加成员变量:为编辑框添加成员变量m_result进入进入ClassWizardClassWizard界面界面Message Message VariblesVaribles为编辑框为编辑框IDC_DISPLAY添加成员变量添加成员变量m_resultm_result用以显示结果。用以显示结果。如图:如图:85步骤步骤5:对主要成员函数编写代

136、码:对主要成员函数编写代码在在MyCalDlg.hMyCalDlg.h中中加入主要成员函数加入主要成员函数和成员变量的申明和成员变量的申明在在MyCalDlg.cppMyCalDlg.cpp中中加入主要加入主要成员函数实现过程成员函数实现过程和成员变量的初始化和成员变量的初始化代码片段后面介绍代码片段后面介绍主要成员函数关系图主要成员函数关系图按钮09.函数如: On0( ).On1( ).On2( ).处理数字输入OnOperandInput( )计算Calculate( )显示输出UpdateDisplay( )按 钮 + - * / . +/- CE = 函数如:Onjia( ). On

137、jian( ).Oncheng( ) .按 钮 sqrt x*x 函数:Onsqrt( ).Onpingfang( )86步骤步骤5续:对头文件续:对头文件MyCalDlg.h编写代码编写代码/在头文件中手动添加成员函数与成员变量声明在头文件中手动添加成员函数与成员变量声明/ / MyCalDlg.hMyCalDlg.h : header file : header file/定义两个定义两个euumeuum枚举枚举类型类型Operator, Operator, CalcErrorCalcError结构结构enumenum Operator Operator OpNoneOpNone, , O

138、pAddOpAdd, , OpSubtractOpSubtract, , OpMultiplyOpMultiply, , OpDivideOpDivide ; ;enumenum CalcErrorCalcError ErrNoneErrNone, , ErrDivideByZeroErrDivideByZero ; ;double double m_operandm_operand; ; /存储当前输入的操作数存储当前输入的操作数double double m_accumm_accum; ; /存储当前的计算处理结束存储当前的计算处理结束BOOL BOOL m_bCoffm_bCoff; ;

139、 /标识当前输入是否是小数标识当前输入是否是小数double double m_coffm_coff; ; /小数输入时的系数小数输入时的系数Operator Operator m_operatorm_operator; ; /定义定义 枚举枚举变量变量 m_operatorm_operator 用以标识当前运算用以标识当前运算符符CalcErrorCalcError m_errorStatem_errorState; ; / / 定义定义 枚举枚举 变量变量m_errorStatem_errorState 用以标识当前运算状态用以标识当前运算状态BOOL BOOL m_bOperandAva

140、ilm_bOperandAvail; /; /标识当前输入是否是新输入数字标识当前输入是否是新输入数字void void UpdateDisplayUpdateDisplay(); (); /成员函数成员函数处理显示处理显示void Calculate(); /void Calculate(); /成员函数成员函数处理计算处理计算void void OnOperandInput(intOnOperandInput(int a); a); /成员函数成员函数处理数字输入处理数字输入87步骤步骤5续续:对原文件对原文件MyCalDlg.cpp编写代码编写代码/在执行文件中添加成员函数实现部分与变量

141、初始在执行文件中添加成员函数实现部分与变量初始/ / MyCaDlg.cppMyCaDlg.cpp : implementation file : implementation file #include “#include “math.hmath.h“/需使用平方根函数,所以要添加此头文件需使用平方根函数,所以要添加此头文件/以下是对声明变量进行初始化以下是对声明变量进行初始化MyCalDlg:MyCalDlg(CWndMyCalDlg:MyCalDlg(CWnd* * pParentpParent /*=NULL*/) /*=NULL*/): : CDialog(MyCalDlg:IDDC

142、Dialog(MyCalDlg:IDD, , pParentpParent) ) /AFX_DATA_INIT(CCaaDlgAFX_DATA_INIT(CCaaDlg) )m_resultm_result = _T(“”); = _T(“”); /默认为默认为m_resultm_result变量初始化变量初始化/AFX_DATA_INIT/AFX_DATA_INIT/ Note that / Note that LoadIconLoadIcon does not require a subsequent does not require a subsequent DestroyIconDes

143、troyIcon in Win32 in Win32/m_hIconm_hIcon = = AfxGetAppAfxGetApp()-()-LoadIcon(IDR_MAINFRAMELoadIcon(IDR_MAINFRAME););m_coffm_coff=0.1; =0.1; /为变量进行初始化为变量进行初始化m_bCoffm_bCoff=0; =0; /为变量进行初始化为变量进行初始化m_errorStatem_errorState = = ErrNoneErrNone; ; /为变量进行初始化为变量进行初始化m_bOperandAvailm_bOperandAvail=FALSE;

144、=FALSE; /为变量进行初始化为变量进行初始化m_operatorm_operator= =OpNoneOpNone; ; /为变量进行初始化为变量进行初始化 88步骤步骤5续:对控件续:对控件09编写代码编写代码/以下是消息处理函数,用以响应消息映射以下是消息处理函数,用以响应消息映射void void CMyCalDlgCMyCalDlg : :On0()On0() /处理处理“ “ 0”0”按钮按钮 / TODO: Add your control notification handler code here/ TODO: Add your control notification

145、handler code hereOnOperandInput(0);OnOperandInput(0); void void CMyCalDlgCMyCalDlg:On1()On1() /处理处理“ “ 1”1”按钮按钮/ TODO: Add your control notification handler code here/ TODO: Add your control notification handler code hereOnOperandInputOnOperandInput(1)(1); ; 注意:处理注意:处理“09”09”按钮的代码都类同。方法为:按钮的代码都类同。方法

146、为:进入类向导中,单击进入类向导中,单击“Edit code”Edit code”按钮,直接进入函数体编按钮,直接进入函数体编辑辑或手动进入或手动进入 (MyCalDlg.cppMyCalDlg.cpp : implementation file : implementation file)编辑)编辑89步骤步骤5续:对控件续:对控件“*,/,+” 编写代码编写代码void void CMyCalDlgCMyCalDlg : :OnchengOncheng() () /处理处理“ *”“ *”按钮按钮 / TODO: Add your control notification handler

147、code here/ TODO: Add your control notification handler code hereCalculate();Calculate();m_operatorm_operator = = OpMultiplyOpMultiply; ; void void CMyCalDlgCMyCalDlg : :OnchuOnchu() () /处理处理“ “ /”/”按钮按钮 / TODO: Add your control notification handler code here/ TODO: Add your control notification hand

148、ler code hereCalculate();Calculate();m_operatorm_operator = = OpDivideOpDivide; ; void void CMyCalDlgCMyCalDlg : :OnjiaOnjia() () /处理处理“ “ +”+”按钮按钮 / TODO: Add your control notification handler code here/ TODO: Add your control notification handler code hereCalculate();Calculate();m_operatorm_operat

149、or = = OpAddOpAdd; ; 90步骤步骤5续:对控件续:对控件“=, .” 编写代码编写代码void void CMyCalDlgCMyCalDlg : :OndengyuOndengyu() () /处理处理“ “ =”=”按钮按钮 / TODO: Add your control notification handler code here/ TODO: Add your control notification handler code hereCalculate();Calculate();m_operatorm_operator = = OpNoneOpNone; ;

150、/无任何操作无任何操作 void void CMyCalDlgCMyCalDlg : :OndianOndian() () /处理处理“ “ .”.”按钮按钮 / TODO: Add your control notification handler code here/ TODO: Add your control notification handler code herem_bCoffm_bCoff=1;=1;UpdateDisplayUpdateDisplay();(); 91步骤步骤5续:对控件续:对控件“-, X*X, sqrt,” 编写代编写代码码void void CMyCal

151、DlgCMyCalDlg : :OnjianOnjian()()/处理处理“ “ -”-”按钮按钮 / TODO: Add your control notification handler code here/ TODO: Add your control notification handler code hereCalculate();Calculate();m_operatorm_operator = = OpSubtractOpSubtract; ; void void CMyCalDlgCMyCalDlg : :OnpingfangOnpingfang() () /处理处理“ “

152、x*x”x*x”按钮按钮 / TODO: Add your control notification handler code here/ TODO: Add your control notification handler code herem_operandm_operand*=*=m_operandm_operand; ;UpdateDisplayUpdateDisplay();(); void void CMyCalDlgCMyCalDlg : :OnsqrtOnsqrt() () /处理处理“ “ sqrtsqrt”按钮按钮 / TODO: Add your control not

153、ification handler code here/ TODO: Add your control notification handler code herem_operandm_operand= =sqrt(m_operandsqrt(m_operand););UpdateDisplayUpdateDisplay();(); 92步骤步骤5续:对控件续:对控件“+/-,CE” 编写代码编写代码void void CMyCalDlgCMyCalDlg : :OnzhengfuOnzhengfu() () /处理处理“ “ +/-”+/-”按钮按钮 / TODO: Add your con

154、trol notification handler code here/ TODO: Add your control notification handler code herem_operandm_operand*=-1;*=-1;UpdateDisplayUpdateDisplay(); (); /成员函数处理显示成员函数处理显示(代码在后面定义)代码在后面定义) void void CMyCalDlgCMyCalDlg : :OnqinglinOnqinglin() () /处理处理“ “ CE”CE”按钮按钮 / TODO: Add your control notification

155、 handler code here/ TODO: Add your control notification handler code herem_operatorm_operator = = OpNoneOpNone; ; / / /无操作符无操作符 m_operandm_operand = 0; = 0;m_accum = 0;m_accum = 0;m_bOperandAvail = FALSE;m_bOperandAvail = FALSE;m_errorState = ErrNone; m_errorState = ErrNone; / / /无错误无错误m_coffm_coff=

156、0.1;=0.1;m_bCoffm_bCoff=0;=0;UpdateDisplayUpdateDisplay();(); 93步骤步骤5续:编写自定义函数(续:编写自定义函数(实现计算实现计算)/以下是自定义函数,用于实现计算功能,在以下是自定义函数,用于实现计算功能,在MyCalDlg.cppMyCalDlg.cpp编写代码编写代码void void CMyCalDlgCMyCalDlg : :OnOperandInput(intOnOperandInput(int a a) ) / /处理处理0-9 0-9 数字的输入函数字的输入函数数 if (if (m_errorStatem_err

157、orState != != ErrNoneErrNone) ) /判断当前运算是否有误,若有则返回判断当前运算是否有误,若有则返回return;return;if (!if (!m_bOperandAvailm_bOperandAvail) ) /判断是否输入新的数字,判断是否输入新的数字,1-1-是是 0-0-否否m_operandm_operand = 0; = 0; if(!m_bCoffif(!m_bCoff) ) /判断是否是小数输入,判断是否是小数输入,1-1-是是 0-0-否否m_operandm_operand= =m_operandm_operand*10+(*10+(a a

158、); ); elseelse m_operandm_operand= =m_operand+(m_operand+(a a)*)*m_coffm_coff; ;m_coffm_coff*=0.1;*=0.1; m_bOperandAvailm_bOperandAvail=TRUE;=TRUE;UpdateDisplayUpdateDisplay(); (); /更新显示更新显示 94步骤步骤5续:编写处理计算函数续:编写处理计算函数/处理计算函数处理计算函数void void CMyCalDlgCMyCalDlg :Calculate() :Calculate() if (if (m_erro

159、rStatem_errorState != != ErrNoneErrNone) )return;return;if (if (m_bOperandAvailm_bOperandAvail) ) /如果没有计算符就将如果没有计算符就将m_operandm_operand值值/赋予赋予m_accumm_accumif (if (m_operatorm_operator = = OpNoneOpNone) ) m_accumm_accum = = m_operandm_operand; ;else if (else if (m_operatorm_operator = = OpMultiplyOp

160、Multiply) ) /否则按计算符进行计算否则按计算符进行计算m_accumm_accum *= *= m_operandm_operand; ;else if (else if (m_operatorm_operator = = OpDivideOpDivide) ) if (if (m_operandm_operand = 0) = 0)m_errorStatem_errorState = = ErrDivideByZeroErrDivideByZero; ;elseelsem_accumm_accum /= /= m_operandm_operand; ; else if (else

161、 if (m_operatorm_operator = = OpAddOpAdd) )m_accumm_accum += += m_operandm_operand; ;else if (else if (m_operatorm_operator = = OpSubtractOpSubtract) )m_accum -= m_operand;m_accum -= m_operand; m_bOperandAvail = FALSE;m_bOperandAvail = FALSE;m_bCoffm_bCoff=0;=0;m_coffm_coff=0.1;=0.1;UpdateDisplayUpd

162、ateDisplay();(); 95步骤步骤5续:编写处理显示函数续:编写处理显示函数void void CMyCalDlgCMyCalDlg : :UpdateDisplayUpdateDisplay()() /处理显示函数处理显示函数 if (if (GetSafeHwndGetSafeHwnd() = NULL)() = NULL)return;return;if (if (m_errorStatem_errorState != != ErrNoneErrNone) )m_resultm_result=除数不能为零除数不能为零;else else /如果当前计算无错误那么进行显示如果当

163、前计算无错误那么进行显示 /如果是输入计算数,那么显示输入情况,如果按下计算符,则显示结果如果是输入计算数,那么显示输入情况,如果按下计算符,则显示结果float float lVallVal = ( = (m_bOperandAvailm_bOperandAvail) ? ) ? m_operandm_operand : : m_accumm_accum; ;m_result.Format(_T(%fm_result.Format(_T(%f), ), lVallVal); ); /将将floatfloat型转化为型转化为CStringCString型型intint i= i=m_resul

164、t.GetLengthm_result.GetLength();();while(m_result.GetAt(i-1)=0)while(m_result.GetAt(i-1)=0) m_result.Delete(i-1,1);m_result.Delete(i-1,1);i-=1;i-=1; /用编辑控件变量用编辑控件变量m_resultm_result改变编辑控件的值,更新显示改变编辑控件的值,更新显示UpdateData(FALSEUpdateData(FALSE); ); 返回返回实例实例96步骤步骤6:技术要点技术要点UpdateDataUpdateData函数函数UpdateDa

165、taUpdateData函数是函数是CDialogCDialog的基类的基类CWndCWnd的成员函数的成员函数; ;函数原型如下:函数原型如下: BOOL BOOL UpdateDataUpdateData( BOOL ( BOOL bSaveAndValidatebSaveAndValidate = TRUE ); = TRUE );一般在对话框的派生类中,利用一般在对话框的派生类中,利用UpdateDataUpdateData函数进行控件函数进行控件和相应变量之间的数据传递,形式如下:和相应变量之间的数据传递,形式如下: UpdateData(TRUEUpdateData(TRUE);

166、); /将控件中的数据传递给相应的变量将控件中的数据传递给相应的变量 UpdateData(FALSEUpdateData(FALSE) ) /将变量中的数据传递给相应的控件,即显示将变量中的数据传递给相应的控件,即显示97步骤步骤7:优化计算器程序优化计算器程序使用宏使用宏用一个消息处理函数来处理对某个用一个消息处理函数来处理对某个IDID范围内所有控件的命令响应,该范围内所有控件的命令响应,该宏的原型为:宏的原型为:ON_COMMAND_RANGE(ON_COMMAND_RANGE(ID1,ID2ID1,ID2, , memberFxnmemberFxn););其中其中ID1ID1是控件是

167、控件IDID的起始值;的起始值;ID2ID2是控件是控件IDID的结束值;的结束值;memberFxnmemberFxn为消息响应函数为消息响应函数。用用OnOperandInputOnOperandInput处理数字按钮处理数字按钮“0”“0” “9”“9”的消息响应函数的方法是:的消息响应函数的方法是:(1)(1)手工添加函数声明,也就是在手工添加函数声明,也就是在MyCalculatorDlg.hMyCalculatorDlg.h中中“AFX_MSG(CMyCalculatorDlg)”“AFX_MSG(CMyCalculatorDlg)”与与“AFX_MSG”“AFX_MSG”之间,添

168、加下面的之间,添加下面的语句:语句:afx_msgafx_msg void void OnOperandInput(UINTOnOperandInput(UINT nIDnID););(2) (2) 在在MyCalculatorDlg.cppMyCalculatorDlg.cpp文件中文件中“AFX_MSG_MAP(CMyCalculatorDlg)”AFX_MSG_MAP(CMyCalculatorDlg)”与与“AFX_MSG_MAP”“AFX_MSG_MAP”之间,加入语之间,加入语句句:ON_COMMAND_RANGE(IDC_BUTTON0,IDC_BUTTON9, ON_COMMA

169、ND_RANGE(IDC_BUTTON0,IDC_BUTTON9, OnOperandInputOnOperandInput););返回返回实例实例98实例实例6调用自定义对话框调用自定义对话框编写在文档区单击左键,则弹出输入成绩对话框,编写在文档区单击左键,则弹出输入成绩对话框,选择选择OKOK后,平均成绩和总分在文档窗口的客户区后,平均成绩和总分在文档窗口的客户区输出。输出。创建步骤:创建步骤:1.1.创建应用程序框架(基于单文档);创建应用程序框架(基于单文档);2.2.设计自定义对话框;设计自定义对话框;3.3.创建对话框类;创建对话框类;4.4.编辑自定义对话框;编辑自定义对话框;5

170、.5.调用对话框类。调用对话框类。99步骤步骤1:创建应用程序框架(基于单文档)创建应用程序框架(基于单文档)(1 1)用类向导生成)用类向导生成SDISDI应用程应用程创建工程创建工程TEST_SDITEST_SDI(单击(单击“文件文件/ /新建新建”命令命令,选定选定“单文档单文档(S S)”,单击,单击“完成完成”按钮)。按钮)。(2 2)系统生成的框架如下图:)系统生成的框架如下图:创建程序框架工作结束创建程序框架工作结束, ,运行此运行此应用程序结果如右图。应用程序结果如右图。100步骤步骤2:设计自定义对话框设计自定义对话框(1 1)选择)选择“插入插入/ /资源资源”命令;命令

171、;(2 2)在弹出)在弹出“插入资源插入资源”对话框对话框中,选定中,选定“DialogDialog”,”,然后选然后选择择“新建新建”;(3 3)在资源视图中展开)在资源视图中展开DialogDialog,可以看到新增了可以看到新增了IDID为为IDD_DIALOG1IDD_DIALOG1的资源,的资源,双击该双击该IDID,则在窗口中间显示对话框,则在窗口中间显示对话框设计界面(在此进行可视化设设计界面(在此进行可视化设计,如右图所示);计,如右图所示);(4 4)测试对话框,即选择)测试对话框,即选择“布局布局/ /测试测试”命令测试对话框,若符命令测试对话框,若符合要求,则对话框设计完

172、成。合要求,则对话框设计完成。101步骤步骤3:创建创建对话框类对话框类(1 1)双击对话框设计界面,)双击对话框设计界面,选择选择“建立类向导建立类向导”,则,则弹出弹出“Adding a ClassAdding a Class”对话框对话框; ;(2 2)选择)选择“Create a new Create a new classclass”,”,单击单击“ok”ok”按钮;按钮;(3 3)在)在“New ClassNew Class”对话对话框中输入对话框类名:框中输入对话框类名:CInputCInput, ,如图所示,对话框如图所示,对话框类创建完成。类创建完成。102步骤步骤4:编辑自

173、定义编辑自定义对话框对话框(1 1)为对话框中的)为对话框中的5 5个编辑个编辑框连接到框连接到CStingCSting类型的变类型的变量。量。(2 2)设置相关属性。)设置相关属性。控件属性控件属性控件控件ID标题标题变量类型变量类型连接变量连接变量编辑框编辑框IDC_YYIDC_YY英语英语CstringCstringm_yym_yy编辑框编辑框IDC_YWIDC_YW语文语文CstringCstringm_ywm_yw编辑框编辑框IDC_HXIDC_HX化学化学CstringCstringm_hxm_hx编辑框编辑框IDC_SXIDC_SX数学数学CstringCstringm_sxm_

174、sx编辑框编辑框IDC_WLIDC_WL物理物理CstringCstringm_wlm_wl按钮按钮IDC_OKIDC_OKOKOK静态文本框静态文本框IDC_S1IDC_S1静态文本框静态文本框IDC_S2IDC_S2静态文本框静态文本框IDC_S3IDC_S3静态文本框静态文本框IDC_S4IDC_S4静态文本框静态文本框IDC_S5IDC_S5103步骤步骤5:调用调用对话框对话框(1 1)在视图类的实现文件)在视图类的实现文件TEST_SDIView.cppTEST_SDIView.cpp中添加中添加类头文件的包含命令:类头文件的包含命令:#include #include Input

175、.hInput.h (2 2)在文档类)在文档类(TEST_SDIDocTEST_SDIDoc)中添加一)中添加一个公有的数据成员个公有的数据成员totaltotal, ,用于存放总分。用于存放总分。Public:Public:double total;double total;104步骤步骤5续续:调用对话框调用对话框_对对象进行初始化对对象进行初始化在在CTEST_SDIDoc.cppCTEST_SDIDoc.cpp文件中对文档类对象文件中对文档类对象TotalTotal进进行初始化:行初始化:total=0;total=0;105步骤步骤5续续:调用对话框调用对话框编写按压左键函数编写按

176、压左键函数OnLButtonDownOnLButtonDown()()函数函数void void CTEST_SDIView:OnLButtonDown(UINTCTEST_SDIView:OnLButtonDown(UINT nFlagsnFlags, , CPointCPoint point) point) / TODO: Add your message handler code here and/or call default/ TODO: Add your message handler code here and/or call default CTEST_SDIDocCTEST_

177、SDIDoc* * pDocpDoc= =GetDocumentGetDocument();();CInputCInput dlgdlg; ; /说明自定义对话框对象说明自定义对话框对象dlgdlgif(dlg.DoModalif(dlg.DoModal()=IDOK) ()=IDOK) / / dlg.DoModaldlg.DoModal()()显示对话框显示对话框, ,并单击并单击OKOK按钮后按钮后 pDocpDoc-total =-total =atoiatoi(dlg.m_hx(dlg.m_hx )+ )+atoi(dlg.m_sxatoi(dlg.m_sx )+ )+atoi(dl

178、g.m_wlatoi(dlg.m_wl) ) + +atoi(dlg.m_ywatoi(dlg.m_yw) +) +atoi(dlg.m_yyatoi(dlg.m_yy) ;) ;Invalidate(); Invalidate(); /使对话框无效使对话框无效 CView:OnLButtonDown(nFlagsCView:OnLButtonDown(nFlags, point);, point); 注意:注意:atoiatoi()()函数是将字符串转为整型。函数是将字符串转为整型。106步骤步骤5续续:调用对话框调用对话框编写显示函数编写显示函数OnDrawOnDraw()()函数函数vo

179、id void CTEST_SDIView:OnDraw(CDCCTEST_SDIView:OnDraw(CDC* * pDCpDC) )/OnDrawOnDraw()()是实现输出的关键函数是实现输出的关键函数/参数参数pDCpDC指向窗口中央的客户区对象指向窗口中央的客户区对象 /说明说明pDoCpDoC为一个指向为一个指向CTEST_SDIDocCTEST_SDIDoc类对象的指针类对象的指针CTEST_SDIDocCTEST_SDIDoc * * pDocpDoc = = GetDocumentGetDocument(); (); /获得指向文档类对象的指针获得指向文档类对象的指针AS

180、SERT_VALID(pDocASSERT_VALID(pDoc); ); /检查检查pDocpDoc是否有效,若有效,则结束程序是否有效,若有效,则结束程序/ TODO: add draw code for native data here/ TODO: add draw code for native data hereCStringCString strstr; ; /构造对象构造对象strstrif (if (pDocpDoc-total !=-1)-total !=-1) str.Formatstr.Format ( (平均成绩平均成绩:%.2f,pDoc-total /5);:%.

181、2f,pDoc-total /5);pDCpDC-TextOutTextOut (50,10,str); (50,10,str);str.Formatstr.Format ( (总总 分分:%.2f,pDoc-total );:%.2f,pDoc-total );pDCpDC-TextOutTextOut (50,30,str); (50,30,str); /TextOut()/TextOut()函数用于输出文字函数用于输出文字 返回返回实例实例107注意:注意:添加一个消息处理,一般要改动添加一个消息处理,一般要改动3 3个地方,以个地方,以WM_LBUTTONDOWNWM_LBUTTOND

182、OWN消息为例,消息为例,在视图类的定义在视图类的定义(test1View.h)(test1View.h)中添加一个成员函数,中添加一个成员函数,在视图类在视图类(test1View.cpp)(test1View.cpp)中添加一条消息映射,中添加一条消息映射,在视图类在视图类(test1View.cpp)(test1View.cpp)中实现消息处理的成员函数。中实现消息处理的成员函数。操作方法操作方法在在“类视图类视图”中选中中选中“Ctest1View”Ctest1View”,再在再在“属性属性”工具中选择工具中选择“WM_LBUTTONDOWN”WM_LBUTTONDOWN”消息,消息,

183、同时选上同时选上“OnLButtonDownOnLButtonDown”后回车就可以。后回车就可以。 108实例实例7 数据库编程数据库编程一般分为一般分为3 3个步骤:个步骤:(1 1)利用)利用ODBCODBC数据源管理器数据源管理器配置与数据库对应的数据源配置与数据库对应的数据源(2 2)利用)利用MFC AppWizardMFC AppWizard应用程序向导应用程序向导生成数据库应用程序框架生成数据库应用程序框架(3 3)根据需要对框架)根据需要对框架添加具体的源代码添加具体的源代码返回目录返回目录109步骤步骤1:利用:利用ODBC数据源管理器数据源管理器ODBCODBC的相关概念

184、的相关概念 数据库访问技术数据库访问技术1. ODBC ODBC API一套复杂的函数集,可提一套复杂的函数集,可提供一些通用的接口,以便供一些通用的接口,以便访问各种后台数据库。访问各种后台数据库。 MFC ODBC2. OLE DB对象链接与嵌人数据库对象链接与嵌人数据库3. ADO ActiveX数据对象数据对象三种数据库访问技术的关系图三种数据库访问技术的关系图非关系型非关系型数据库数据库ADOOLE DBODBC110步骤步骤1续:利用续:利用ODBC数据源管理器数据源管理器ODBCODBC的相关概念的相关概念MFC ODBCMFC ODBCMFC MFC 的的 ODBC ODBC

185、类对较复杂的类对较复杂的 ODBC API ODBC API 进行了封装,进行了封装, 提供简提供简化的调用接口,化的调用接口, 方便数据库应用程序的开发。方便数据库应用程序的开发。 MFC MFC 的的 ODBC ODBC 类主要包括:类主要包括: CDatabaseCDatabase 类类针对某个数据库,负责连接数据源针对某个数据库,负责连接数据源 CRecordsetCRecordset 类类针对数据源中的记录集,针对数据源中的记录集, 负责对记录的操作负责对记录的操作CRecordViewCRecordView 类类负责界面负责界面 CFieldExchangeCFieldExchan

186、ge 类类支持记录字段数据交换(支持记录字段数据交换(DFXDFX) CDBExceptionCDBException 类类代表代表ODBC ODBC 类产生的异常类产生的异常(Exception)(Exception)111步骤步骤1续:利用续:利用ODBC数据源管理器数据源管理器ODBCODBC的相关概念的相关概念ODBCODBC组成部件:组成部件: 1.应用程序应用程序2.ODBC管理器:管理器:管理安装的管理安装的ODBC驱动程序驱动程序和数据源。和数据源。 3.驱动程序管理器:驱动程序管理器:管理管理ODBC驱动程序。驱动程序。 4.ODBC API。 5.ODBC 驱动程序:驱动程

187、序:是一些是一些DLL,提供了,提供了ODBC和数据库之间的接口和数据库之间的接口。 6.数据源:数据源:包含了数据库位置和数据库包含了数据库位置和数据库类型等信息,实际上是一种类型等信息,实际上是一种数据连接的抽象。数据连接的抽象。112步骤步骤1续:利用续:利用ODBC数据源管理器数据源管理器配置与数据库对应的数据源配置与数据库对应的数据源单击单击“开始开始/ /控制面板控制面板/ /管理工管理工”,打开,打开“管理工具管理工具”窗口,窗口,双击图标双击图标在弹出的对话框中选择在弹出的对话框中选择“用户用户DSNDSN”选项卡,单击选项卡,单击“添加添加”按钮,从弹出的对话框中选中按钮,从

188、弹出的对话框中选中“Microsoft Access Microsoft Access Driver(*.Driver(*.mdbmdb)”)”;单击单击“完成完成”后,将弹出一个后,将弹出一个新的对话框,在数据源名编辑新的对话框,在数据源名编辑框中填入框中填入 “ “studentstudent” ; ” ; 连接成功后画面如图所示连接成功后画面如图所示. .113步骤步骤2:使用:使用MFC AppWizard向导向导应用向导应用向导MFC MFC AppWizard(exeAppWizard(exe) ) 制作程序框架的步骤:制作程序框架的步骤:第一步:选择程序类型第一步:选择程序类型单

189、文档应用程序单文档应用程序SDISDI(一次只允许打开一个文档)(一次只允许打开一个文档)多文档应用程序多文档应用程序MDIMDI(允许同时打开多个文档)(允许同时打开多个文档)基于对话框的应用程序基于对话框的应用程序( (不支持文档不支持文档/ /视图结构,简单对话框)视图结构,简单对话框)第二步:程序对数据库的支持第二步:程序对数据库的支持选择应用程序所需的数据库支持选择应用程序所需的数据库支持(4(4选项选项) )、默认、默认None(None(不需要不需要) )第三步:程序对第三步:程序对OLEOLE和和ActiveXActiveX控件的支持控件的支持第四步:程序外观和对通信的支持第四

190、步:程序外观和对通信的支持第五步:程序的风格、代码加注释、链接库设置第五步:程序的风格、代码加注释、链接库设置第六步:选择视类的基类第六步:选择视类的基类114步骤步骤2续:续:利用利用MFC AppWizard向导向导创建数据库应用程序创建数据库应用程序(EX88EX88)框架)框架设置工程属性设置工程属性(1 1)设置应用程序为单个文)设置应用程序为单个文档模式档模式选中选中“文档文档/ /查看结构体查看结构体系支柱系支柱”复选框复选框115步骤步骤2续:续:利用利用MFC AppWizard向导向导设置工程属性设置工程属性(2 2)选择)选择“数据库查看使用数据库查看使用文件支持文件支持

191、”单选框单选框在在“DatasouceDatasouce”区域中区域中选择选择ODBCODBC单选框,选择单选框,选择数据源;数据源;在在RecordesetRecordeset Type Type区域区域中选择中选择DynasetDynaset单选框单选框(动态集动态集)(3 3)取消选择)取消选择“ActiveXActiveX”复复选框选框(4 4)取消选择)取消选择“打印和打印打印和打印预览预览”复选框复选框(5 5)按向导提示做完)按向导提示做完动态集动态集快照快照116步骤步骤2续:续:利用利用MFC AppWizard向导向导应用程序的主画面应用程序的主画面117步骤步骤3:调试和

192、:调试和编辑框架编辑框架运行效果运行效果根据需要对框架添加具体根据需要对框架添加具体的源代码的源代码118二、学生基本信息管理系统二、学生基本信息管理系统MFCMFC创建该应用程序实例创建该应用程序实例119/64步骤步骤1:确定应用程序的基本类型确定应用程序的基本类型单文档应用程序类型单文档应用程序类型使用使用ODBCODBC建立数据连接建立数据连接记录集为记录集为“动态集动态集”120步骤步骤2:使用:使用MFC创建应用程序界面创建应用程序界面创建工程创建工程EX01DBEX01DB设置工程设置工程EX01DBEX01DB属性属性(1 1)设置应用程序为)设置应用程序为单个文档单个文档模模

193、式,选中式,选中“文档文档/ /查看结构体查看结构体系支柱系支柱”复选框复选框(2 2)选择)选择“数据库查看使用文件数据库查看使用文件支持支持”单选框,单选框,在在“DatasouceDatasouce”区域区域中选择中选择ODBCODBC单选框,选单选框,选择数据源;择数据源;在在RecordesetRecordeset Type Type区区域中选择域中选择DynasetDynaset单选单选框(框(动态集动态集)(3 3)取消选择)取消选择“ActiveX”ActiveX”复选复选框框(4 4)取消选择)取消选择“打印和打印预览打印和打印预览”复选框复选框动态集动态集快照快照121步骤

194、步骤2:使用:使用MFC创建应用程序界面创建应用程序界面此时在程序中自行生成一此时在程序中自行生成一个数据源和数据源中的一个数据源和数据源中的一个表的相关程序,其程序个表的相关程序,其程序清单如图:清单如图:class CEx88Set : public CRecordset /基于CRecordset的CEx88Set新类122运行效果运行效果MFCMFC创建应用程序创建应用程序EX01DBEX01DB的框架解释的框架解释左窗格中包含的内容左窗格中包含的内容类视图面板(系统产生类视图面板(系统产生6 6个基类)个基类)对话框类对话框类应用程序类应用程序类文档类文档类记录集类记录集类视图类视图

195、类框架窗口类框架窗口类GlobalsGlobals存放的全局变量存放的全局变量 theApptheApp说明:说明:MFC生成的应用程序界面生成的应用程序界面123说明:说明:使用使用MFC创建应用程序界面创建应用程序界面MFCMFC创建应用程序创建应用程序EX01DBEX01DB的框架解释的框架解释资源视图面板(资源视图面板(7 7个文件夹)个文件夹)Accelerator(Accelerator(加速器加速器) )包含模拟菜单和工具栏选择的键定义包含模拟菜单和工具栏选择的键定义Dialog(Dialog(对话框对话框) )包括对话框的样式和内容包括对话框的样式和内容EX01DBEX01DB

196、中只中只有有ABOUTABOUT对话框对话框Icon(Icon(图标图标) ) 描绘图标描绘图标(16x16(16x16象素和象素和32x3232x32象素象素) )Menu(Menu(菜单菜单) )描绘为应用程序的顶级菜单和关连的描绘为应用程序的顶级菜单和关连的快捷菜单快捷菜单String table(String table(字符串表字符串表) )包含字符串但不包括包含字符串但不包括C+C+源代码的部分源代码的部分Toolbar(Toolbar(工具栏工具栏) ) 描述为直接在菜单下的一行按钮描述为直接在菜单下的一行按钮Version(Version(版本信息版本信息) ) 包括程序说明包

197、括程序说明, ,版本号版本号, ,语言等等语言等等124说明:说明:使用使用MFC创建应用程序界面创建应用程序界面MFCMFC创建应用程序创建应用程序EX01DBEX01DB的框架解释的框架解释文件视图面板文件视图面板源文件夹源文件夹头文件夹头文件夹资源文件夹资源文件夹nrc里面包含的是资源里面包含的是资源n可以直接在可以直接在ide(字(字符界面的符界面的集成开发环境集成开发环境)的资源编辑器里面编辑的资源编辑器里面编辑125步骤步骤3:实现程序的显示记录的功能:实现程序的显示记录的功能在对话框编辑器中(如左在对话框编辑器中(如左图)设计自己的窗体。图)设计自己的窗体。CRecordView

198、CRecordView应用程序围绕应用程序围绕着充当应用程序主窗口的着充当应用程序主窗口的对话框而创建。对话框而创建。设计象窗体一样的对话框设计象窗体一样的对话框来显示存储在来显示存储在studentstudent数据数据库记录域中的值。如图所库记录域中的值。如图所示来示来放置静态文本框放置静态文本框与与编编辑文本框辑文本框。n注意:注意:Vc+中,使用中,使用MFC编程时不见控件工具窗口,右击编程时不见控件工具窗口,右击工具栏任一按钮工具栏任一按钮, 选选controls 126步骤步骤3:实现程序的显示记录的功能:实现程序的显示记录的功能为了实现数据传输,把每个控为了实现数据传输,把每个控

199、件与代表数据库域的件与代表数据库域的CEX88SetCEX88Set变量联系起来变量联系起来单击单击“查看查看/ /建立类向导建立类向导”菜单菜单命令,在弹出的命令,在弹出的“MFC MFC ClassWizardClassWizard ” ”对话框中选择对话框中选择成员变量选项卡;成员变量选项卡;单击单击“Add VariableAdd Variable按钮按钮”,从下拉表中直接选择相应的成从下拉表中直接选择相应的成员变量名;员变量名;全部设置好之后单击全部设置好之后单击“OK”OK”。运行应用程序运行应用程序1274.建立应用程序主窗口标题建立应用程序主窗口标题方法一:方法一: 利用利用R

200、esourceViewResourceView打开工程的资源,修改打开工程的资源,修改String String TableTable中的中的IDR_MAINFRAMEIDR_MAINFRAME的值。的值。1284.建立应用程序主窗口标题建立应用程序主窗口标题一个学生信息管理系统。一个学生信息管理系统。用的是用的是MFC ODBCMFC ODBC来完成的。在成绩管理系统中,当查来完成的。在成绩管理系统中,当查询到记录后要刷新,使所有的记录从新显示出来的话,询到记录后要刷新,使所有的记录从新显示出来的话,如果系统中存在如果系统中存在70007000条记录的话,刷新一次的时间要条记录的话,刷新一次

201、的时间要2020多秒钟多秒钟, ,处理后,可以在用户查询后,在不到一秒中处理后,可以在用户查询后,在不到一秒中的时间内来完成刷新。的时间内来完成刷新。另另: :用户名用户名:good,:good,密码密码: :pypy-a -a 1294.建立应用程序主窗口标题建立应用程序主窗口标题方法二:方法二:改变改变CSDIMainFrame的成员函数PreCreateWindow()为:为:1305.更改单文档应用程序标题更改单文档应用程序标题再再appapp类中的类中的InitInstanceInitInstance()()函数中添加下面的语句函数中添加下面的语句 m_pMainWndm_pMain

202、Wnd-SetWindowTextSetWindowText( ( 学生信息管理系统学生信息管理系统););131.更改更改MFC创建应用程序系统图标创建应用程序系统图标插入想要的图标插入想要的图标将系统生成的图标的名字将系统生成的图标的名字复制,再删除复制,再删除将自己插入的图标更名为将自己插入的图标更名为系统定义的名字即可系统定义的名字即可1327.在单文档界面上添加控件并建立关联在单文档界面上添加控件并建立关联编辑框控件编辑框控件成员变量成员变量命令按钮命令按钮建立类向导建立类向导1337.在单文档界面上添加控件并建立关联在单文档界面上添加控件并建立关联系统自动生成系统自动生成134结束

203、!谢谢!结束!谢谢!135/64ClassView类视图类视图ClassViewClassView(类视图):(类视图):显示项目中定义的显示项目中定义的C+C+类类图标的含义:图标的含义:1.管理版本信息对话框管理版本信息对话框2.管理维护应用程序的主框架管理维护应用程序的主框架3.管理维护应用程序管理维护应用程序4.管理应用程序的数据文档管理应用程序的数据文档5.管理应用程序的视图管理应用程序的视图6.Globals是存储工程的全局变是存储工程的全局变量和函数的文件夹量和函数的文件夹其中:其中:theApp为全局对象为全局对象136ResourceView资源视图资源视图ResourceV

204、iewResourceView( (资源视图资源视图) )内容内容显示项目中所包含的资显示项目中所包含的资源文件。源文件。作用管理所有:作用管理所有:菜单、图标、光标、图菜单、图标、光标、图片、对话框等资源。片、对话框等资源。137FileView文件视图文件视图显示所创建的工程显示所创建的工程主框架窗口类的源文件主框架窗口类的源文件标准标准AfxAfx(全局)源文件(全局)源文件AppApp(应用程序)类的源文件(应用程序)类的源文件应用程序的资源文件应用程序的资源文件用户文档类的源文件用户文档类的源文件用户视图类的源文件用户视图类的源文件与上述文件一一对应的头文件与上述文件一一对应的头文件

205、是你的工程要用到的头文件是你的工程要用到的头文件 1381.简单应用程序实例简单应用程序实例对话框程序对话框程序例例1 1:编写如图所示的应用程序。:编写如图所示的应用程序。创建步骤:创建步骤:1.1.建立建立基于对话框基于对话框的的MFCMFC应用程序应用程序框架;框架;2.2.放置控件;放置控件;3.3.设置控件属性;设置控件属性;4.4.为控件连接变量,即为控件命名;为控件连接变量,即为控件命名;5.5.添加并且编写消息处理函数。添加并且编写消息处理函数。139步骤步骤1:建立基于对话框的建立基于对话框的MFC应用程序框架应用程序框架1.1.单击单击“文件文件/ /新建新建”命令;命令;

206、2.2.在在“工程工程”选项卡中选项卡中, ,选定选定“MFC MFC AppWizard(exeAppWizard(exe)”,)”,输入工程名称输入工程名称TESTTEST,单击,单击“确定确定”按钮;按钮;3.3.选定选定“基本对话框(基本对话框(D D)”,即创建,即创建基于对话框的应用程序,单击基于对话框的应用程序,单击“完完成成”按钮;按钮;4.4.在随后弹出的对话框中显示了工程在随后弹出的对话框中显示了工程汇总信息,单击汇总信息,单击“确定确定”按钮。按钮。创建程序框架工作结束,创建程序框架工作结束,Developer Developer StudioStudio(开发者工作室)

207、窗口如图(开发者工作室)窗口如图所示。所示。140步骤步骤2:放置控件放置控件1.1.先删除原有控件先删除原有控件2.2.然后放置本例所需要的然后放置本例所需要的控件控件放置控件的方法放置控件的方法单击控件工具栏上的单击控件工具栏上的控件图标,选择所需控件图标,选择所需的控件,然后在对话的控件,然后在对话框设计界面上按住鼠框设计界面上按住鼠标左键拖拉出所需要标左键拖拉出所需要的大小后释放。的大小后释放。141步骤步骤3:设置控件属性设置控件属性命令按钮属性设置命令按钮属性设置(1 1)设置)设置IDcopyIDcopy属性属性(2 2)设置)设置IDendIDend属性属性编辑框编辑框IDC_

208、EDIT1IDC_EDIT1的属性的属性设置为:设置为:(1 1)选定)选定“多行多行”复选框,复选框,编辑框中可以输入多行文编辑框中可以输入多行文本;本;(2 2)选定)选定“垂直滚动垂直滚动”和和“水平滚动水平滚动”,编辑框将有,编辑框将有垂直滚动条;垂直滚动条;(3 3)选定)选定“需要返回需要返回”。用同样的方法设置编辑用同样的方法设置编辑框框IDC_EDIT2IDC_EDIT2的属性的属性142步骤步骤4:连接变量连接变量即给每一个对象连接一个变量(此变量将即给每一个对象连接一个变量(此变量将成为类中的一个数据成员)。成为类中的一个数据成员)。(1 1)为)为IDC_EDIT1IDC

209、_EDIT1连接变量连接变量m_e1m_e1在在IDC_EDIT1IDC_EDIT1编辑框的快捷菜单中选择编辑框的快捷菜单中选择“建建立类向导立类向导”( (如右图如右图) );在在“Member Variables”Member Variables”选项卡中,选定选项卡中,选定“IDC_EDIT1”IDC_EDIT1”,再选择,再选择”Add Variable”Add Variable”命令;命令;在图中所示的在图中所示的“Add Member Variable”Add Member Variable”对对话框中输入以下数据:话框中输入以下数据:Member Variable name(Me

210、mber Variable name(成员变量名成员变量名) ):m_e1m_e1; ;Category(Category(类别类别):):Control;Control;Variable type(Variable type(类型类型) ):CEditCEdit(2 2)用同样的方法为)用同样的方法为IDC_EDIT2IDC_EDIT2连接变量连接变量m_e2m_e2143步骤步骤5:添加并且编写消息处理函数添加并且编写消息处理函数在程序运行时,在在程序运行时,在“复制复制”按钮按钮上发生单击事件后,上发生单击事件后,WindowsWindows向对向对话框发出一个话框发出一个BN_CLIC

211、KEDBN_CLICKED消息,消息,CTESTDlgCTESTDlg类应有一个处理的函数。类应有一个处理的函数。(1 1)双击双击“复制复制”按钮按钮,在,在“Add Add Member Function”Member Function”对话框中输入函对话框中输入函数名(缺省函数名为数名(缺省函数名为OnButton1OnButton1), ,单击单击“OK”OK”按钮后,添加一个空函按钮后,添加一个空函数。数。(或用类向导建立)(或用类向导建立)144步骤步骤5续续: (2 2)为)为void CTESTDlg:OnButton1() void CTESTDlg:OnButton1()

212、添加代码:添加代码:(3 3)为)为void CTESTDlg:OnButton2() void CTESTDlg:OnButton2() 添加代码:添加代码:void CTESTDlg:OnButton1() / TODO: Add your control notification handler code herem_e1.SetSel(0,-1); m_e1.Copy ();m_e2.SetSel (0,-1);m_e2.Paste ();注意:输入代码时,请使用智能器注意:输入代码时,请使用智能器void CTESTDlg:OnButton2() / TODO: Add your c

213、ontrol notification handler code here OnOK();/退出对话框程序退出对话框程序145表表1 1 CEditCEdit类的常用成员函数类的常用成员函数成员函数成员函数说明说明GetSelGetSel获取文本编辑框中当前选择的起始字符和终止字符位置获取文本编辑框中当前选择的起始字符和终止字符位置ReplaceSelReplaceSel用指定文本替换文本编辑框中的当前选择用指定文本替换文本编辑框中的当前选择SetSelSetSel选择文本编辑框中的一个字符范围选择文本编辑框中的一个字符范围GetModifyGetModify确定文本编辑框中内容是否已被修改确

214、定文本编辑框中内容是否已被修改SetModifySetModify设置或清除文本框控件的修改标志设置或清除文本框控件的修改标志SetReadonlySetReadonly设置文本框控件的只读状态设置文本框控件的只读状态GetPasswordCharGetPasswordChar获取用户输入文本时在文本框控件内显示的口令字符获取用户输入文本时在文本框控件内显示的口令字符GetRectGetRect获取文本框控件的矩形获取文本框控件的矩形LimitTextLimitText限制用户可输入文本框控件的文本长度限制用户可输入文本框控件的文本长度SetPasswordCharSetPasswordCha

215、r设置或删除当用户输入文本时在文本框控件中显示的口令字符设置或删除当用户输入文本时在文本框控件中显示的口令字符UndoUndo取消上一次文本框控件操作取消上一次文本框控件操作ClearClear清除文本框控件内的当前选择清除文本框控件内的当前选择CopyCopy将文本框控件中的当前选项以将文本框控件中的当前选项以CF_TEXTCF_TEXT格式拷贝到剪贴板中格式拷贝到剪贴板中PastePaste将数据从剪贴板拷贝到文本框控件中的当前光标位置处将数据从剪贴板拷贝到文本框控件中的当前光标位置处GetLineCountGetLineCount获取多行文本框控件的行数获取多行文本框控件的行数GetLi

216、neGetLine从文本框控件内获取一行文本从文本框控件内获取一行文本返回返回实例实例146对话框中的属性中的字体大小的设置对话框中的属性中的字体大小的设置1.1.改静态文体的改静态文体的ID:IDC_STATIC1 ID:IDC_STATIC1 2.2.在在OnInitDialogOnInitDialog中添加如下代码:中添加如下代码: CFontCFont * f; * f; f = new f = new CFontCFont; ; f-CreateFont(16, / f-CreateFont(16, / nHeightnHeight0, / 0, / nWidthnWidth 0,

217、/ 0, / nEscapementnEscapement 0, / 0, / nOrientationnOrientation FW_BOLD, / FW_BOLD, / nWeightnWeight TRUE, / TRUE, /是否斜体,布尔值是否斜体,布尔值 FALSE, / FALSE, / bUnderlinebUnderline 0, / 0, / cStrikeOutcStrikeOut ANSI_CHARSET, / ANSI_CHARSET, / nCharSetnCharSet OUT_DEFAULT_PRECIS, / OUT_DEFAULT_PRECIS, /nOut

218、PrecisionnOutPrecision CLIP_DEFAULT_PRECIS, / CLIP_DEFAULT_PRECIS, / nClipPrecisionnClipPrecision DEFAULT_QUALITY, / DEFAULT_QUALITY, / nQualitynQuality DEFAULT_PITCH | FF_SWISS, / DEFAULT_PITCH | FF_SWISS, / nPitchAndFamilynPitchAndFamily _ _T(ArialT(Arial); / ); / lpszFaclpszFac GetDlgItem(IDC_SGe

219、tDlgItem(IDC_S)-)- SetFont(fSetFont(f); ); 147关闭对话框关闭对话框void CT1Dlg:OnB1() void CT1Dlg:OnB1() / TODO: Add your control notification handler code here/ TODO: Add your control notification handler code hereEndDialog(IDC_B1); EndDialog(IDC_B1); /关闭对话框关闭对话框CInputCInput dlgdlg; ; /定义对话框对象定义对话框对象dlgdlgdlg.DoModaldlg.DoModal();(); 148

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号