730 likes | 974 Views
第 3 章 MFC 应用程序概述. MFC 应用程序概述. Windows 应用程序概述 MFC 应用程序框架 文档 / 视图结构 消息映射. 3.1 Windows 应用程序概述. 3.1.1 窗口编程基础 窗口 消息和消息队列 事件驱动的程序设计 资源管理. 1. 窗口 (Window). 窗口是应用程序与用户交互的界面 窗口元素以对象方式组织 一个应用程序由多个窗口组成 程序运行过程是窗口之间,窗口与系统,窗口与用户之间交换并处理数据的过程。. 标题栏. 菜单栏. 最小化按钮. 关闭按钮. 最大化按钮. 客户区. 垂直滚动条.
E N D
MFC应用程序概述 • Windows 应用程序概述 • MFC应用程序框架 • 文档/视图结构 • 消息映射
3.1 Windows 应用程序概述 3.1.1 窗口编程基础 • 窗口 • 消息和消息队列 • 事件驱动的程序设计 • 资源管理
1. 窗口(Window) • 窗口是应用程序与用户交互的界面 • 窗口元素以对象方式组织 • 一个应用程序由多个窗口组成 • 程序运行过程是窗口之间,窗口与系统,窗口与用户之间交换并处理数据的过程。
标题栏 菜单栏 最小化按钮 关闭按钮 最大化按钮 客户区 垂直滚动条 窗口边界 水平滚动条 2. 窗口的界面元素
消息(Message)和消息队列 • 消息用于通知某个事件的产生 • 消息机制 • MSG • 消息的类型
消息(Message)和消息队列 • Windows应用程序是利用消息与其他Windows应用程序和操作系统进行信息交换的。 • 消息的作用是通知一个应用程序某个确定的事件的产生。 • 应用程序对该事件做出响应,即编写相应的消息处理代码。 举例:按下鼠标左键时,系统会产生WM_LBUTTONDOWN消息
消息(Message)和消息队列 Windows应用程序接受系统队列传递过来的消息的步骤: (1)每个Windows应用程序都有一个WinMain( )函数,在该函数中会定义一个窗口句柄,当应用程序启动时,会使该窗口句柄注册,操作系统使用窗口句柄与Windows应用程序通信。
消息(Message)和消息队列 (2)Windows应用程序创建一个或多个窗口,每个窗口都有一个窗口处理函数(WndProc),负责窗口显示和响应用户输入。 (3)消息映射(Message Mapping):负责从消息队列中取消息,并送回窗口,由窗口处理函数选择合适的消息处理函数响应消息。
程序开始 程序结束 消息源1 捕获消息 消息源2 派送消息 · · · 否 是否退出 消息 处理消息 是 消息源n
消息机制 消息机制是Windows应用程序运行的核心工作机制,用如下结构体MSG表示: typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; }MSG;
MSG结构体成员说明: (1)hwnd 接收消息的窗口句柄。 (2)Message 消息值,每个windows消息都有一个消息值,该值由windows.h头文件的宏定义来标识。
(3) wParam和lParam 包含有关消息的附加信息,它随消息的不同而不同。 (4)Time 指定消息送至队列的时间界限。 (5)pt 指定消息发送时屏幕光标的位置,结构如下: typedef struct tagPOINT { LONG x; LONG y; POINT; }
消息的类型 1.输入消息 由键盘和鼠标操作产生输入消息。这类消息首先放在系统消息队列中,后由Windows操作系统将他们放到应用程序消息队列中,由应用程序处理消息。 2.控件消息 用户操作窗口对象时产生控件消息,这类消息一般不进入应用程序消息队列,而直接发送到控件对象所属的对话框窗口
消息的类型 3.系统消息 对程序化的事件或系统时钟中断做出的放映。一类例如DDE(动态数据交换消息)要通过Windows的系统消息队列,送入应用程序的消息队列,另一类直接送入应用程序的消息队列,例如创建窗口消息。 4.用户消息 是程序员自己定义并在应用程序中主动发出的,一般由应用程序的某一部分做内部处理。
3. 事件驱动的程序设计 • Windows操作系统下的Windows应用程序采用事件驱动的程序设计,与Dos操作系统下面向过程有明显不同。 • 事件驱动的程序的逻辑顺序是按事件的产生而决定的。 • 事件的产生不是预先定义的,有着随机性 。
3. 事件驱动的程序设计 例1、一个应用程序的功能是体操全能比赛项目运动成绩管理,体操全能包括4个项目,在一个驱动中需要如下步骤: (1)输入第一项运动员的成绩。 (2)输入第二项运动员的成绩。 (3)输入第三项运动员的成绩。 (4)输入第四项运动员的成绩。 (5)计算每个运动员的总分。 (6) 按总分排名。
开始 输入第一项某运动员的成绩 计算每个运动员的总分 消息 循环 输入第二项某运动员的成绩 输入第三项某运动员的成绩 输入第四项某运动员的成绩 按总分排名 结束 事件驱动程序流程示例
资源的类型 用户自定义资源 菜单 对话框 工具栏 系统资源 设备上下文 画刷 画笔 字体 通信端口 4. 资源管理
3.1.2 Windows应用程序组成 一个应用程序是如何开始? • 操作系统创建一个新的进程和一个初始线程 • 应用程序代码装载到内存 • 动态链接库装载到内存(如果需要使用DLL) • 为数据和堆栈分配物理内存,并映射到虚拟内存 • 应用程序开始执行
3.1.2 Windows应用程序组成 Windows应用程序必须包含两个基本函数: (1)应用程序主函数WinMain( ) WinMain函数定义了窗口句柄,创建初始化窗口并启动一个消息循环。 (2)窗口处理函数WinProc( ) WinProc函数处理所有从操作系统传递到窗口的消息。每一个窗口都要有一个窗口处理函数。
3.1.2 Windows应用程序组成 1.WinMain( )函数 Windows应用程序是从WinMain( )函数开始和结束的。 在”WINBASE.H”中定义如下: int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSR lpCmdLine, int nCmdShow );
3.1.2 Windows应用程序组成 参数说明如下: (1) hInstance 系统分配的窗口所属的应用程序的实例句柄,标识当前进程的实例,是进程所占据的地址空间的首地址,是程序的唯一标识。 (2)hPrevInstance 用于检查是否有多个程序实例运行。
3.1.2 Windows应用程序组成 (3)lpCmdLine 是一个指向字符串的指针,用来保存程序运行时的参数,同main函数中的argv[ ]相似。 (4)nCmdShow 用来指明应用程序的主窗口的显示方式(最大化,最小化,一般显示),通常被ShowWindow( )函数作为显示窗口的参数。
3.1.2 Windows应用程序组成 WinMain函数的作用: 注册窗口类,创建并初始化窗口,创建消息循环(message loop)。 (1) 注册窗口类 每个窗口都包含一些基本属性,如窗口边框、标题、大小、位置、鼠标、背景色等,注册的过程是将这些属性报告给系统。
3.1.2 Windows应用程序组成 (2) 创建并初始化窗口 CreateWindow( )函数用于创建窗口,定义了窗口的名称、位置、尺寸等数据,创建成功返回窗口句柄,否则为0。 创建后创口需要调用ShowWindow( ) 和UpdateWindow( )两个函数显示窗口。
3.1.2 Windows应用程序组成 (3) 创建消息循环 使用While语句创建一个消息循环,负责从消息队列中获取消息并发送给相应的处理函数。 while(GetMessage (&Msg,NULL,0,0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } TranslateMessage( )函数的作用是将来自键盘的命令翻译为消息的ID字符表示。 DispatchMessage( )把每个消息分发给相应的窗口函数。
3.1.2 Windows应用程序组成 2. 窗口处理函数 决定窗口在它的客户区中显示哪些内容、窗口如何响应用户输入,窗口函数定义如下: LRESULT CALLBACK WndProc( HWND hwnd, UNIT Message, WPARAM wParam, LPARAM lparam, )
3.1.2 Windows应用程序组成 参数说明如下: (1) LRESULT 表示该函数返回值为长整数,由系统使用。 (2)CALLBACK 表示该函数是回调函数,由系统使用。 (3)Hwnd 接收消息的窗口句柄 (4)Message 用来标示消息的数字 (5)wParam和lparam 两个32位的消息参数,用来提供消息的附加信息。
Windows的编程模型与MS-DOS编程模型之比较 • 第一,用C语言编写基于MS-DOS的应用程序时,唯一绝对需要的是一个名为main的函数。而当Windows操作系统启动一个程序时,调用的是WinMain函数。 • 第二,许多MS-DOS程序直接写显存和打印机接口。这种技术的不利之处是对每一种设备需要其支持的驱动程序软件。Windows引入了一个名为图形设备接口(GDI)的抽象化外层,所以用户不必知道有关系统设备的类型。Windows程序不是寻址硬件,而是调用GDI函数。
Windows的编程模型与MS-DOS编程模型之比较 • 第三,要在MS-DOS环境下进行数据驱动编程,必须或者为把数据编码成为初始化常量或者提供独立的数据文件让程序来读。进行Windows编程时,使用大量已经确立的格式在资源文件中存储数据。 • 第四,在MS-DOS环境下一个程序的所有对象模块在建立过程中是静态连接的。Windows允许动态链接,这意味着特别创建的库可以在运行时加载和链接。多个应用程序可以共享动态链接库(DLLs),它节省内存和磁盘空间。动态链接增加了程序的模块性。
3.1.3 应用程序举例 分析使用AppWizard生成的Win32窗口程序示例Exam3_2,并对该程序作以下修改: (1)修改输出的文本字符串”Hello World”为”Hello C++!”。 (2)在视图的中央输出文本”Starting your VC++ learning!” (3)添加一个对话框,并能使用菜单调用这个对话框。
3.2 MFC应用程序框架 • Visual C++6.0是一种集成开发环境,提供了MFC类库。 • MFC(Microsoft基本类库,Microsoft Foundation Class Library) • MFC是微软公司对大部分标准的Win32 API函数的封装,提供了图形环境应用程序的框架及创建应用程序的组件.
MFC 简 介 • MFC是用来写Windows应用程序的VC++类集,该类集以层次结构组织起来。提供的类库对程序设计高度抽象,使代码的可靠性和重用性得到很大的提高。 • MFC给Windows系统开发平台程序员以最好支持的基本类结构,它包含的类分层结构和功能是具有可伸缩性,在功能扩展的同时,MFC还保持了程序的向下兼容性。
MFC类的层次结构 • MFC类库中是以层次结构的方式组织起来的,每个层次结构都与一具体的Windows的实体相对应。 • 大多数MFC类是从3个基类(CObject类、CCmdTarget类、CWnd类)派生的
MFC类的层次结构 • 根类:CObject类 CObject类 CCmdTarget类 CWnd类 • 从CObject类派生的类具有运行时获得对象大小的名字的能力 • 从CCmdTarget类派生的类能够处理命令消息 • 从CWnd类派生的类能够控制窗口 派生 派生
CObject CCmdTarget CWinThread CWnd CDocument CWinApp CFrameWnd CView CObject派生类
MFC类的层次结构 • MFC提供的一些重要的类分为以下几种: • 应用程序框架结构类CWinApp • 程序窗口类CFramWnd • 图形打印类CGdiObject • 文件类CFile • Internet类 • 集合类 • 异常和调试支持类
应用程序类CWinApp • 应用程序框架类主要包括应用程序类、线程类、文档类和文档模板类。 • 应用程序类CWinApp:每个MFC应用程序只能由一个CWinApp的派生对象。 • CWinApp是应用程序开始后创建的第一个对象,结束前最后一个执行对象。
文档类CDocument • 文档类Cdocument封装了应用程序的数据管理功能,可以存储和载入用户定义的持久数据提供“容器” • 文档类负责将一个文档赋给它的成员变量,并允许视图类编辑这些成员变量。
程序窗口类CWnd • 程序窗口类主要包括框架窗口类、对话框类、视图类、控件类等。 • 类CWnd提供了MFC中所有窗口类的基本功能,作为所有类的公共基类。 • 创建一个Windows窗口需二步,首先引入构造函数,构造一个CWnd对象,然后调用Create建立Windows窗口并将它连接到CWnd对象上。
框架窗口类CFramWnd • 框架窗口类CFramWnd是CWnd类的子类,创建和维护窗口的边框、菜单栏、工具栏、状态栏等部分. • 一个SDI应用程序,主框架类是从CMainFrame派生的,对于一个MDI应用程序,主框架类是从CMDIFramWnd派生的。
视图类CView • 视图类是应用程序中较重要的类,应用程序返回的结果大多在视图类上进行进行和显示, CView 是用于让用户通过窗口来访问文档 ,提供人机交互的界面。 • 视图类负责描述文档的内容,也可以用户编辑文档。 • 创建应用程序时,创建文档类的一个实例后将创建视图类Cview的一个实例。
几种视图类 • CView类是基本视类,支持基本操作 • CScrollView类提供了滚动功能,设置滚动尺寸和坐标模式。 • CFormView类可在资源文件中定义界面的能力,并可将子窗口和变量进行绑定。 • CListView类利用ListCtrl(列表框)界面作为视界面 • CEditView类利用Edit接收用户输入,具有输入框的一切功能,可实现多行文本的编辑。
对话框类CDialog • CDialog类封装了用来创建对话框的Windows API,在创建时可以用对话框模板中定义的控件来填充。 • CDialog 可分别处理无模式和有模式两种类型的对话框. • 几个MFC通用对话框类CColorDialog、CFileDialog、CFontDialog、CPrintDialog。
控件类和控制栏类 • 常用控件类CButton类,CListCtrl类,CProgressCtrl类,CTreeCtrl类,CComboBox类,CEdit类等。 • 控制栏类(CControl类的派生类),从编成的角度看,工具栏只是CToolBar类的一个对象,状态栏是CStatusBar类的对象。
MFC应用程序框架分析 • 在一个CHello SDI应用程序中,向导为我们生成了4个主要的类,这些类都是MFC类的派生类,分别包含在对应的头文件以及实现文件中。 • 分析每个类的作用
MFC应用程序框架分析 • CHelloApp类——类CHelloApp的一个对象代表一个应用程序。 • 程序定义了一个全局CHelloApp对象theApp。CWinApp基类决定theApp的大多数行为。 • CWinApp类重载函数:InitInstance( ),完成应用的初始化以,与WinMain函数结构中的初始化处理相对应。
MFC应用程序框架分析 • 典型的一个应用程序将有一个主应用程序窗口。因此,CHelloApp 应用程序类定义了一个名为m_pMainWnd 成员变量来指向主窗口。 • InitInstance 函数建立了一个 CHelloWindow 事例,并使用 m_pMainWnd 来指向一个新的窗口
MFC应用程序框架分析 • CMainFrame代表的是程序的主框架窗口。 • 框架窗口类及其相关的文件框架窗口类对应应用程序的主窗口 ,他的定义是在头文件MainFrm.h中,而实现则是在MainFrm.cpp文件中。所有与框架窗口相关的功能都是在这里定义和实现的。