资源描述
,第9章Windows程序开发概述,课件制作,2,主要内容,Windows程序开发概述Win32应用程序基于MFC的Windows程序开发MFC体系结构简洁基于MFC的Windows对话框程序开发基于MFC的Windows单文档程序开发基于MFC的Windows多文档程序开发GDI+编程简介,课件制作,3,9.1Windows程序开发概述,Windows的消息处理机制消息:事件发生时所产生的信息,如鼠标单击(按下、释放)Windows消息包含程序执行过程中所发生的动作行为,如鼠标消息(移动、单击等),键盘消息(按键、释放、组合按键等)消息驱动以非顺序的方法处理事件:程序启动后就一直等待消息的发生,当某一消息发生后就对其进行相应处理消息的来源:用户输入的鼠标、键盘消息,程序自身的消息,其它程序产生的消息,操作系统产生的消息,用户发送的消息。当消息发生时,Windows就会将产生的消息分配到相关的程序中进行处理消息的处理:通过专门的消息处理函数来执行,消息处理函数通常包括消息的名称和两个附加参数(wParam,lParam),课件制作,4,9.1Windows程序开发概述,WindowsAPI简介在Windows下编程,通常要调用WindowsAPI(ApplicationProgramInterface)来实现API是提供用户程序(应用程序)与操作系统进行通信的接口层,程序需要操作系统完成某项功能时,一般需通过API调用来完成使用API的优点:当OS升级时只要新版OS提供了与旧版本兼容的API,应用程序就可以正常运行并获得新版本OS带来的好处WinMain()函数DOS下C语言程序一定都是从主函数main()开始,所有真正的Windows下的C+语言程序都是从入口函数WinMain()开始执行WinMain()函数主要用于程序初始化、显示主窗口并进入消息循环,等待发生消息并进行处理,课件制作,5,9.1Windows程序开发概述,WinMain()函数函数原型WINAPI:在windows.h头文件定义的一个宏,把函数调用翻译成正确调用的约定HINSTANCE实例句柄。句柄,是一个被用来标识应用程序或对象如窗口、菜单、设备、文件等唯一整数,也可以是一个指向对象的指针。,intWINAPIWinMain(HINSTANCEhInstance,/handletocurrentinstanceHINSTANCEhPrevInstance,/handletopreviousinstanceLPSTRlpCmdLine,/pointertocommandlineintnCmdShow/showstateofwindow);,课件制作,6,9.1Windows程序开发概述,Windows程序和Windows消息的基本流程,开始,初始化应用,初始化和创建应用窗口,进入消息循环并从消息队列得到一个消息,当前消息是否“退出”?,结束,程序是否定义了对此消息的处理,进行默认处理,处理消息,Y,N,课件制作,7,9.1Windows程序开发概述,Windows应用程序常见类型WindowsConsoleApplication(控制台应用程序,字符界面)Win32Application(基于WindowsAPI)Win32Dynamic-LinkLibraryMFCApplication基于对话框单文档应用程序多文档应用程序MFCApplicationDLL,课件制作,8,9.2Win32应用程序,Win32应用程序生成,选择Win32Application,课件制作,9,9.2Win32应用程序,Win32应用程序生成,课件制作,10,9.2Win32应用程序,Win32应用程序生成,课件制作,11,9.2Win32应用程序,Win32应用程序生成,课件制作,12,9.2Win32应用程序,Win32应用程序生成,课件制作,13,9.2Win32应用程序,Win32应用程序生成,课件制作,14,9.2Win32应用程序,Win32应用程序生成,课件制作,15,9.2Win32应用程序,Win32应用程序执行过程Windows应用程序启动时的入口函数为WinMain函数,其第一个参数为操作系统分配的应用程序实例句柄在WinMain函数中,首先调用MyRegisterClass函数注册窗口类然后调用InitInstance函数,InitInstance函数将实例句柄保存在一个全局变量中,并调用CreateWindow函数创建程序主窗口,调用ShowWindow函数显示程序主窗口以及调用UpdateWindow函数更新程序主窗口最后进入由GetMessage函数、TranslateMessage函数和DispatchMessage函数组成的消息循环,DispatchMessage函数将消息发送给窗口过程,课件制作,16,9.2Win32应用程序,Win32应用程序执行过程由WndProc窗口过程函数处理各种Windows消息,完成Windows应用程序所要完成的功能当GetMessage函数捕获到WM_QUIT消息之后返回FALSE,于是消息循环终止,WinMain函数返回,程序执行结束,课件制作,17,9.2Win32应用程序,窗口的创建与显示窗口结构的定义,typedefstruct_WNDCLASSEXUINTcbSize;UINTstyle;/窗口风格WNDPROClpfnWndProc;/指定在窗口产生消息时调用的消息处理函数intcbClsExtra;intcbWndExtra;HANDLEhInstance;/指定义窗口应用程序的句柄HICONhIcon;/程序图标HCURSORhCursor;/鼠标样式HBRUSHhbrBackground;/设置窗口背景色LPCTSTRlpszMenuName;/设置窗口菜单LPCTSTRlpszClassName;/设置窗口类名HICONhIconSm;WNDCLASSEX;,课件制作,18,9.2Win32应用程序,窗口的创建与显示窗口结构的定义,WNDCLASSEXwcex;wcex.cbSize=sizeof(WNDCLASSEX);wcex.style=CS_HREDRAW|CS_VREDRAW;wcex.lpfnWndProc=(WNDPROC)WndProc;wcex.cbClsExtra=0;wcex.cbWndExtra=0;wcex.hInstance=hInstance;wcex.hIcon=LoadIcon(hInstance,(LPCTSTR)IDI_MYWIN32APP);wcex.hCursor=LoadCursor(NULL,IDC_ARROW);wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName=(LPCSTR)IDC_MYWIN32APP;wcex.lpszClassName=szWindowClass;/MyWin32Appwcex.hIconSm=LoadIcon(wcex.hInstance,(LPCTSTR)IDI_SMALL);,课件制作,19,9.2Win32应用程序,窗口的创建与显示窗口注册RegisterClassEx(创建窗口,HWNDCreateWindowEx(DWORDdwExStyle,/extendedwindowstyleLPCTSTRlpClassName,/pointertoregisteredclassnameLPCTSTRlpWindowName,/pointertowindownameDWORDdwStyle,/windowstyleintx,/horizontalpositionofwindowinty,/verticalpositionofwindowintnWidth,/windowwidthintnHeight,/windowheightHWNDhWndParent,/handletoparentorownerwindowHMENUhMenu,/handletomenu,orchild-windowidentifierHINSTANCEhInstance,/handletoapplicationinstanceLPVOIDlpParam/pointertowindow-creationdata);,课件制作,20,9.2Win32应用程序,窗口的创建与显示创建窗口,课件制作,21,9.2Win32应用程序,窗口的创建与显示创建窗口,课件制作,22,9.2Win32应用程序,窗口的创建与显示创建窗口,课件制作,23,9.2Win32应用程序,窗口的创建与显示创建窗口,课件制作,24,9.2Win32应用程序,窗口的创建与显示创建窗口,hInst=hInstance;/StoreinstancehandleinourglobalvariablehWnd=CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);if(!hWnd)returnFALSE;,课件制作,25,9.2Win32应用程序,窗口的创建与显示窗口的显示与更新,TheShowWindowfunctionsetsthespecifiedwindowsshowstate.BOOLShowWindow(HWNDhWnd,/handletowindowintnCmdShow/showstateofwindow);,BOOLUpdateWindow(HWNDhWnd/handleofwindow);,ShowWindow(hWnd,nCmdShow);UpdateWindow(hWnd);,课件制作,26,9.2Win32应用程序,消息循环GetMessage()TranslateMessage()DispatchMessage(),BOOLGetMessage(LPMSGlpMsg,/addressofstructurewithmessageHWNDhWnd,/handleofwindowUINTwMsgFilterMin,/firstmessageUINTwMsgFilterMax/lastmessage);,BOOLTranslateMessage(CONSTMSG*lpMsg/addressofstructurewithmessage);,LONGDispatchMessage(CONSTMSG*lpmsg/pointertostructurewithmessage);,课件制作,27,9.2Win32应用程序,消息循环PeekMessage()PostMessage(),BOOLPeekMessage(LPMSGlpMsg,/pointertostructureformessageHWNDhWnd,/handletowindowUINTwMsgFilterMin,/firstmessageUINTwMsgFilterMax,/lastmessageUINTwRemoveMsg/removalflags);,BOOLPostMessage(HWNDhWnd,/handleofdestinationwindowUINTMsg,/messagetopostWPARAMwParam,/firstmessageparameterLPARAMlParam/secondmessageparameter);,课件制作,28,9.2Win32应用程序,消息循环SendMessage()消息结构,LRESULTSendMessage(HWNDhWnd,/handleofdestinationwindowUINTMsg,/messagetosendWPARAMwParam,/firstmessageparameterLPARAMlParam/secondmessageparameter);,typedefstructtagMSG/msgHWNDhwnd;UINTmessage;WPARAMwParam;LPARAMlParam;DWORDtime;POINTpt;MSG;,typedefstructtagPOINTLONGx;LONGy;POINT;,课件制作,29,9.2Win32应用程序,消息处理消息处理函数常用Windows消息,LRESULTCALLBACKWndProc(HWNDhwnd,/handletowindowUINTuMsg,/messageidentifierWPARAMwParam,/firstmessageparameterLPARAMlParam/secondmessageparameter);,KeyboardInputMessagesThefollowingmessagesareusedtoreceiveandprocesskeyboardinput.WM_ACTIVATEWM_CHARWM_DEADCHARWM_GETHOTKEYWM_HOTKEYWM_KEYDOWNWM_KEYUPWM_KILLFOCUSWM_SETFOCUSWM_SETHOTKEYWM_SYSCHARWM_SYSDEADCHARWM_SYSKEYDOWNWM_SYSKEYUP,课件制作,30,9.2Win32应用程序,消息处理常用Windows消息,MouseInputMessagesThefollowingmessagesareusedwithmouseinput.WM_CAPTURECHANGEDWM_LBUTTONDBLCLKWM_LBUTTONDOWNWM_LBUTTONUPWM_MBUTTONDBLCLKWM_MBUTTONDOWNWM_MBUTTONUPWM_MOUSEACTIVATEWM_MOUSEMOVEWM_MOUSEWHEELWM_NCHITTESTWM_NCLBUTTONDBLCLKWM_NCLBUTTONDOWNWM_NCLBUTTONUPWM_NCMBUTTONDBLCLKWM_NCMBUTTONDOWNWM_NCMBUTTONUPWM_NCMOUSEMOVEWM_NCRBUTTONDBLCLKWM_NCRBUTTONDOWNWM_NCRBUTTONUPWM_RBUTTONDBLCLKWM_RBUTTONDOWNWM_RBUTTONUP,课件制作,31,9.2Win32应用程序,消息处理常用Windows消息,WindowMessagesThefollowingmessagesareusedtocreateandmanagewindows.WM_ACTIVATEWM_ACTIVATEAPPWM_CANCELMODEWM_CHILDACTIVATEWM_CLOSEWM_COMPACTINGWM_CREATEWM_DESTROYWM_ENABLEWM_ENTERSIZEMOVEWM_EXITSIZEMOVEWM_GETICONWM_GETMINMAXINFOWM_GETTEXTWM_GETTEXTLENGTHWM_INPUTLANGCHANGEWM_INPUTLANGCHANGEREQUESTWM_MOVEWM_MOVINGWM_NCACTIVATEWM_NCCALCSIZEWM_NCCREATEWM_NCDESTROYWM_PARENTNOTIFYWM_QUERYDRAGICONWM_QUERYOPENWM_QUITWM_SETICONWM_SETTEXTWM_SETTINGCHANGEWM_SHOWWINDOWWM_SIZEWM_SIZINGWM_STYLECHANGEDWM_STYLECHANGINGWM_USERCHANGEDWM_WINDOWPOSCHANGEDWM_WINDOWPOSCHANGINGWM_WININICHANGE,课件制作,32,9.2Win32应用程序,消息处理Windows消息处理示例,switch(message)caseWM_COMMAND:wmId=LOWORD(wParam);wmEvent=HIWORD(wParam);/Parsethemenuselections:switch(wmId)caseIDM_ABOUT:DialogBox(hInst,(LPCTSTR)IDD_ABOUTBOX,hWnd,(DLGPROC)About);break;caseIDM_EXIT:DestroyWindow(hWnd);break;default:returnDefWindowProc(hWnd,message,wParam,lParam);break;,课件制作,33,9.2Win32应用程序,消息处理Windows消息处理示例,switch(message)caseWM_PAINT:hdc=BeginPaint(hWnd,课件制作,34,9.2Win32应用程序,Win32应用程序运行机制,鼠标/键盘消息,WinMain()WNDCLASSwcAppRegisterClass();CreateWindow();ShowWindow();UpdateWindow();while(GetMessage(,WndProc()switch(msg)returnDefWindowProc();返回,应用程序自身或其它程序产生的消息,程序消息队列,系统消息队列,提取消息,发送消息,课件制作,35,9.2Win32应用程序,消息提示对话框,intMessageBox(HWNDhWnd,/handleofownerwindowLPCTSTRlpText,/addressoftextinmessageboxLPCTSTRlpCaption,/addressoftitleofmessageboxUINTuType/styleofmessagebox);intAfxMessageBox(LPCTSTRlpszText,UINTnType=MB_OK,UINTnIDHelp=0);,课件制作,36,9.2Win32应用程序,消息提示对话框,课件制作,37,9.2Win32应用程序,Windows应用程序中的命名法匈牙利命名法:一种编程时的命名规范,其基本原则是在命名标志符时,要选择易读的标志符名称可以适当采用英文缩写,如szAppTitle,wMsgFilterMin可读性比简洁性更重要最好不要使用下划线、连字符或任何其他非字母数字字符,不要使用中文标志长度要适宜,不要过长不要出现局部变量与全局变量同名的情况表示常量或宏定义的标志符用大写字母表示,以表示与普通标志符的区别,变量名:=属性前缀+类型+对象描述,课件制作,38,9.2Win32应用程序,Windows应用程序中的命名法范围前缀,课件制作,39,9.2Win32应用程序,Windows应用程序中的命名法常用的一般数据类型前缀,课件制作,40,9.2Win32应用程序,Windows应用程序中的命名法常用的一般数据类型前缀,课件制作,41,9.2Win32应用程序,Windows应用程序中的命名法常用Windows对象名称缩写,课件制作,42,9.2Win32应用程序,Windows应用程序中的命名法常用宏定义命名常用数据类型,课件制作,43,9.2Win32应用程序,Windows应用程序中的命名法常用数据类型,课件制作,44,9.2Win32应用程序,Windows应用程序中的命名法常用数据类型,课件制作,45,9.2Win32应用程序,Win32应用程序实例分析Win32应用程序的使用实时性要求较高场合,如游戏,工业数据采集与控制系统设备驱动程序Win32应用程序的缺点编写复杂,复用性较弱不适合大型应用系统,课件制作,46,9.3基于MFC的Windows程序开发,MFC体系结构基本概念MFC封装了Win32API,目前已包括有200多个类。MFC是一个类层次体系,基类是CObject,其他类大部分是采用单重继承从该类直接或间接派生而来常用的以CObject为基类的类层次结构,课件制作,47,9.3基于MFC的Windows程序开发,MFC体系结构常用的以CObject为基类的类层次结构,课件制作,48,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序MFC应用程序框架分类基于对话框的应用程序单文档界面应用程序(简称SDI)多文档界面应用程序(简称MDI)基于对话框的应用程序,CH9_2:实现如左图所示的对话框应用程序,CDialogCFileDialogCEditCButtonCFileCStringAfxMessageBox,课件制作,49,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序基于文档/视图结构的应用程序框架,CH9_3:实现如左图所示的文档/视图结构应用程序的用户界面,课件制作,50,9.3基于MFC的Windows程序开发,MFC体系结构部分CObject派生类的功能CCmdTarget:封装了MFC的消息映射机制,是MFC类库中消息映射体系的基类,希望接收系统事件和窗口消息的类都从它派生CWinThread:该类的一个对象代表应用程序的一个执行线程,主线程通常由CWinThread的派生类CWinApp的对象提供CWinApp:派生Windows应用程序对象的基类CWnd:对创建、操纵窗口类的API函数进行了封装,提供了MFC中所有窗口类的基本功能CFrameWnd:SDI应用程序的主框架窗口的基类,也是所有其他框架窗口类的基类CDocument:应用程序文档的基类CView:应用程序视图的基类,课件制作,51,9.3基于MFC的Windows程序开发,MFC体系结构部分CObject派生类的功能CDialog:所有对话框(模态或者非模态)的基类CFile:提供二进制磁盘文件的访问接口CDC:设备上下文类的基类,封装了绘图的所有功能函数CException:所有异常的基类,用于处理各种异常用MFCAppwizard自动生成Windows程序应用程序框架通常是指一个完整的程序模型,具备标准应用软件所需的一切基本功能,如文件存取、打印预览等,以及这些功能的使用接口,如工具栏、状态栏、菜单等提供一个一般应用程序所需要的全部面向对象软件组件的集合,课件制作,52,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序SDI应用程序的组成:一个典型的SDI应用程序一般由四个类组成主框架窗口类(CMainFrame)由AppWizard自动添加基类是CFrameWnd,框架类负责管理程序的主窗口,包含窗口边框、标题栏、菜单栏、系统菜单栏、工具栏、状态栏等各种元素。类的定义和实现文件分别是MainFrm.h和MainFrm.cpp应用程序类(CMFCDemoSDIApp)基类是CWinApp,应用程序类是应用程序运行的基础,用来管理整个应用程序,封装了Windows应用程序要做的初始化、运行和终止三大主要任务。该类的定义和实现文件分别是MFCDemoSDI.h和MFCDemoSDI.cpp。基类是CWinApp,应用程序类是应用程序运行的基础,用来管理整个应用程序,封装了Windows应用程序要做的初始化、运行和终止三大主要任务。该类的定义和实现文件分别是MFCDemoSDI.h和MFCDemoSDI.cpp。,课件制作,53,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序SDI应用程序的组成:一个典型的SDI应用程序一般由四个类组成文档类(CMFCDemoSDIDoc)基类是CDocument,文档类封装了应用程序的数据管理功能,负责存放程序数据、读出数据并进行I/O操作。该类的定义和实现文件分别是MFCDemoSDIDoc.h和MFCDemoSDIDoc.cpp。视图类(CMFCDemoSDIView)基类是CView,视图类负责管理视图窗口,显示程序中的数据和处理用户输入,而数据是从文档类中获得,视图窗口是框架窗口的子窗口,显示在主框架窗口的客户区中。该类的定义和实现文件分别是MFCDemoSDIView.h和MFCDemoSDIView.cpp。,课件制作,54,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序MDI应用程序在MDI应用程序中,除了具有SDI应用程序中的四个类外,还包括子框架窗口类主框架窗口类的基类为CMDIFrameWnd类,子框架窗口(文档框架窗口)类的基类为CMDIChildWnd类,课件制作,55,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序工程文件的组成文件夹Debug:用于存放编译、链接时产生的中间文件和可执行文件Res:用于存放工程的资源文件工程文件(以C:TempMFCDemoSDI为例)MFCDemoSDI.dsw:工作区文件,保存了工程所属的工作区信息MFCDemoSDI.dsp:工程文件,保存了用户所建工程的有关信息MFCDemoSDI.opt:工作区选项文件,保存了用户为所建工作区所定制的一些选项,当每次打开该工作区时可自动设置用户定制的选项状态MFCDemoSDI.clw:为ClassWizard数据库文件,存放由ClassWizard使用的信息,Wizard还使用这个文件来存储信息,以便创建和编辑消息映射、对话框数据映射、以及创建成员函数的原型,课件制作,56,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序工程文件的组成工程文件(以C:TempMFCDemoSDI为例)MFCDemoSDI.ncb:非编译的浏览文件,包含了由分析器产生的一些信息,可被ClassView、WizardBar和ComponentGallery利用预编译头文件:StdAfx.h和StdAfx.cpp,这两个文件用来产生预编译头文件MFCDemoSDI.pch和一个OBJ文件StdAfx.obj资源文件MFCDemoSDI.rc和Resource.h:包含了一般MFC应用程序用到的所有资源,如菜单、加速键、字符串表以及About对话框、图标文件、位图文件resMFCDemoSDI.rc2:包含VisualC+不能直接编辑的资源,可以将所有不能由资源编辑器编辑的资源放置到这个文件中resMFCDemoSDI.ico:图标文件resToolbar.bmp:用于创建工具栏按钮的位图文件,课件制作,57,9.3基于MFC的Windows程序开发,用MFCAppwizard自动生成Windows程序工程文件的组成帮助文件:若用户在MFCAppWizard-Step4of6对话框中选择了“提供上下文相关帮助”,则会在工程目录上生成一个hlp子目录,并产生一系列所需帮助文件,课件制作,58,9.3基于MFC的Windows程序开发,MFC消息映射应用程序模式过程控制模式在MS-DOS的控制台应用程序中,main函数是程序的入口,按照程序语句的执行流程来控制程序代码的执行执行的顺序和方式是在编写程序时设置好的,这种程序模式称为过程控制模式事件驱动模式:Windows程序的控制流程不再由事件的预定发生顺序来决定,而是由实际运行时各种事件的实际发生来触发Windows消息机制Windows消息分类标准Windows消息:以WM_为前缀的消息(除WM_COMMAND)控件通知消息:以WM_COMMAND为消息名,由编辑框、列表框等控件或子窗口发给其父窗口的通知消息,课件制作,59,9.3基于MFC的Windows程序开发,MFC消息映射Windows消息机制Windows消息分类命令消息:当用户选择菜单、工具栏、加速键时产生的消息,也以WM_COMMAND为消息名,在消息中包含有命令的标识符(ID),以区分具体的命令MSG结构体,typedefstructtagMSGHWNDhwnd;/接收消息的窗口句柄UINTmessage;/消息类型WPARAMwParam;LPARAMlParam;/消息的附加信息DWORDtime;/消息发送时间POINTpt;/消息发送时光标在屏幕上的位置MSG;,课件制作,60,9.3基于MFC的Windows程序开发,MFC消息映射Windows消息机制消息队列系统消息队列应用程序(消息)队列窗口过程每个窗口会有一个称为窗口过程(WndProc)的回调函数,它带有四个参数:窗口句柄,消息ID,和两个消息参数(wParam,lParam)当窗口收到消息时系统就会调用此窗口过程来处理消息,即消息响应任何一个窗口类都有一个窗口过程,同一个类的窗口使用同样的窗口过程来响应消息Windows消息从产生到响应处理的过程,课件制作,61,9.3基于MFC的Windows程序开发,系统或外部输入,Windows系统消息队列,应用程序1,消息队列,应用程序m,消息队列,窗口1的窗口过程,窗口n的窗口过程,将事件转换为消息,.,.,控件1,控件k,.,应用程序1,WinMain函数,消息循环,课件制作,62,9.3基于MFC的Windows程序开发,MFC消息映射Windows消息机制Windows消息从产生到响应处理的过程MFC消息映射机制MFC把所有图形用户界面元素(如对话框、按钮、编辑框和菜单等)以类的方式封装,使用消息映射宏将这些图形用户界面元素所发出的消息“映射”到消息处理函数进行处理,while(GetMessage(,课件制作,63,9.3基于MFC的Windows程序开发,MFC消息映射MFC消息映射机制消息处理函数是以CCmdTarget为基类的派生类成员函数,CCmdTarget类是MFC处理命令消息的基础和核心在VC+中建立消息映射必须遵循的规范声明消息处理函数首先,在需要进行消息处理的类定义头文件中,在成员定义末尾加入DECLARE_MESSAGE_MAP宏,其语法格式如下:DECLARE_MESSAGE_MAP()其次,在需要进行消息处理的类的定义中声明消息处理函数,其语法格式如下:/AFX_MSG(子类名)afx_msg类型函数名(形参表);/AFX_MSG,课件制作,64,9.3基于MFC的Windows程序开发,MFC消息映射MFC消息映射机制在VC+中建立消息映射必须遵循的规范建立消息与处理函数之间的映射在需要进行消息处理的类的实现文件中加入如下代码添加消息处理函数:在需要进行消息处理的类的实现文件中添加消息处理函数,其语法格式如下,BEGIN_MESSAGE_MAP(子类名,父类名)/消息映射宏定义或消息映射语句,一般有若干个ON_COMMAND.(消息名或控制号,处理函数名)ON_WM_END_MESSAGE_MAP(),类型类名:处理函数名(形参表)/处理代码,消息映射的这三项内容既可手工加入,也可以使用ClassWizard工具ClassWizard为消息处理程序自动生成函数原型和空的函数定义,用户需要根据实际功能添加具体的消息处理函数体代码,课件制作,65,9.3基于MFC的Windows程序开发,MFC消息映射MFC命令消息的传递机制命令消息在应用程序类、文档类、视图类、以及框架窗口类中都可以进行处理当产生一个命令消息时,该消息的接收和处理对象有不同的优先级的,消息是按一定的路径进行传递的,例CH9_3:在上述MFCDemoSDI工程添加菜单项“测试”,并分别在视图类、文档类、框架类和应用程序类中为其添加消息映射,然后测试消息对视图对象、文档对象、框架对象和应用程序对象的响应优先级,MainFrameViewDocApp,课件制作,66,9.3基于MFC的Windows程序开发,MFC消息映射MFC命令消息的传递机制命令消息的处理过程,开始,主,/,子框架窗口对象,活动视图对象,找到消息处理函数,文档对象,Y,处理命令消息,搜索视图消息映射表,搜索主,/,子框架窗,口消息映射表,命令消息,找到消息处理函数,搜索文档消,息映射表,Y,N,N,找到消息处理函数,Y,N,由应用程序对,象处理消息,结束,课件制作,67,9.3基于MFC的Windows程序开发,MFC消息映射MFC命令消息的传递机制命令消息的处理过程用户消息(鼠标、键盘输入等)会先发往主框架窗口对象(对于MDI应用程序,会再将消息的处理机会传递给当前活动的MDI子框架窗口)主/子框架窗口对象则将消息传递给当前活动视图对象视图对象先搜索自己的消息映射,如果没有找到该消息的处理函数,则将消息传递给与此视图关联的文档对象如果文档对象也没有处理该消息则又将消息传递给文档模板对象如果在文档模板对象中也没有找到该消息的处理函数,则消息又被传回主/子框架窗口对象主/子框架窗口对象搜索自己的消息映射(对于MDI应用程序,如果子框架窗口中没有处理函数,命令消息就被传回给主框架窗口),如果找到就进行处理如果在主框架窗口对象没有处理该消息,则由应用程序对象来处理未被处理的命令消息,课件制作,68,9.3基于MFC的Windows程序开发,使用ClassWizard工具打开ClassWizard工具主要功能使用ClassWizard进行消息映射使用ClassWizard添加类使用ClassWizard添加成员变量覆盖基类虚成员函数编程演示使用ClassWizard进行消息映射使用ClassWizard添加类(插入对话框资源),需要删除某个消息映射函数,需要首先用ClassWizard工具删除消息映射入口项和消息处理成员函数的函数原型,然后在该消息映射函数所在的实现文件(.cpp)中手动删除该消息处理成员函数的定义代码,课件制作,69,9.3基于MFC的Windows程序开发,使用ClassWizard工具编程演示使用ClassWizard添加成员变量利用ClassWizard可以方便地向类中添加成员变量,并将这些成员变量与对话框或窗口中的控件关联起来,当控件的值改变时,所对应的成员变量的值也跟着发生变化演示:向CLoginDialog类中添加成员变量,使它们与相应的控件相关联,例CH9_4:完成登录对话框,要求在主界面显示之前弹出一个登录对话框,由用户输入用户名和密码,如果输入正确,则程序继续执行,否则程序终止,课件制作,70,9.3基于MFC的Windows程序开发,使用ClassWizard工具编程演示覆盖基类虚成员函数在MFC类库中,很多成员函数在声明时都有virtual关键字,即它们都是虚成员函数当创建基于MFC的应用程序时,在用户的派生类中往往需要重新定义基类的虚成员函数,这样当通过基类对象指针(或引用)调用虚成员函数时,可以实现运行时的多态性说明在MFCDemoSDIDoc.h中可以看到该虚成员函数的声明在MFCDemoSDIDoc.cpp中可以看到该虚成员函数的定义Serialize函数用来实现文件的串行化操作,例CH9_5:在完成的MFCDemoSDI工程的文档类CMFCDemoSDIDoc中添加Serialize成员函数,从而覆盖基类CDocument中定义的Serialize虚成员函数,课件制作,71,9.3基于MFC的Windows程序开发,使用ClassWizard工具编程演示覆盖基类虚成员函数说明当用户选择了“打开”、“保存”或“另存为”命令,程序框架为这个文件创建CFile对象,关联到新创建的CArchive对象上,并设置CArchive对象的“store”或“load”标记,用这个CArchive对象来调用CDocument派生类的Serialize成员函数在Serialize函数完成读写操作返回后,自动删除CArchive和CFile对象,课件制作,72,9.3基于MFC的Windows程序开发,文档/视图结构在MFCAppWizard-Step1向导对话框中,当选择SDI或MDI应用程序时,系统默认选择支持文档/视图结构当选择基于对话框的应用程序时,“文档/视图结构支持”复选框是被禁用的,即此时系统不支持文档/视图结构文档是用来保存数据以及关于数据的处理的,每当MFCSDI/MDI响应“File|Open”或“File|New”菜单命令的时候,都会打开一份文档视图在Windows中是一个从CView类派生出来的窗口,也是一个可视化的矩形区域视图用来表示文档的数据,文档的内容通过视图窗口显示给用户,这种文档和视图的结合,称为“文档/视图结构”,课件制作,73,9.3基于MFC的Windows程序开发,文档/视图结构每个视图必须依附于一个框架(在SDI中依附于MainFrame,在MDI中依附于ChildFrame)框架是一个Windows窗口,但是在框架上可以放置菜单、工具栏、状态栏等,视图放在框架的客户区文档与视图的关系如下图,课件制作,74,9.3基于MFC的Windows程序开发,文档/视图结构文档模板类(CDocTemplate)作用:在MFC中,一个应用程序的主线由应用类体现,而应用类又通过文档模板类在运行时动态创建和管理文档类、视图类和框架窗口类,将它们组成一个有机的整体,共同完成程序的任务是一个抽象基类,它定义了文档模板的基本处理函数(或称接口),用于支持文档模板操作CDocTemplate类有两个派生类CSingleDocTemplate:用于SDI程序CMultipleDocTemplate:用于MDI程序这三个类的声明在“afxwin.h”文件中,课件制作,75,9.3基于MFC的Windows程序开发,文档/视图结构文档模板类(CDocTemplate)在SDI程序中文档模板类的使用(以S1工程为例)在CS1App的InitInstance函数中,CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,/指定这个文档显示时候采用的菜单资源RUNTIME_CLASS(CS1Doc),RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CS1View);AddDocTemplate(pDocTemplate);,课件制作,76,9.3基于MFC的Windows程序开发,文档/视图结构文档模板类(CDocTemplate)在MDI程序中文档模板类的使用(以MFCDemoSDI工程为例)在CMFCDemoSDIApp的InitInstance函数中,CMultiDocTemplate*pDocTemplate;pDocTemplate=newCMultiDocTemplate(IDR_S1TYPE,/同上RUNTIME_CLASS(CS1Doc),RUNTIME_CLASS(CChildFrame),RUNTIME_CLASS(CS1View);AddDocTemplate(pDocTemplate);,课件制作,77,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)是所有文档类的基类,它对文档的建立及归档提供支持,并提供了应用程序用于控制其数据的接口该类的定义在“afxwin.h”文件中文档类的主要成员函数添加视图成员函数:voidAddView(CView*pView)将一个视图连接到文档上,并将视图的文档指针指向该文档一个文档可以有多个视图,每个文档都维护一个链表来管理与之关联的视图,该链表在CDocument类中的定义为:CPtrListm_viewList删除视图成员函数:voidRemoveView(CView*pView)创建文档成员函数:virtualBOOLOnNewDocument();当用户启动应用程序,或选择“File|New”菜单时,会触发该函数的执行,课件制作,78,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)文档类的主要成员函数打开文档成员函数:virtualBOOLOnOpenDocument(LPCTSTRlpszPathName)保存文档成员函数:virtualBOOLOnSaveDocument(LPCTSTRlpszPathName)关闭文档成员函数:virtualvoidOnCloseDocument(),例CH9_6:在完成的MFCDemoSDI工程中,实现在客户区单击鼠标左键连线绘图,提供绘图文件的保存和打开功能,(1)在CMFCDemoSDIDoc类中添加如下公有成员变量:intm_nCount;/记录当前点的个数CPointm_ptPosition90;/记录点的坐标(2)完成成员变量的初始化:CMFCDemoSDIDoc:CMFCDemoSDIDoc()/TODO:addone-timeconstructioncodeherem_nCount=0;for(inti=0;im_nCountm_ptPositionpDoc-m_nCount=point;/保存当前鼠标点击位置pDoc-m_nCount+;/将点的个数进行累加Invalidate();/刷新屏幕CView:OnLButtonDown(nFlags,point);,课件制作,80,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument),例CH9_6:在完成的MFCDemoSDI工程中,实现在客户区单击鼠标左键连线绘图,提供绘图文件的保存和打开功能,说明:Invalidate()是使视图类窗口无效(即需要重绘)的函数,它有一个默认的参数TRUE,即Invalidate(TRUE)该函数会产生一个WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint函数负责重绘窗口在视图类的OnPaint函数中调用了OnDraw函数(5)修改CMFCDemoSDIView:OnDraw函数,对鼠标单击过的点进行连线绘图:,voidCS1View:OnDraw(CDC*pDC)CMFCDemoSDIDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);/TODO:adddrawcodefornativedataherepDC-MoveTo(pDoc-m_ptPosition0);for(inti=1;im_nCount;i+)pDC-LineTo(pDoc-m_ptPositioni);,课件制作,81,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument),例CH9_6:在完成的MFCDemoSDI工程中,实现在客户区单击鼠标左键连线绘图,提供绘图文件的保存和打开功能,(6)运行MFCDemoSDI工程在视图区连续单击鼠标左键可绘成连线,但不能保存当前绘图文件为了能保存绘制结果,需要对文档类的成员变量m_nCount和m_ptPosition90进行序列化处理(7)修改CMFCDemoSDIDoc:Serialize函数voidCMFCDemoSDIDoc:Serialize(CArchive,课件制作,82,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)MFC对象序列化机制对象的序列化:将对象当前状态(通常由该对象的成员变量指示)写入永久性存储介质(如磁盘文件),或从永久性存储介质中读取对象状态恢复到内存的过程称为对象的序列化对象的持久性对象所具有的保存和加载其状态数据的能力称为对象的持久性持久性对象能够在应用程序结束之前以某种方式将当前的对象状态数据记录下来,当程序再次运行时,通过对这些数据的读取而恢复到上一次任务结束时的状态CArchiveCArchive类的对象用作将被序列化的对象和存储介质之间的中介物当进行打开/保存文件操作时,系统会构造一个CArchive对象,并将其与一个打开文件的CFile对象相关联,从CFile对象获得序列化所需的信息,包括文件名和请求的操作是读取还是写入,课件制作,83,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)MFC对象序列化机制CArchive然后这个CArchive对象会调用CDocument派生类的Serialize成员函数,在Serialize函数完成读写操作后,自动删除CArchive对象和CFile对象MFC对CObject派生类的序列化提供内置支持,CObject派生类可以重载CObject:Serialize函数实现序列化操作,即所有的CObject派生类都是具有持久性的使一个类可序列化需要完成如下五个步骤该类直接或间接从CObject类派生在该类中重载Serialize成员函数在该类声明文件中使用DECLARE_SERIAL宏,该宏只需要将类名作为参数,课件制作,84,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)MFC对象序列化机制使一个类可序列化需要完成如下五个步骤在该类中定义一个无参构造函数。若一个对象来自文件,MFC必须以无参构造函数动态创建它,然后从文件中读取对象的状态数据在该类实现文件中使用IMPLEMENT_SERIAL宏。该宏需要三个参数:类名,基类名和一个方案号。其中方案号是一个相当于版本号的整数,每当改变了类的序列化数据格式后就应当及时更改此数值,例CH9_7:对绘图数据进行封装,创建可序列化类CCurve,实现绘图数据的持久性,课件制作,85,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)MFC对象序列化机制,创建“curve.h”文件,定义CCurve类来封装曲线位置数据classCCurve:publicCObjectDECLARE_SERIAL(CCurve)public:intm_nCount;CPointm_ptPosition90;public:CCurve();virtualCCurve()voidSerialize(CArchive,课件制作,86,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)MFC对象序列化机制,(2)创建“curve.cpp”文件,在CCurve类的构造函数中进行数据的初始化#includeCurve.hIMPLEMENT_SERIAL(CCurve,CObject,0)CCurve:CCurve()m_nCount=0;for(inti=0;im_pCur-m_ptPositionpDoc-m_pCur-m_nCount=point;if(pDoc-m_pCur-m_nCountm_pCur-m_nCount+;Invalidate();/刷新屏幕CView:OnLButtonDown(nFlags,point);,课件制作,90,9.3基于MFC的Windows程序开发,文档/视图结构文档类(CDocument)MFC对象序列化机制,(8)修改重绘函数为voidCMFCDemoSDIView:OnDraw(CDC*pDC)CMFCDemoSDIDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);/TODO:ad
展开阅读全文