MFC基本应用程序的建立.ppt_第1页
MFC基本应用程序的建立.ppt_第2页
MFC基本应用程序的建立.ppt_第3页
MFC基本应用程序的建立.ppt_第4页
MFC基本应用程序的建立.ppt_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第4章MFC基本应用程序的建立,4.1 Windows编程基础 4.2 编制一个MFC应用程序 4.3 使用MFC AppWizard 4.4 使用ClassWizard 作业,4.1Windows编程基础,4.1.1简单的Windows应用程序 例Ex_HelloMsg 一个简单的Windows应用程序。 #include int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) MessageBox (NULL, “你好,我的Visual C+世界!“, “问候“, 0) ; return 0 ; 运行上述程序需要进行以下步骤: 选择“File”“New”。单击Projects,选中Win32 Application项。 在Project Name框中键入项目名称Ex_HelloMsg。在Location下的编辑框中直接键入文件夹名称,或单击Browse按钮(.)选择一个已有的文件夹。 单击OK。选中An empty project项。单击Finish,单击OK系统将自动创建此应用程序。 选择“File”“New”。单击File标签,在左边的列表框中选择C+ Source File项,在右边的File框中键入Ex_HelloMsg.cpp,单击OK。,4.1Windows编程基础,输入上面的代码,运行程序,如图。 从程序可以看出 : 传统的DOS程序以main函数作为进入程序的初始入口点,但在Windows应用程序中,main函数被WinMain函数取而代之,WinMain函数的原型如下: int WINAPI WinMain ( HINSTANCE hInstance, / 当前实例句柄 HINSTANCE hPrevInstance, / 前一实例句柄 LPSTR lpCmdLine, / 指向命令行参数的指针 int nCmdShow) / 窗口的显示状态 句柄是一个标识Windows资源(如菜单、图标、窗口等)和设备等对象的变量,或者是一个对操作系统资源的间接引用。 每一个Windows应用程序都需要Windows.h头文件,它还包含了其他的一些Windows头文件。这些头文件定义了Windows的所有数据类型、函数调用、数据结构和符号常量。 MessageBox是一个Win32 API(Application Programming Interface, 应用程序接口)函数,用来弹出一个对话框窗口,显示短信息。该函数第一个参数用来指定父窗口句柄,即对话框所在的窗口句柄。第二、三个参数分别用来指定显示的消息内容和对话框窗口的标题,最后一个参数用来指定在对话框中显示的按钮。,图4.1 Ex_HelloMsg运行结果,4.1Windows编程基础,例Ex_HelloWin 一个完整的Windows应用程序。 #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); / 窗口过程 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) HWND hwnd ; / 窗口句柄 MSG msg ; / 消息 WNDCLASS wndclass ; / 窗口类 wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc= WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra= 0 ; wndclass.hInstance= hInstance ; wndclass.hIcon= LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor= LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName= NULL ; wndclass.lpszClassName= “HelloWin”; / 窗口类名 if (!RegisterClass ( ,4.1Windows编程基础,hwnd = CreateWindow (“HelloWin“, / 窗口类名 “我的窗口“, / 窗口标题 WS_OVERLAPPEDWINDOW, / 窗口样式 CW_USEDEFAULT, / 窗口最初的 x 位置 CW_USEDEFAULT, / 窗口最初的 y 位置 CW_USEDEFAULT, / 窗口最初的 x 大小 CW_USEDEFAULT, / 窗口最初的 y 大小 NULL, / 父窗口句柄 NULL, / 窗口菜单句柄 hInstance, / 应用程序实例句柄 NULL) ; / 创建窗口的参数 ShowWindow (hwnd, nCmdShow) ; / 显示窗口 UpdateWindow (hwnd) ; / 更新窗口,包括窗口的客户区 / 进入消息循环:当从应用程序消息队列中检取的消息是WM_QUIT时,则退出循环。 while (GetMessage ( ,4.1Windows编程基础,LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) case WM_CREATE: / 窗口创建产生的消息 return 0 ; case WM_LBUTTONDOWN: MessageBox (NULL, “你好,我的Visual C+世界!“, “问候“, 0) ; return 0 ; case WM_DESTROY: / 当窗口关闭时产生的消息 PostQuitMessage (0) ; return 0 ; return DefWindowProc (hwnd, message, wParam, lParam) ; / 执行默认的消息处理 ,4.1Windows编程基础,程序运行,单击鼠标左键,如图。 窗口过程函数WndProc用来接收和处理各种不同的消息,WinMain函数通常要完成: 调用API函数RegisterClass注册应用程序的窗口类。 调用相关API函数创建和显示窗口,并进行必要的初始化。CreateWindow创建已注册窗口类的窗口。Windows每一个窗口都有一些基本属性。窗口类就是充当这些属性的模板。 创建和启动应用程序的消息循环。Windows应用程序接受各种不同的消息。Windows系统首先将消息放入消息队列中,应用程序的消息循环就是从应用程序的消息队列中检取消息,并将消息发送相应的窗口过程函数中作进一步处理。 如果接收到WM_QUIT消息,则退出应用程序,图4.2 Ex_HelloWin运行结果,4.1Windows编程基础,应用程序的基本流程,如图。,图4.3 Windows应用程序的基本流程,4.1Windows编程基础,4.1.2Windows编程特点 消息驱动机制 DOS程序是通过调用系统的函数来获得用户输入的,Windows程序则是通过操作系统发送的消息来处理用户输入的。 无论是系统产生的动作或是运行应用程序产生的动作,都称为事件(Events)产生的消息(Message)。在应用程序中,通过接收消息、分发消息、处理消息来和用户进行交互。许多消息都经过了严格的定义,并且适用于所有的应用程序。 图形设备接口(GDI ) DOS环境中,要在打印机上打印一幅图形是非常复杂的事件。Windows则提供了一个抽象的接口,称为图形设备接口(Graphical Device Interface,简称GDI),使得用户直接利用系统的GDI函数就能方便实现输入或输出,而不必关心与系统相连的外部设备的类型。 基于资源的程序设计 Windows应用程序常常包含众多图形元素,每一个这样的元素都作为一种可以装入应用程序的资源来存放。这些资源可以被编辑、修改,也可以被其他应用程序所共享。VC中提供的许多编辑器能“所见即所得”地进行不同类型资源的设计、编辑等。,4.1Windows编程基础,动态链接库 提供一些特定结构的函数,能被应用程序在运行过程中装入和连接,多个程序可以共享同一个动态链接库。从编程角度,动态链接库可以提高程序模块的灵活性,它本身是可以单独设计、编译和调试的。 Windows提供了应用程序可利用的丰富的函数调用,大多数用于实现其用户界面和在显示器上显示的文本和图形,都是通过动态链接库来实现的。 Windows中,KERNEL32用来处理存储器低层功能、任务和资源管理等核心服务; GDI32用来提供图形设备接口,管理用户界面和图形绘制;USER32负责窗口的管理。 进程和线程 Windows是一个32位多任务操作系统,采用进程和线程的管理模式。 进程是装入内存中正在执行的应用程序。进程包括私有的虚拟地址空间、代码、数据及其它操作系统资源。进程包括了一个或多个在进程上下文内运行的线程。 线程是操作系统分配CPU时间的基本实体。线程可以执行应用程序代码的任何部分,包括当前正在被其它线程执行的那些部分。同一进程的所有线程共享同样的虚拟地址空间、全局变量和操作系统资源。 一个应用程序,包括一个或多个进程,每个进程由一个或多个线程构成。,4.1Windows编程基础,4.1.3Windows基本数据类型,4.1Windows编程基础,需要说明的是: 这些基本数据类型都是以大写字符出现。 凡是数据类型的前缀是P或LP,表示该类型是一个指针或长指针数据类型。前缀是H,表示是句柄类型。前缀是U,表示是无符号数据类型。 还提供一些宏来处理上述基本数据类型。LOBYTE和HIBYTE分别用来获取16位数值中的低位和高位字节;LOWORD和HIWORD分别用来获取32位数值中的低位和高位字;MAKEWORD是将两个16位无符号值结合成一个32位无符号值。,4.2.1MFC概述 1987年微软公司推出了第一代Windows产品,并为应用程序设计者提供了Win16 API,在此基础上推出了Windows GUI(图形用户界面),然后采用面向对象技术对API进行封装。1992年推出应用程序框架产品AFX(Application Frameworks),并在AFX的基础上进一步发展为MFC产品。MFC类的基本层次结构如图。,4.2编制一个MFC应用程序,4.2.2设计一个MFC程序 例Ex_HelloMFC 一个MFC应用程序。 #include / MFC头文件 class CHelloApp : public CWinApp / 声明应用程序类 public: virtual BOOL InitInstance(); ; CHelloApp theApp; / 建立应用程序类的实例 class CMainFrame: public CFrameWnd / 声明主窗口类 public: CMainFrame() / 创建主窗口 Create(NULL, “我的窗口“, WS_OVERLAPPEDWINDOW, CRect(0,0,400,300); protected: afx_msg void OnLButtonDown(UINT nFlags, CPoint point); DECLARE_MESSAGE_MAP() ; / 消息映射入口 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_LBUTTONDOWN() / 单击鼠标左键消息的映射宏 END_MESSAGE_MAP(),4.2编制一个MFC应用程序,void CMainFrame:OnLButtonDown(UINT nFlags, CPoint point) MessageBox (“你好,我的Visual C+世界!“, “问候“, 0) ; CFrameWnd:OnLButtonDown(nFlags, point); / 每当应用程序首次执行时都要调用的初始化函数 BOOL CHelloApp:InitInstance() m_pMainWnd = new CMainFrame(); m_pMainWnd-ShowWindow(m_nCmdShow); m_pMainWnd-UpdateWindow(); return TRUE; 运行上述MFC程序需要进行以下步骤: 选择“File”“New”。单击Projects,选中Win32 Application项,创建一个Ex_HelloMFC空应用程序项目。 选择“File”“New”。单击File标签,在左边的列表框中选择C+ Source File项,在右边的File框中键入Ex_HelloMsg.cpp,单击OK。 输入上面的代码。选择“Project”“Settings”,选择“General”标签。在“Microsoft Foundation Classes”组合框中,选择“Use MFC in a Shared DLL”。单击OK。 程序运行后,单击鼠标左键,就会弹出一个对话框,结果同Ex_HelloWin。,4.2编制一个MFC应用程序,4.2.3理解程序代码 MFC是使用afxwin.h来代替头文件windows.h。 运行应用程序时,自动调用应用程序框架内部的WinMain函数,并自动查找该应用程序类CHelloApp(从CWinApp派生)的全局变量theApp,然后自动调用CHelloApp的虚函数InitInstance,该函数会进一步调用相应的函数来完成主窗口的构造和显示工作。上述程序中InitInstance的执行过程。 首先执行的是: m_pMainWnd = new CMainFrame(); 创建从CFrameWnd类派生而来的用户框架窗口CMainFrame类对象,继而调用该类的构造函数,使得Create函数被调用,完成了窗口创建工作。 然后执行后面两句: m_pMainWnd-ShowWindow(m_nCmdShow); m_pMainWnd-UpdateWindow(); 用作窗口的显示和更新。 最后返回TRUE,表示窗口创建成功。 由于应用程序类CWinApp是用来调用WinMain以及实例的初始化,因此每一个MFC应用程序有且只能一个这样的应用程序类,且需要一个全局的对象实例,如上述程序中的theApp。,4.2编制一个MFC应用程序,InitInstance完成初始化后,调用基类CWinApp的成员函数Run,执行应用程序的消息循环。Run检查到消息队列为空时,调用基类CWinApp的成员函数OnIdle进行空闲时的后台处理工作。若消息队列为空且又没有后台工作要处理时,则应用程序一直处于等待状态,一直等到有消息为止。当程序结束后,调用基类CWinApp的成员函数ExitInstance,完成终止应用程序的收尾工作。 在MFC中,一个消息的处理往往是通过独特的MFC消息映射机制来进行的。 消息映射(Message Map)机制,指MFC类中将消息与消息处理函数联系起来,一一对应的机制。任何一个从类CCmdTarget派生的类理论上均可处理消息,且都有相应的消息映射函数。 按照MFC的消息映射机制,映射一个消息的过程由三个部分组成: 在处理消息的类中,使用消息宏DECLARE_MESSAGE_MAP()声明对消息映射的支持,并在该宏之前声明消息处理函数。 使用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏在类声明之后的地方定义该类支持的消息映射入口点,所有消息映射宏都添加在这里,当然不同的消息MFC都会有不同的消息映射宏。 定义消息处理函数。 为了使该消息能被其他对象接收并处理,在函数中常常需要调用基类中的相关消息处理函数。MFC的ClassWizard(类向导)能自动完成消息的上述映射过程。,4.3使用MFC AppWizard,4.3.1应用程序框架类型,4.3使用MFC AppWizard,4.3.2创建一个单文档应用程序 开始 选择“File”“New”,选择Projects标签;选择MFC AppWizard(exe)的项目类型(该类型用于创建可执行的Windows应用程序),将项目工作文件夹定位在“D:Visual C+ 6.0程序”,并在“Project Name”框中输入项目名Ex_SDIHello,如图,单击OK。,图4.5 MFC AppWizard的“New”对话框,4.3使用MFC AppWizard,第一步 从应用程序类型Single Document、Multiple Document和Dialog Based中选择SDI。 决定应用程序中是否需要MFC的“文档/视图”结构的支持。若不选定此项,则程序中的磁盘文件的打开、保存以及文档和视图的相互作用等功能需要用户来实现,且将跳过Step 2Step 5,直接弹出“Step 6”对话框。 选择资源所使用的语言,这里是“中文中国”,单击Next按钮。,图4.6 SDI的“Step 1”对话框,4.3使用MFC AppWizard,第二步 单击Next按钮进入下一步。 第三步 单击Next按钮进入下一步。,图4.7 SDI的“Step 2”对话框,图4.8 SDI的“Step 3”对话框,4.3使用MFC AppWizard,第四步 单击Next按钮进入下一步。,图4.9 SDI的“Step 4”对话框,4.3使用MFC AppWizard,第五步 在弹出的对话框(如图)中出现三个方面的选项,供用户来选择: 应用程序的主窗口是MFC标准风格还是窗口左边有切分窗口的浏览器风格; 在源文件中是否加入注释用来引导用户编写程序代码; 使用动态链接库还是静态链接库。 保留缺省状态,单击Next按钮进行下一步。,图4.10 SDI的“Step 5”对话框,4.3使用MFC AppWizard,第六步 单击Finish按钮出现如图4.12所示的对话框,图4.11 SDI的“Step 6”对话框,图4.12 项目信息对话框,4.3使用MFC AppWizard,编译并运行,4.3使用MFC AppWizard,4.3.3理解程序框架 应用类CEx_SDIHelloApp 下面首先来看看Ex_SDIHello应用程序的Ex_SDIHello.h文件: . class CEx_SDIHelloApp : public CWinApp public: CEx_SDIHelloApp(); /AFX_VIRTUAL(CEx_SDIHelloApp) public: virtual BOOL InitInstance(); /AFX_VIRTUAL / Implementation(实现) /AFX_MSG(CEx_SDIHelloApp) afx_msg void OnAppAbout(); / NOTE - the ClassWizard will add and remove member functions here. / DO NOT EDIT what you see in these blocks of generated code ! /AFX_MSG DECLARE_MESSAGE_MAP() / 声明消息映射 ; .,4.3使用MFC AppWizard,代码中, /AFX_VIRTUAL(类名) . /AFX_VIRTUAL 是ClassWizard定义的专门用作虚函数重载的标记,表示该程序块中的虚函数的重载是由ClassWizard来自动管理的,一般不需要去更改。同样, /AFX_MSG(类名) . /AFX_MSG 是ClassWizard定义的专门用作消息映射声明的标记。 代码中的“/TODO:”以及英文等注释是由MFC AppWizard为用户自动生成的。若不需要这些注释,可在应用程序向导的第五步对话框中,将“Would you like to generate source file comments?”项选为“No,thank you”。 下面再来看看该Ex_SDIHello应用程序的Ex_SDIHello.cpp源文件: #include “stdafx.h“ / 预编译处理的头文件 #include “Ex_SDIHello.h“ / 应用类的头文件 #include “MainFrm.h“ / 主框架类的头文件 #include “Ex_SDIHelloDoc.h“ / 文档类的头文件 #include “Ex_SDIHelloView.h“ / 视图类的头文件,4.3使用MFC AppWizard,/消息映射开始 BEGIN_MESSAGE_MAP(CEx_SDIHelloApp, CWinApp) / 消息映射宏 /AFX_MSG_MAP(CEx_SDIHelloApp) / 映射“帮助”菜单项中的“关于Ex_SDIHello”命令消息,当用户选择了 / 该命令时,将执行函数OnAppAbout ON_COMMAND(ID_APP_ABOUT, OnAppAbout) / NOTE - the ClassWizard will add and remove mapping macros here. / DO NOT EDIT what you see in these blocks of generated code! /AFX_MSG_MAP / 映射“文件”菜单项中的“新建”和“打开”命令消息,当用户选择了“新建” / 或“打开”命令时,将相应执行CWinApp:OnFileNew或CWinApp:OnFileOpen ON_COMMAND(ID_FILE_NEW, CWinApp:OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp:OnFileOpen) / 映射“文件”菜单项中的“打印设置”命令消息,当用户选择了 / 该命令时,将执行函数CWinApp:OnFilePrintSetup ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp:OnFilePrintSetup) END_MESSAGE_MAP() / 消息映射宏,4.3使用MFC AppWizard,/ 消息映射开始结束 CEx_SDIHelloApp:CEx_SDIHelloApp() / 构造函数 CEx_SDIHelloApp theApp; / 定义的一个应用类对象,表示一个实例 BOOL CEx_SDIHelloApp:InitInstance() . . void CEx_SDIHelloApp:OnAppAbout() CAboutDlg aboutDlg; / 定义的CAboutDlg对象 aboutDlg.DoModal(); / 调用相应的库函数,显示 CAboutDlg对话框 代码中, /AFX_MSG_MAP(类名) /AFX_MSG_MAP 是ClassWizard定义的专门用作消息映射的标记,表示该程序块中的消息映射函数是由ClassWizard来自动管理的,用户一般不需要去更改。,4.3使用MFC AppWizard,最主要的InitInstance函数体代码: BOOL CEx_SDIHelloApp:InitInstance() / 若用户在MFC AppWizard的第三步中,选中了“ActiveX Controls”, / 则表示所创建的应用程序支持ActiveX控件 AfxEnableControlContainer(); / 若用户在MFC AppWizard的第四步中,选中了“3D controls” / 则表示所创建的应用程序支持Windows 95版本前的3D控件风格 #ifdef _AFXDLL Enable3dControls(); / 使用动态的3D控件 #else Enable3dControlsStatic(); / 使用静态的3D控件 #endif / 在系统注册表中登记应用程序的主键值,以便将一些与应用程序 / 相关的参数存放在该主键值下 SetRegistryKey(_T(“Local MFC AppWizard-Generated Applications“); / 从注册表中调入应用程序的一些标准参数值. LoadStdProfileSettings();,4.3使用MFC AppWizard,/ 若用户在MFC AppWizard的第一步中,选择了“Single document”类型, / 则进行下列的单文档模板的创建及其初始化操作。 CSingleDocTemplate* pDocTemplate; / 定义一个单文档模板指针变量 pDocTemplate = new CSingleDocTemplate(/ 登记并创建单文档应用程序模板 IDR_MAINFRAME, / 菜单、快捷键等的资源标识号 RUNTIME_CLASS(CEx_SDIHelloDoc), / 文档类 RUNTIME_CLASS(CMainFrame), / 主框架窗口类 RUNTIME_CLASS(CEx_SDIHelloView); / 视图类 AddDocTemplate(pDocTemplate); / 向应用程序添加文档模板 / 分列命令行标准命令如DDE、文件打开等 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); / 传送命令行指定的命令,并执行相应的操作 if (!ProcessShellCommand(cmdInfo) return FALSE; / 对主框架窗口进行初始化以便显示和更新 m_pMainWnd-ShowWindow(SW_SHOW); m_pMainWnd-UpdateWindow(); return TRUE; ,4.3使用MFC AppWizard,RUNTIME_CLASS是一个运行类的宏定义,返回CRuntimeClass类指针。借助CRuntimeClass类结构能在应用程序运行过程中获得该类对象及其基类的相关信息,从而可以实现运行时类型检查。 CSingleDocTemplate是一个单文档模板类,将用户应用程序项目中的资源、主框架窗口类、文档类以及视图类建立了联系。AddDocTemplate负责将这些联系嵌入应用程序中。类似的,还有用于多文档应用程序的多文档模板类CMultiDocTemplate,但与单文档不同的是,多文档模板可以创建多个视、多个文档, 很多程序都需要从命令行输入参数,它是通过ParseCommandLine函数保存在由CCommandLineInfo类定义的对象中,命令行最终的命令和参数是通过ProcessShellCommand执行的。与DOS命令行操作不同的是,Windows应用程序命令行参数是通过选择“开始”“运行”菜单命令,在弹出的运行对话框中指定的。,4.3使用MFC AppWizard,文档类CEx_SDIHelloDoc CEx_SDIHelloDoc类的Ex_SDIHelloDoc.h文件: . class CEx_SDIHelloDoc : public CDocument protected: CEx_SDIHelloDoc(); / 构造函数 DECLARE_DYNCREATE(CEx_SDIHelloDoc) . public: /AFX_VIRTUAL(CEx_SDIHelloDoc) public: virtual BOOL OnNewDocument();/ 当新建一个文档时,自动调用该函数 virtual void Serialize(CArchive #endif .,4.3使用MFC AppWizard,/ 产生消息映射函数 protected: /AFX_MSG(CEx_SDIHelloDoc) / NOTE - the ClassWizard will add and remove member functions here. / DO NOT EDIT what you see in these blocks of generated code ! /AFX_MSG DECLARE_MESSAGE_MAP() ; . 用户的文档类CEx_SDIHelloDoc是从基类CDocument派生而来。 AssertValid和Dump是用于调试版本的两个虚函数。AssertValid的目的是启用“断言”机制来检验对象的正确性、合法性,而Dump的目的是为他人分析用户自己定义的类提供一种机制,用来输出类的名称或其他数据内容。,4.3使用MFC AppWizard,视图类CEx_SDIHelloView CEx_SDIHelloView类的Ex_SDIHelloView.h文件: class CEx_SDIHelloView : public CView protected: CEx_SDIHelloView(); DECLARE_DYNCREATE(CEx_SDIHelloView) public: CEx_SDIHelloDoc* GetDocument(); / 用于返回文档类指针 public: /AFX_VIRTUAL(CEx_SDIHelloView) public: virtual void OnDraw(CDC* pDC); / 用于绘制的虚函数 virtual BOOL PreCreateWindow(CREATESTRUCT /AFX_VIRTUAL,4.3使用MFC AppWizard,/ Implementation public: virtual CEx_SDIHelloView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext #endif CEx_SDIHelloView的成员函数GetDocument是用inline声明成一个内联函数。,4.3使用MFC AppWizard,CEx_SDIHelloView类的Ex_SDIHelloView.cpp文件: #include “stdafx.h“ #include “Ex_SDIHello.h“ #include “Ex_SDIHelloDoc.h“ #include “Ex_SDIHelloView.h“ . IMPLEMENT_DYNCREATE(CEx_SDIHelloView, CView) BEGIN_MESSAGE_MAP(CEx_SDIHelloView, CView) /AFX_MSG_MAP(CEx_SDIHelloView) /AFX_MSG_MAP / 为“文件”菜单下的“打印.”和“打印预览”映射标准打印命令 ON_COMMAND(ID_FILE_PRINT, CView:OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView:OnFilePrintPreview) END_MESSAGE_MAP() CEx_SDIHelloView:CEx_SDIHelloView() CEx_SDIHelloView:CEx_SDIHelloView() BOOL CEx_SDIHelloView:PreCreateWindow(CREATESTRUCT ,4.3使用MFC AppWizard,void CEx_SDIHelloView:OnDraw(CDC* pDC) CEx_SDIHelloDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); BOOL CEx_SDIHelloView:OnPreparePrinting(CPrintInfo* pInfo) / default preparation return DoPreparePrinting(pInfo); void CEx_SDIHelloView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) / TODO: add extra initialization before printing void CEx_SDIHelloView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) / TODO: add cleanup after printing ,4.3使用MFC AppWizard,/ 以下是用于调试的函数 #ifdef _DEBUG void CEx_SDIHelloView:AssertValid() const CView:AssertValid(); void CEx_SDIHelloView:Dump(CDumpContext #endif /_DEBUG,4.3使用MFC AppWizard,视图类CEx_SDIHelloView是从基类CView派生而来的。说明: 各种类型的输入都可以由视图来响应、处理,并且打印和打印预览也是在视图类中完成的。这种文档和视图的结合,称为“文档/视图结构”机制,是MFC应用程序框架的核心,可以进行消息的处理、文档的格式化及文档数据的可视化处理等;它不但使文档数据和视图分离,而且能简化应用程序并减少代码冗余。 PreCreateWindow虚函数是在相应窗口创建前被系统自动调用的。在此函数中,可以更改其CREATESTRUCT结构内容,将改变相应窗口的风格. OnDraw是个非常有用的虚函数,当应用程序中的窗口状态或大小发生改变时,系统均会调用此函数重新绘制文档窗口的客户区。用户可以将一些绘图有关的代码添加此函数中,能在视图中进行图形的绘制。 例如,下面的代码: void CEx_SDIHelloView:OnDraw(CDC* pDC) CEx_SDIHelloDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDC-TextOut(100,100,“Hello,World!“); ,4.3使用MFC AppWizard,主框架窗口类CMainFrame “关于”对话框类CAboutDlg MFC涉及到的机制有: 文档/视图机制:它使用户应用程序类、文档类、视图类以及框架类之间有机地结合在一起,是MFC最引人注目的机制。 消息映射机制:它是实现对各种不同消息的处理。 数据映射机制:是实现对话框中变量与控件之间的数据交换和数据校验。 运行时类型检查机制:它通过GetRuntimeClass、IsKindOf、宏DECLARE_DYNAMIC和宏IMPLEMENT_DYNAMIC来实现的。 诊断信息转储机制:它是通过AssertValid、Dump和宏TRACE来实现的。 实现文档/视图机制是通过MFC应用程序向导自动完成的,而消息和数据映射则是通过MFC的ClassWizard来自动进行的。,4.4使用ClassWizard,4.4.1ClassWizard概述 打开MFC的ClassWizard的方法: 选择“View”“ClassWizard”菜单或直接使用Ctrl+W快捷键。 在源代码文件的文档编辑窗口中,右击鼠标,选择ClassWizard命令。 当ClassWizard打开后,就会弹出如图的MFC ClassWizard对话框。,图4.15 MFC ClassWiard对话框,4.4使用ClassWizard,4.4.2消息和消息映射 消息分类 Windows应用程序中的消息主要有三种类型。 窗口消息(Windows message) 主要指由WM_开头的消息,一般由窗口类和视图类对象来处理。窗口消息往往带有参数,以标志处理消息的方法。 控件的通知消息(Control notifications) 当控件的状态发生改变时,控件就会向其父窗口发送WM_COMMAND通知消息。应用程序框架处理控件消息的方法和窗口消息相同,但按钮的BN_CLICKED通知消息除外,它的处理方法与命令消息相同。 命令消息(Command message) 主要包括由用户交互对象(菜单、工具条的按钮、快捷键等)发送的WM_COMMAND通知消息。命令消息的处理方式与其他两种消息不同,它能够被多种对象接收、处理,这些对象包括文档类、文档模板类、应用程序本身以及窗口和视类等;而窗口消息和控件的通知消息是由窗口对象接收并处理的,这里的窗口对象是指从CWnd中派生的类的对象,它包括CFrameWnd、CMDIFrameWnd、CMDIChildWnd、CView、CDialog以及从这些类派生的对象等。,4.4使用ClassWizard,ClassWizard映射消息的一般方法,4.4使用ClassWizard,例如,向CEx_SDIHelloView中添加WM_LBUTTOMDOWN的消息映射,则可按下列步骤进行: (1)按Ctrl+W快捷键打开MFC ClassWizard对话框。 (2)在Class name组合框中,将类名选定为CEx_SDIHelloView。 (3)在Object IDs列表框中选定CEx_SDIHelloView,而在Messages列表中选定WM_LBUTTOMDOWN消息。 (4)双击Messages列表中的WM_LBUTTOMDOWN消息或单击Add Function按钮,都会在CEx_SDIHelloView类中添加该消息的映射函数OnLButtonDown,同时在Member funcions列表中显示这一消息映射函数和被映射的消息,如图。,图4.16 映射WM_LBUTTONDOWN消息,4.4使用ClassWizard,(5)单击Edit Code,转向文档窗口,定位到OnLButtonDown源代码处。 (6)添加下列代码: void CEx_SDIHelloView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default MessageBox (“你好,我的Visual C+世界!“, “问候“, 0) ; CView:OnLButtonDown(nFlags, point); (7)程序运行后,在窗口客户区左击,弹出一个消息对话框。 查看CEx_SDIHelloView程序代码,可以发现:ClassWizard为WM_LBUTTOMDOWN的消息映射作了以下三个方面内容的安排: 在头文件Ex_SDIHelloView.h中声明消息处理函数OnLButtonDown: protected: /AFX_MSG(CEx_SDIHelloView) afx_msg void OnLButtonDown(UINT nFlags, CPoint point); /AFX_MSG DECLARE_MESSAGE_MAP(),4.4使用ClassWizard,在Ex_SDIHelloView.cpp源文件前面的消息映射入口处,添加映射宏: BEGIN_MESSAGE_MAP(CEx_SDIHelloView, CView) / 消息映射开始 /AFX_MSG_MAP(CEx_SDIHelloView) ON_WM_LBUTTONDOWN() /AFX_MSG_MAP END_MESSAGE_MAP() / 消息映射结束 在Ex_SDIHelloView.cpp文件中写入一个空的消息处理函数的模板,框架: void CEx_SDIHelloView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default CView:OnLButtonDown(nFlags, point); 根据ClassWizard产生的上述消息映射过程,可以手动添加一些ClassWizard不支持的消息映射函数,以完成特定的功能。 鼠标和键盘消息各自都有相应的消息处理宏和预定义消息处理函数,因此消息映射函数名称不再需要用户重新定义。对于菜单和按钮等命令消息来说,用ClassWizard映射时会弹出一个对话框,用来指定消息映射函数的名称。 若指定的消息映射函数需要删除,则需要先在ClassWizard对话框的Messages列表中选定要删除的消息映射函数,然后单击Delete Function按钮,最后关闭ClassWizard对话框,并在该消息映射函数所在的类实现文件(.cpp)中将映射函数定义的代码全部删除。,4.4使用ClassWizard,键盘和鼠标消息 按下一个键或组合键时,将WM_KEYDOWN或WM_SYSKEYDOWN放入具有输入焦点的应用程序窗口的消息队列中。键被释放时,把WM_KEYUP或WM_SYSKEYUP消息放入消息队列中。对字符键,会在这两个消息之间产生WM_CHAR消息。, ClassWizard能自动添加了当前类的WM_KEYDOWN和WM_KEYUP击键消息处理函数的调用,它们具有下列函数原型: afx_msg void OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ); afx_msg void OnKeyUp( UIN

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论