《实践教程第二章第二版》由会员分享,可在线阅读,更多相关《实践教程第二章第二版(82页珍藏版)》请在金锄头文库上搜索。
1、第二章第二章 MFC编程基础知识编程基础知识本章介绍本章介绍MFCMFC的基本原理的基本原理 Windows操操作作系系统统采采用用了了图图形形用用户户界界面面,借借助助于于 它它 提提 供供 的的 API( Application Programming Interface)函函数数,用用户户可可以以编编出出具具有有漂漂亮亮图图形形界界面面的程序。的程序。Windows本本身身是是面面向向对对象象的的,因因此此采采用用面面向向对对象象的的程程 序序 设设 计计 更更 为为 自自 然然 。 VC+的的 微微 软软 基基 础础 类类 库库(Microsoft Foundation Class L
2、ibrary,MFC)封封装装了了大大部部分分API函函数数,并并提提供供了了一一个个应应用用程程序序框框架架,简简化化和和标标准准化化了了Windows程程序序设设计计,因因此此MFC编编程程被称为标准被称为标准Windows程序设计。程序设计。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.第二章第二章 MFC编程基础知识(选读)编程基础知识(选读)2.1 传统的传统的Windows编程编程 2.3 MFC基础类
3、及其层次结构基础类及其层次结构 2.5 MFC对象和对象和Windows对象对象2.4 MFC编程编程 2.7 MFC中的文件中的文件处理理 2.6 MFC的消息映射的消息映射 2.2 Windows对象句柄象句柄Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程WindowsWindows操作系统的特征操作系统的特征: Windows操作系统是多任务、图形界面的操作系统。操
4、作系统是多任务、图形界面的操作系统。Windows拥有一个拥有一个图形用户界面图形用户界面(GUI)。用户可以用键盘和。用户可以用键盘和鼠标与显示器上的图形实现直接交互。鼠标与显示器上的图形实现直接交互。 Windows支持多任务操作,可在同一时刻运行多个程支持多任务操作,可在同一时刻运行多个程序,并可在程序间进行信息交互。每个程序只能在称为序,并可在程序间进行信息交互。每个程序只能在称为“窗窗口口”的屏幕矩形区中实现输出。的屏幕矩形区中实现输出。Windows的的图图形形设设备备接接口口(GDI),实实现现了了程程序序与与设设备备的的无无关关性性,即即为为Windows编编写写的的应应用用程
5、程序序可可以以运运行行于于任任何何具具有有Windows设备驱动程序设备驱动程序的硬件环境中,方便了使用。的硬件环境中,方便了使用。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd. 2.1 传统的传统的Windows 编程编程APIAPI函数:函数:为使程序员在编写应用程序时实现这些特征,为使程序员在编写应用程序时实现这些特征,Windows提供了一个提供了一个应用程序编程接口应用程序编程接口,称,称Windows
6、API(Application Programming Interface),这是,这是Windows支持的函数定义、参数定义和消息格式的集合,支持的函数定义、参数定义和消息格式的集合,可供应用程序调用。可供应用程序调用。 这上千个这上千个APIAPI函数函数包含了各种窗口类和系统资源包含了各种窗口类和系统资源(内存管理、文件、线程等等)。利用这些函数就可以(内存管理、文件、线程等等)。利用这些函数就可以编出具有编出具有WindowsWindows风格的程序。风格的程序。Windows APIWindows API也是也是WindowsWindows操作系统自带的在操作系统自带的在Window
7、sWindows环境下运行的环境下运行的软件开软件开发包(发包(SDKSDK)。程序员总是直接或间接引用。程序员总是直接或间接引用APIAPI进行应用进行应用程序的开发,所以程序的开发,所以WindowsWindows应用程序就有大致相同的用应用程序就有大致相同的用户界面。户界面。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd. 2.1 传统的传统的Windows 编程编程C/C+C/C+调用调用APIAPI函数的
8、优势:函数的优势:Windows环境下的最佳编程语言就是环境下的最佳编程语言就是C/C+语言,语言,因为因为Windows API函数本身就是用函数本身就是用C语言编写的语言编写的,C和和C+调用调用C语言的语言的API函数是直接调用,而其他语言则多函数是直接调用,而其他语言则多一道转换。一道转换。C/C+编程可以很方便地利用计算机的底层编程可以很方便地利用计算机的底层资源,其程序运行速度远远高于其他语言。资源,其程序运行速度远远高于其他语言。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0
9、.0.Copyright 2004-2011 Aspose Pty Ltd. 2.1 传统的传统的Windows 编程编程1) 1) 系统服务系统服务2) 2) 通用控件库通用控件库3) 3) 图形设备接口图形设备接口4) 4) 网络服务网络服务5) 5) 用户接口用户接口6) 6) 系统系统ShellShell 7) Windows 7) Windows 系统信息系统信息 标准标准Win32 API 函数分类:函数分类: Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyrig
10、ht 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程传统的传统的WindowsWindows编程编程 :直接采用直接采用API进行的进行的C/C+程序设计程序设计【例【例2.1】一个对话框的简单】一个对话框的简单Windows程序:程序:#includeint APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPreinstance, LPSTR lpCmdLine, int nCmdshow)MessageBox(NULL,This is a MessageBox windows example,
11、Ex2_1,MB_OK); return 0;Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程说明:说明:(1) windows.h是是windows程程序序最最基基本本的的头头文文件件,它它包包含含了了其其它它几几个个windows头头文文件件,它它们们定定义义了了windows的的所所有有数数据据类类型型、数数据据结构、符号常量和结构、符号常量和API函数原型声明。函数
12、原型声明。 (2) MessageBox 是一个是一个API函数,显示一个消息框。其中:第一个函数,显示一个消息框。其中:第一个参数指明此消息框的父窗口句柄,为参数指明此消息框的父窗口句柄,为NULL则说明没有父窗口;则说明没有父窗口;第二、三个参数类型均为字符型指针,分别指向消息框中要显示的字第二、三个参数类型均为字符型指针,分别指向消息框中要显示的字符串和消息框标题栏显示的字符串;符串和消息框标题栏显示的字符串;第四个参数是一个无符号整数,表明消息框中显示的按钮和风格。第四个参数是一个无符号整数,表明消息框中显示的按钮和风格。#define MB_OK 0x00000000L / OK按钮
13、按钮#define MB_OKCANCEL 0x00000001L / OK和和CANCEL两个按钮两个按钮#define MB_ABORTRETYRIGNORE 0x00000002L /ABORT,RETRY和和IGNORE3个按钮个按钮#define MB_YESNOCANCEL0x00000003L / YES、NO和和CANCEL共共3个按钮个按钮Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统
14、的传统的Windows 编程编程(3) WinMain函数是函数是windows程序的入口函数,包含程序的入口函数,包含4个参数:个参数:hInstance是唯一标识本程序的实例句柄,系统和其它应用程序是唯一标识本程序的实例句柄,系统和其它应用程序通过该句柄与本程序通讯。通过该句柄与本程序通讯。hPrevInstance是本程序的前一个实例句柄,由于是本程序的前一个实例句柄,由于32位位windows采用进程线程模式,每一线程拥有自己的句柄,因采用进程线程模式,每一线程拥有自己的句柄,因此该参数始终为空。此该参数始终为空。lpCmdLine是一个字符串指针,指向命令行参数字符串,没有是一个字符
15、串指针,指向命令行参数字符串,没有命令行参数时为空。命令行参数时为空。nCmdShow指明程序最初运行时窗口打开方式,如正常方式、指明程序最初运行时窗口打开方式,如正常方式、最大化或最小化运行。最大化或最小化运行。WinMain返回一个整数值,作为退出代码。返回一个整数值,作为退出代码。APIENTRY表示函数调用约定,函数调用时参数按从左至右的表示函数调用约定,函数调用时参数按从左至右的顺序压入栈,由被调用者将参数弹出栈顺序压入栈,由被调用者将参数弹出栈。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profil
16、e 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程典型的典型的WindowsWindows程序结构:程序结构: WindowsWindows程序采用程序采用事件驱动、消息传递事件驱动、消息传递方式,由方式,由入入口函数和窗口函数口函数和窗口函数两部分组成。两部分组成。 入口函数中有一个由入口函数中有一个由while语句组成的语句组成的消息循环消息循环,其中调用了诸如其中调用了诸如获取消息获取消息、键盘消息转换键盘消息转换、派送消息派送消息和和窗口处理函数窗口处理函数等等API函数,循环直到取得函数,循环直到取得
17、退出消息退出消息(WIN-QUIT)结束。)结束。 在应用程序中还有由操作系统的在应用程序中还有由操作系统的API函数函数回调回调(callback)的窗口处理函数(简称的窗口处理函数(简称窗口函数窗口函数),根据),根据消息值转向相应的消息处理,这是由消息值转向相应的消息处理,这是由switch语句组成的语句组成的多向选择。如果不能处理则转缺省的窗口函数。多向选择。如果不能处理则转缺省的窗口函数。参见图参见图2.3。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright
18、2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程图图2.3 Windows消息流程消息流程Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程【例【例2.2】显示一个窗口的】显示一个窗口的Windows应用程序。应用程序。#include /包含包含windows.h头文件头文件LRESULT CALLBACK WndProc(HW
19、ND, UINT, WPARAM, LPARAM ); /窗口函数声明窗口函数声明 /*入口函数入口函数 WinMain()*/int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) WNDCLASS wndclass; /定义定义窗口类结构变窗口类结构变量量 HWND hwnd; /定义窗口句柄定义窗口句柄 MSG msg; /定义消息结构变量定义消息结构变量Evaluation only.Created with Aspose.Slides for .N
20、ET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程/*窗口类使用步骤窗口类使用步骤*/*定义窗口类的各属性定义窗口类的各属性*/ wndclass.style = CS_HREDRAW|CS_VREDRAW; /改变窗口大小则重画改变窗口大小则重画 wndclass.lpfnWndProc = WndProc; /窗口函数为窗口函数为 WndProc wndclass.cbClsExtra = 0;/窗口类无扩展窗口类无扩展 wndclass.cbWndExtra = 0
21、;/窗口实例无扩展窗口实例无扩展 wndclass.hInstance = hInstance; /注册窗口类实例句柄注册窗口类实例句柄 wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); /用默认光标用默认光标 wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); /用箭头光标用箭头光标 wdclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); /背景为白色背景为白色 wndclass.lpszMenuName = NULL;/窗口缺省无菜单窗
22、口缺省无菜单 wndclass.lpszClassName = Ex2_2; /窗口类名为窗口类名为Ex2_2Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程/*设置后,必须注册窗口类设置才生效设置后,必须注册窗口类设置才生效*/if(! RegisterClass(&wndclass) return FALSE; /*前面只是定义了窗口类,下面创建窗口前面只是定义了窗口类
23、,下面创建窗口*/hwnd = CreateWindow(Ex2_2,/窗口类名窗口类名 Ex2_2 Ex2_2,/窗口名窗口名EX2_2 WS_OVERLAPPEDWINDOW,/重叠式窗口重叠式窗口 CW_USEDEFAULT, CW_USEDEFAULT, /左上角屏幕坐标左上角屏幕坐标CW_USEDEFAULT, CW_USEDEFAULT, /宽度和高度宽度和高度 NULL,/此窗口无父窗口此窗口无父窗口 NULL,/此窗口无主菜单此窗口无主菜单 hInstance, /创建此窗口的实例句柄创建此窗口的实例句柄 NULL); /此窗口无创建参数此窗口无创建参数Evaluation o
24、nly.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程/*显示并更新窗口显示并更新窗口*/ ShowWindow(hwnd,nCmdShow); /显示窗口显示窗口 UpdateWindow (hwnd); /更新窗口的客户区更新窗口的客户区/*消息循环消息循环*/获取消息,遇获取消息,遇WM_QUIT退出循环退出循环 while(GetMessage (&msg,NULL,0,0) Translate
25、Message (&msg); /键盘消息转换键盘消息转换 DispatchMessage (&msg); /派派送送消消息息给给窗窗口口函函数数 return msg.wParam; /返回退出值返回退出值Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程 /*窗口函数窗口函数*/LRESULT CALLBACK WndProc(HWND hwnd,UINT message
26、,WPARAM wParam, LPARAM lParam) /根据消息值转相应的消息处理根据消息值转相应的消息处理 switch (message) case WM_PAINT: /重画窗口客户区消息处理重画窗口客户区消息处理 HDC hdc; /定义定义设备描述表设备描述表句柄句柄 PAINTSTRUCT ps; /定义定义绘图信息结构变量绘图信息结构变量 /获取要重画的窗口的设备描述表句柄获取要重画的窗口的设备描述表句柄 hdc = BeginPaint (hwnd,&ps); TextOut (hdc,0,0,This is my Windows application”, 26);
27、/输出文本输出文本 EndPaint (hwnd,&ps);/结束重画,释放设备描述表句柄结束重画,释放设备描述表句柄 return 0;Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.1 传统的传统的Windows 编程编程 case WM_DESTROY:/撤消窗口消息处理撤消窗口消息处理 PostQuitMessage (0); /产生产生退出程序消息退出程序消息WM_QUIT return 0; retu
28、rn DefWindowProc (hwnd, message, wParam, lParam); /其它转缺省窗口函数其它转缺省窗口函数 程序的运行结果:程序的运行结果: Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.事件驱动、消息传递事件驱动、消息传递事件与消息:事件与消息:事件事件-在在WindowsWindows环境下,应用程序启动后,系统等待用环境下,应用程序启动后,系统等待用户在图形用户界面内的输入选择
29、,如户在图形用户界面内的输入选择,如鼠标按键、键盘按鼠标按键、键盘按键、窗口被创建、关闭、改变大小、移动键、窗口被创建、关闭、改变大小、移动等等, ,对系统来说,对系统来说,这都是事件。这都是事件。 只要有事件发生,系统即产生特定的只要有事件发生,系统即产生特定的消息消息。消息描述。消息描述了事件的类别,包含了相关信息,了事件的类别,包含了相关信息,WindowsWindows应用程序利用应用程序利用消息与系统及其它应用程序进行信息交换。消息与系统及其它应用程序进行信息交换。 由于由于windowswindows事件的发生的是随机的,程序的执行先后事件的发生的是随机的,程序的执行先后顺序也无法
30、预测,系统采用顺序也无法预测,系统采用消息队列消息队列来存放事件发生的来存放事件发生的消息,然后从消息队列中依次取出消息进行相应的处理。消息,然后从消息队列中依次取出消息进行相应的处理。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.事件驱动、消息传递事件驱动、消息传递消息结构的定义如下:消息结构的定义如下: typedef struct tagMSG HWND hWnd;/指定消息发向的窗口句柄指定消息发向的窗口
31、句柄UINTmessage;/标识消息的消息值标识消息的消息值WPARAMwParam;/消息参数消息参数LPARAM lParam;/消息参数消息参数DWORD time;/消息进入队列的时间消息进入队列的时间POINTpt;/消息进入队列时鼠标指针的屏幕坐标消息进入队列时鼠标指针的屏幕坐标 MSG,*PMSG,NEAR *NPMSG, FAR * LPMSG;Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.事件驱
32、动、消息传递事件驱动、消息传递消息结构中各个成员的意义:消息结构中各个成员的意义:message是标识消息的消息值或消息名。每个消息都有是标识消息的消息值或消息名。每个消息都有唯一一个数值标识唯一一个数值标识,常用不同前缀的,常用不同前缀的符号常量符号常量以示区别。例以示区别。例如,如,WM_WM_表示窗口消息表示窗口消息 。 Windows常用的窗口消息和消息值定义于常用的窗口消息和消息值定义于winuser.h中中#define WM_CREATE 0X0001 /创建窗口产生的消息创建窗口产生的消息#define WM_DESTROY 0X0002 /撤销窗口产生的消息撤销窗口产生的消息
33、#define WM_PAINT 0X000F /重画窗口产生的消息重画窗口产生的消息#define WM_CLOSE 0X0010 /关闭窗口产生的消息关闭窗口产生的消息#define WM_CHAR 0X0102 /按下非系统键产生的字符消息按下非系统键产生的字符消息#define WM_USER 0X0400 /用户自定义消息用户自定义消息 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.事件驱动、消息传递事件
34、驱动、消息传递wParam,lParam消息参数,均为消息参数,均为32位位其其数据类型数据类型在在windef.h中定义如下:中定义如下: typedef UINT WPARAM; typedef LONG LPARAM;pt表示消息进入消息队列时鼠标指针的屏幕坐标,表示消息进入消息队列时鼠标指针的屏幕坐标,数据类型数据类型POINT是定义在是定义在windef.h中的结构体,表示屏中的结构体,表示屏幕上一点,定义如下:幕上一点,定义如下: typedef struct tagPOINT LONG x;/表示点的屏幕横坐标表示点的屏幕横坐标 LONG y;/表示点的屏幕纵坐标表示点的屏幕纵坐
35、标 POINT, *PPOINT,NEAR *NPPOINT,FAR *LPPOINT;Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.Windows数据类型数据类型数据类型数据类型说说 明明BYTE8位无符号字符位无符号字符PSTR32位字符指针位字符指针COLORREF32位整数,表示一个颜色位整数,表示一个颜色WORD16位无符号整数位无符号整数LONG32位有符号整数位有符号整数DWORD32位无符号整数,是
36、位无符号整数,是WORD的两倍长度的两倍长度UINT32位无符号整数位无符号整数BOOL布尔值,值为布尔值,值为TRUE或或FALSEHANDLE句柄句柄常用常用windows数据类型:数据类型:Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.Windows数据类型数据类型数据类型数据类型说说 明明LPSTR32位指针,指向字符位指针,指向字符LPCSTR32位指针,指向字符串常量位指针,指向字符串常量LPTSTR3
37、2位指针,指向字符串,此字符串可移植到位指针,指向字符串,此字符串可移植到Unicode和和DBCS双字符集双字符集LPCTSTR32位指针,指向字符串常量,此串可移植到位指针,指向字符串常量,此串可移植到Unicode和和DBCS双字符集双字符集LPVOID32位指针,可指向任何类型数据位指针,可指向任何类型数据LPRESULT32位数值,作为窗口函数或位数值,作为窗口函数或CALLBACK函数的返回类型函数的返回类型WNDPROC32位指针,指向一个窗口函数位指针,指向一个窗口函数LPARAM32位数值,作为窗口函数和位数值,作为窗口函数和CALLBACK函数的参数函数的参数WPARAM作
38、为窗口函数和作为窗口函数和CALLBACK函数的参数,在函数的参数,在win 16中是中是16位,在位,在win 32中是中是32位位Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.窗口类及其使用步骤窗口类及其使用步骤窗口结构类型:窗口结构类型: typedef struct tagWNDCLASS UINT style; /窗口风格窗口风格 WNDPROC lpfnWndProc; /指向窗口处理函数的函数指针指向
39、窗口处理函数的函数指针 int cbClsExtra; /窗口结构中的预留字节数窗口结构中的预留字节数 int cbWndExtra; /为其它创建窗口预留字节数为其它创建窗口预留字节数 HINSTANCE hInstance; /注册该窗口类的实例句柄注册该窗口类的实例句柄 HICON hIcon; /代表该窗口类的图标句柄代表该窗口类的图标句柄 HCURSOR hCursor; / 该窗口客户区鼠标光标句柄该窗口客户区鼠标光标句柄 HBRUSH hbrBackGround; /该窗口背景颜色句柄该窗口背景颜色句柄 LPCSTR lpszMenuName; /指向窗口菜单名的字符指针指向窗口
40、菜单名的字符指针 LPCSTR lpszClassName; /指向窗口名的字符指针指向窗口名的字符指针 WNDCLASS, *PWNDCLASS,NEAR *NPWNDCLASS, FAR *LPWNDCLASS;Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.窗口类及其使用步骤窗口类及其使用步骤nWinMain()WinMain()函数完成第一项工作函数完成第一项工作建立一个窗口建立一个窗口(1) (1) 定义一
41、个窗口类定义一个窗口类,包括定义窗口对象并对它的相关成员赋,包括定义窗口对象并对它的相关成员赋值。值。(2) (2) 注册窗口类注册窗口类,调用,调用RegisterClass()RegisterClass()注册窗口类,并判断注册窗口类,并判断是否注册成功。其参数是是否注册成功。其参数是WNDCLASSWNDCLASS结构类型指针,用需要结构类型指针,用需要注册的窗口对象地址进行调用。注册的窗口对象地址进行调用。(3) (3) 创建窗口创建窗口,定义注册窗口后,可以创建一个或多个同类型,定义注册窗口后,可以创建一个或多个同类型的窗口;由的窗口;由APIAPI函数函数CreateWindow(
42、)CreateWindow()创建窗口,并返回所创创建窗口,并返回所创建窗口的句柄。建窗口的句柄。(4) (4) 调用调用APIAPI函数函数ShowWindow()ShowWindow()和和UpdateWindow()UpdateWindow()显示并更新显示并更新窗口窗口,它们的参数相同,第一个参数是要显示的窗口句柄,它们的参数相同,第一个参数是要显示的窗口句柄,第二个参数是窗口显示的方式。第二个参数是窗口显示的方式。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyrig
43、ht 2004-2011 Aspose Pty Ltd.消息循环与消息传递消息循环与消息传递消息循环消息循环(while(while循环循环) ) GetMessage()函数从应用程序消息队列中函数从应用程序消息队列中读取消息读取消息, TranslateMessage()函数进行函数进行键盘消息转换键盘消息转换,然后由,然后由DispatchMessag()将将消息派送消息派送给相应的窗口函数进行处理;当消息队列为空时,给相应的窗口函数进行处理;当消息队列为空时,应用程序进入等待状态,等待用户输入。应用程序进入等待状态,等待用户输入。 GetMessage()函数函数声明如下:声明如下:B
44、OOL WINAPI GetMessage (LPMSG, HWND, UINT, UINT );其中第其中第1个参数为存放消息的个参数为存放消息的MSG结构指针,第结构指针,第2个参数表示接个参数表示接收消息的窗口句柄,第收消息的窗口句柄,第3、4个参数分别表示要获取的最大和最个参数分别表示要获取的最大和最小消息值。当后小消息值。当后3个参数值设为个参数值设为NULL或或0时,表示应用程序接时,表示应用程序接收它所创建的所有窗口的所有消息。收它所创建的所有窗口的所有消息。当当GetMessage()获取到获取到WM_QUIT消息时,返回消息时,返回FALSE,结束,结束消息循环。消息循环。E
45、valuation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.消息循环与消息传递消息循环与消息传递TranslateMessage()函数函数负责键盘消息转换。负责键盘消息转换。 击键消息除字符键消息外,其它击键操作产生击键消息除字符键消息外,其它击键操作产生虚拟键消息,包括虚拟键消息,包括WM_KEYDOWNWM_KEYDOWN,WM_SYSKEYDOWNWM_SYSKEYDOWN,WM_KEYUPWM_KEYUP,WM_SYSK
46、EYUPWM_SYSKEYUP,这些虚拟键消息必须通,这些虚拟键消息必须通过转换成字符消息程序才能响应。过转换成字符消息程序才能响应。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.消息循环与消息传递消息循环与消息传递消息派送流程消息派送流程 DispatchMessage函数函数根据消息所包含的信息,将消息派送到相应的根据消息所包含的信息,将消息派送到相应的窗口函数,过程如图:窗口函数,过程如图: hWndMes
47、sagewParawIparamTimePtMSGEx2_2Ex2_2HWNDStyleWndprocEx2_2Ex2_2WNDCLASSEvaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.窗口处理函数窗口处理函数 WndProc() 应用程序创建的每一个窗口或对话框都对应一个窗口处应用程序创建的每一个窗口或对话框都对应一个窗口处理函数,处理来自窗口的消息。对于应用程序,理函数,处理来自窗口的消息。对于应用程序,WinM
48、ain()WinMain()函函数都差不多,编程的主要任务就是编写窗口函数。数都差不多,编程的主要任务就是编写窗口函数。WndProc()WndProc()的原型如下:的原型如下:LRESULT CALLBACK WndProc(HWND hwnd,UINT message, LRESULT CALLBACK WndProc(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);WPARAM wParam, LPARAM lParam);其中,第一个参数表示对应窗口的句柄,第二个参数是需要其中,第一个参数表示对应窗口的句柄,第二个参数是需要
49、处理的消息的消息值,第三、四个参数包含了相应消息的某处理的消息的消息值,第三、四个参数包含了相应消息的某些信息,如消息发生时鼠标位置等。些信息,如消息发生时鼠标位置等。 WndProc()WndProc()函数的结构是一个函数的结构是一个switchswitch语句,根据消息值不语句,根据消息值不同,选择不同的同,选择不同的casecase子句执行,如子句执行,如WM_PAINTWM_PAINT消息表示窗口客消息表示窗口客户区需要重画,户区需要重画,WM_DESTROYWM_DESTROY消息表示窗口要被撤销等。如果消息表示窗口要被撤销等。如果messagemessage参数的值与各个参数的值
50、与各个casecase子句的常量都不同,则调用子句的常量都不同,则调用DefWindowProcDefWindowProc()()函数处理。函数处理。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.进队和不进队消息进队和不进队消息 窗口函数一般由系统调用窗口函数一般由系统调用,应用程序不直接调用它,而是,应用程序不直接调用它,而是通过通过PostMessage()PostMessage()和和SendMessage(
51、)SendMessage()函数传递消息来函数传递消息来间接调间接调用用窗口函数。消息分为进队消息和不进队消息。窗口函数。消息分为进队消息和不进队消息。 (1) (1) 进队消息进队消息是由是由windowswindows放入应用程序消息队列、由应放入应用程序消息队列、由应用程序消息循环从消息队列中取出并派送到窗口函数的消息。用程序消息循环从消息队列中取出并派送到窗口函数的消息。进队消息一般由用户操作产生,如鼠标移动、点击产生的消进队消息一般由用户操作产生,如鼠标移动、点击产生的消息,键盘按键消息,重画窗口消息等。调用息,键盘按键消息,重画窗口消息等。调用APIAPI函数函数PostMessa
52、gePostMessage()()可以可以邮送邮送(post)(post)一条消息一条消息到指定窗口的消息队列到指定窗口的消息队列,其原型,其原型如下:如下:BOOL WINAPI PostMessage(HWND hWnd, UINT Msg, BOOL WINAPI PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) ;WPARAM wParam, LPARAM lParam) ;其中其中MsgMsg参数指定了要发送的消息值参数指定了要发送的消息值( (名名) )。PostQuitMessagePostQuitMes
53、sage()()调用本函数邮送消息。调用本函数邮送消息。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.进队和不进队消息进队和不进队消息 (2) 不进队消息不进队消息,直接,直接发送发送(send)(send)给指定窗口的窗口函数进行给指定窗口的窗口函数进行处理。处理。程序中调用某些特定的程序中调用某些特定的APIAPI函数会产生不进队消息函数会产生不进队消息。如调。如调用用CreateWindow()CreateW
54、indow()创建窗口时发送的创建窗口时发送的WM_CREATEWM_CREATE消息,调用消息,调用UpdateWindowUpdateWindow()()更新窗口时发送的更新窗口时发送的WM_PAINTWM_PAINT消息及调用消息及调用DestroyWindow()DestroyWindow()时发时发送的送的WM_DESTROYWM_DESTROY消息都是不进队消息。消息都是不进队消息。可以通过调用可以通过调用SendMessage()SendMessage()函数直接发送消息给窗口函数直接发送消息给窗口:LRESULT WINAPI SendMessage(HWND hWnd,UIN
55、T Msg,LRESULT WINAPI SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);WPARAM wParam,LPARAM lParam);有的不进队消息来自进队消息,如退出应用程序时会产生一条有的不进队消息来自进队消息,如退出应用程序时会产生一条进队消息进队消息WM_CLOSEWM_CLOSE,消息循环将其派送到窗口函数,处理这一,消息循环将其派送到窗口函数,处理这一消息一般是调用消息一般是调用DestroyWindow()DestroyWindow()函数撤销并关闭窗口,并发送函数撤销并关闭窗口,并发送不进队消
56、息不进队消息WM_DESTROYWM_DESTROY到窗口函数。有的用户操作可能既产生到窗口函数。有的用户操作可能既产生进队消息,又产生不进队消息。进队消息,又产生不进队消息。消息是否进入队列由消息是否进入队列由WindowsWindows自自行操作,程序设计人员只要关心窗口函数的编写行操作,程序设计人员只要关心窗口函数的编写。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.设备描述表设备描述表绘图信息数据结构定义:
57、绘图信息数据结构定义:typedef struct tagPAINTSTRUCTHDC hdc;/ 设备描述表句柄设备描述表句柄 BOOL fErase; / 布尔值,若背景要重画,则为非布尔值,若背景要重画,则为非0,否则为,否则为0RECT rcPaint;/ 指定窗口客户区无效区域指定窗口客户区无效区域BOOL fRestore;/ 保留保留BOOL fIncUpdate;/ 保留保留BYTE rgbReserved32;/ 保留保留PAINTSTRUCT,* PPAINTSTRUCT,* NPPAINTSTRUCT, *lPPAINTSTRUCT;Evaluation only.Cre
58、ated with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.设备描述表设备描述表 WM_PAINTWM_PAINT是重画窗口客户区消息,当窗口内是重画窗口客户区消息,当窗口内容被改变、移动或窗口被覆盖后,需要对窗口进容被改变、移动或窗口被覆盖后,需要对窗口进行重画,一般应用程序都需要处理这个消息,处行重画,一般应用程序都需要处理这个消息,处理这一消息需要获取理这一消息需要获取设备描述表设备描述表句柄。句柄。 Windows Windows的的图形设备接口图形设备接口
59、GDIGDI是一组是一组APIAPI函数,函数,它提供与它提供与设备无关的图形功能设备无关的图形功能,使应用程序在不,使应用程序在不同图形设备同图形设备( (如打印机,显示器、绘图仪等如打印机,显示器、绘图仪等) )上进上进行相同的操作行相同的操作( (调用调用GDIGDI函数函数) ),而无需考虑设备,而无需考虑设备的硬件差异,设备无关性是通过的硬件差异,设备无关性是通过设备描述表设备描述表实现实现的。的。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004
60、-2011 Aspose Pty Ltd.设备描述表设备描述表 设备描述表设备描述表 (Device Context,DC) (Device Context,DC)也称为也称为设备上下设备上下文文,是,是GDIGDI内部定义的一个有图形对象、图形方式及其属内部定义的一个有图形对象、图形方式及其属性的一个数据结构,与特定设备相关,描述了硬件设备性的一个数据结构,与特定设备相关,描述了硬件设备的具体特征信息。如需要执行显示任务,就构造一个显的具体特征信息。如需要执行显示任务,就构造一个显示设备的示设备的DCDC,获得其句柄;例如,需要执行打印任务,获得其句柄;例如,需要执行打印任务,则构造一个打印
61、设备的则构造一个打印设备的DCDC,获得其句柄,获得其句柄,GDIGDI函数以该句函数以该句柄为参数完成相应任务。与具体设备相关的操作交给柄为参数完成相应任务。与具体设备相关的操作交给DCDC,将应用程序的设备无关图形功能调用转换为在设备驱,将应用程序的设备无关图形功能调用转换为在设备驱动程序下执行的设备相关操作。动程序下执行的设备相关操作。 应用程序不能直接访问设备描述表,为了进行图形应用程序不能直接访问设备描述表,为了进行图形输出,必须先获取设备描述表句柄,然后以设备描述表输出,必须先获取设备描述表句柄,然后以设备描述表句柄为参数调用句柄为参数调用GDIGDI函数,实现图形功能。函数,实现
62、图形功能。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.2 Windows对象句柄对象句柄 句柄的概念:句柄的概念: 早期的句柄早期的句柄Handle是一个是一个16位的代号。在位的代号。在DOS操作系统操作系统中,必须用带路径的文件名,句柄是文件的代号,文件读中,必须用带路径的文件名,句柄是文件的代号,文件读/写写时只用这个代号就行了,而不必用很长的路径名。时只用这个代号就行了,而不必用很长的路径名。 文件句
63、柄只是一个代号,它不是文件的地址。文件句柄只是一个代号,它不是文件的地址。地址信息放地址信息放在文件句柄指向的内存中特定的文件管理区域的一个单元中,在文件句柄指向的内存中特定的文件管理区域的一个单元中,那里存放了入口地址和有关文件的其它信息那里存放了入口地址和有关文件的其它信息。 句柄的数据类型在句柄的数据类型在winnt.h中说明如下:中说明如下:typedef void * HANDLE;所以所以从物理上看从物理上看句柄是一个句柄是一个泛型(无类型)指针泛型(无类型)指针。但它但它不是指不是指向一个向一个Windows对象的存储首地址,而是指向包含了使用该对象的存储首地址,而是指向包含了使
64、用该对象有关信息的一块内存单元对象有关信息的一块内存单元。所以从逻辑上说它是一个代号,。所以从逻辑上说它是一个代号,一个一个对象的代号对象的代号。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.2 Windows对象句柄对象句柄句柄的使用:句柄的使用: 句柄所指向的句柄所指向的内容是不能由句柄操作来改变的,只能由系内容是不能由句柄操作来改变的,只能由系统来改变统来改变。句柄。句柄允许做的唯一操作是检查它是否是一
65、个有效句允许做的唯一操作是检查它是否是一个有效句柄柄。不等于零是一个有效句柄,等于零是无效句柄。不等于零是一个有效句柄,等于零是无效句柄。 Windows操作系统中所谓操作系统中所谓“句柄句柄”(handle)是唯一标)是唯一标识某个识某个Windows对象(如程序实例、窗口、图标、光标、画对象(如程序实例、窗口、图标、光标、画刷、菜单等)的一个刷、菜单等)的一个32位无符号整数,句柄是位无符号整数,句柄是Windows对象对象的代号。的代号。 Windows程序通常通过调用程序通常通过调用win32 API函数来获得某个函数来获得某个Windows对象的句柄,只有有了句柄,程序才能使用与其对
66、对象的句柄,只有有了句柄,程序才能使用与其对应的应的Windows对象。形象地讲,对象。形象地讲,对象是学生,句柄是学号对象是学生,句柄是学号。 建立一个建立一个Windows对象,自然就建立起一个实例句柄。对象,自然就建立起一个实例句柄。要使一个句柄无效只须撤消对该对象的引用,不要销毁句柄。要使一个句柄无效只须撤消对该对象的引用,不要销毁句柄。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.2 Windows对
67、象句柄对象句柄表表2.1 常用常用Windows句柄类型句柄类型句柄句柄类型型说明明句柄句柄类型型说明明HANDLE一般句柄一般句柄类型型HICON图标句柄句柄类型型HWND窗口句柄窗口句柄类型型HCURSOR光光标句柄句柄类型型HINSTANCE 程序程序实例句柄例句柄HBRUSH画刷句柄画刷句柄类型型HDC设备描述表句柄描述表句柄HPEN画笔句柄画笔句柄类型型HMENC菜菜单句柄句柄类型型HFONT字体句柄字体句柄类型型HBITMAP位位图句柄句柄类型型HFILE文件句柄文件句柄类型型Evaluation only.Created with Aspose.Slides for .NET 3
68、.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.3 MFC基础类及其层次结构基础类及其层次结构MFCMFC开发的思路与过程:开发的思路与过程: 19891989年年微微软软成成立立了了Application Application FrameworkFramework(应应用用程程序序框框架架)开开发发小小组组(AFXAFX),其其目目的的是是要要建建立立一一个个图图形形应应用用程程序序的的通通用用C+C+类类库库,这这是是一一个个单单一一的的类类库库,可可以以用用来来简简化化所所有有主主流流微微机机操操作作系系统统
69、应应用用程程序序的的开开发发,AFXAFX希希望望利利用用面面向向对对象象的的技技术术来来建建立立一一个个易易于使用的可移植的用户图形界面于使用的可移植的用户图形界面(GUIGUI)。)。 一一年年后后失失败败,最最主主要要的的原原因因是是目目标标太太理理想想化化,AFXAFX小小组组过过分分信信任任面面向向对对象象的的程程序序设设计计方方法法的的能能力力,纯纯粹粹抽抽象象的的类类,理理想想而而不不实实用用。因因此此,AFXAFX小小组组转转向向开开发发MFCMFC库库,目目标标不不再再理理想想,但但是是实实用用。不不再再追追求求多多平平台台,而而是是采采取取对对Windows Windows
70、 APIAPI函函数数进进行行便便于于使使用用的的封封装装。不不再再试试图图建建立立纯纯粹粹抽抽象象的的类类,而而是是重重点点建建立立切切实实可可行行的的类类。不不再再使使用用C+C+中中复复杂杂的的多多重重继继承承。不不追追求求对对APIAPI函函数数进进行行完完美美的的封封装装,而而使使用用户户可可以以方方便便地地调调用用APIAPI函函数数直直接接完完成成某某些些任任务务,即即不不追求纯粹的面向对象的程序设计,而是相当的宽容追求纯粹的面向对象的程序设计,而是相当的宽容。Evaluation only.Created with Aspose.Slides for .NET 3.5 Clie
71、nt Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.3 MFC基础类及其层次结构基础类及其层次结构AFXAFX小组的小组的MFCMFC开发设计的原则:开发设计的原则:1. 使用使用C+进行进行Windows应用程序设计的过程应简单和直观。应用程序设计的过程应简单和直观。2. 用类封装用类封装Windows API和和Windows对象,并按照对象,并按照API的方式的方式进行工作。进行工作。3. 使用标准的使用标准的Windows命令的约定和编码风格。命令的约定和编码风格。4. 类库应有足够的可扩展性,以便跟随类库应有足够的可扩展性,
72、以便跟随Windows的更新发展。的更新发展。5. 能更方便地使用能更方便地使用API函数,采用函数,采用Windows API的概念,函数和的概念,函数和编程风格。编程风格。从这里可以看出从这里可以看出MFC和和Windows很好地连接起来,使很好地连接起来,使Windows下的下的C语言程序设计,成为面向对象的语言程序设计,成为面向对象的MFC。这里没有追求纯粹,。这里没有追求纯粹,而是而是包容和实用包容和实用! Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright
73、2004-2011 Aspose Pty Ltd. MFC是采用是采用单一继承单一继承,从根类,从根类Cobject层层派生出层层派生出绝大多数绝大多数MFC中的类,其层次结构是最典型。参见图中的类,其层次结构是最典型。参见图2 2.6 图图2 2.6 根类根类CObject分类派生图分类派生图 2.3 MFC基础类及其层次结构基础类及其层次结构Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.Cobject根类根类
74、CCmdTarget 命令相关类命令相关类 CDC设备环境类设备环境类 CClientDC、CWindowDC、CPaintDC、CGdiObject 绘画工具类绘画工具类 CPen、CBrush、CFont、CBitmap、CPalette、 CMenu菜单菜单 CArray、CList、CMap、 群(集合)类群(集合)类 CDatabase、CRecordset、 ODBC数据库支持数据库支持 CDatabase、CDataRecordset、 DAO数据库支持数据库支持CFile 文件类文件类 CMemFile、COleStreamFile、CSocketFile、CException
75、 异常类异常类CSyncObject 同步对象类同步对象类 CInternetSession 因特网会话类因特网会话类 CInternetConnection 因特网连接类因特网连接类 CFtpConnection、CGopherConnection、CHelpConnection图图2 2.7 Cobject派派生生类类层层次次示示意意图图 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.CObject根类根类CC
76、mdTarget 命令处理类命令处理类 CWinThread 线程类线程类 CDocument 文档类文档类 CDocTemplate 文档模板类文档模板类 CWnd 窗口类窗口类 CWinApp Windows应用程序类应用程序类 CSingleDocTemplate 单文档单文档模板类模板类 CMultiDocTemplate 多文多文档模板类档模板类图图2.8 应应用用程程序序结结构构Cobject根类派生的最重要的类组成一个应用程序结构根类派生的最重要的类组成一个应用程序结构(Application Architecture)的集合,它是由的集合,它是由CCmdTarget为为基类派生
77、出来的,其中主要部分参见图基类派生出来的,其中主要部分参见图2.10。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.CFrameWnd 框架窗口类框架窗口类 CControlBar 控制条类控制条类 CSplitterWnd 窗口分割类窗口分割类 CPropertSheet 属性表类属性表类 CMDIFrameWnd、CMDIChildWnd、CMiniFrameWnd CDialogBar、CToolBar、CS
78、tatusBarCWnd 窗口类窗口类 CDialog 对话框类对话框类 CCommonDialog 公用对话框类公用对话框类CProperty 属性页表属性页表 CFileDialog、CColorDialog、 图图2.8 应用应用程序程序结构结构Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.CView 视图类视图类控制类控制类 CButton、CEdit、CListBox、CScrollBar、CStatic
79、、CComboBoxCCtrlViewCFormViewCEditView、CListView、CTreeView、CRichEditViewCRecordView 图图2.8 应用应用程序程序结构结构基类基类CobjectCobject的最基本功能:的最基本功能:1. 支持序列化支持序列化(serialization)。序列化指如何让一个对象保持持)。序列化指如何让一个对象保持持久不变,即把对象成员数据内容存入一个文件或从一个文件中读取久不变,即把对象成员数据内容存入一个文件或从一个文件中读取内容重构对象的过程。内容重构对象的过程。2. 运行时(运行时(Run-time)类的信息获取)类的信
80、息获取。3. 提供特定的提供特定的new,delete和和=操作符操作符,完成对象的建立与删除。,完成对象的建立与删除。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程标准标准WindowsWindows程序设计:程序设计: VC+的微软基础类库(的微软基础类库(Microsoft Foundation Class Library,MFC)封装了大部分)封装了大部分API函数,并提供了函数,并
81、提供了一个应用程序框架,简化了和标准了一个应用程序框架,简化了和标准了Windows程序设计程序设计,所以用所以用MFC编写编写Windows应用程序也称为应用程序也称为标准标准Windows程序设计。程序设计。 标准标准Windows程序设计程序设计把传统的把传统的Windows程序设计程序设计转向转向C+面向对象的面向对象的Windows程序设计程序设计 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 M
82、FC 编程编程MFCMFC简介:简介: MFC约有约有200个类,提供了个类,提供了Windows应用程序框架应用程序框架和创建应用程序的组件。其中只有和创建应用程序的组件。其中只有5个核心类对应用程序个核心类对应用程序框架有影响:框架有影响:Cwinapp,Cdocument,Cview,CFrameWnd和和CDocTemplate。 五个之中只有五个之中只有Cwinapp是必不可少的类,是必不可少的类,Cwinapp的对象在应用程序中必须有一个,也只有一个,并是一个的对象在应用程序中必须有一个,也只有一个,并是一个全局对象,它建立了应用程序执行的全局对象,它建立了应用程序执行的主线程主线
83、程(线程的概念(线程的概念参见本节后的附录)。全局对象是在参见本节后的附录)。全局对象是在MFC初始化之前,也初始化之前,也即当即当Windows操作系统调用操作系统调用WinMain( )时,这个对象就时,这个对象就先已建立,即主线程已建立。形象地说,执行程序的通路先已建立,即主线程已建立。形象地说,执行程序的通路已经开通。已经开通。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程入口函数
84、:入口函数: 在在MFC编编程程中中,入入口口函函数数WinMain( )被被封封装装在在MFC的的应应用用程程序序框框架架内内,已已经经不不用用也也不不可可以以再再定定义义另另一一个个WinMain()函数。函数。应用程序向导:应用程序向导:MFC编程使用编程使用MFC的的应用程序向导应用程序向导工具:工具: AppWizard AppWizard为程序员提供了一种快捷方便的工具来为程序员提供了一种快捷方便的工具来定制基于定制基于MFC的应用程序框架,程序员只需以此为基础,的应用程序框架,程序员只需以此为基础,添加与修改程序代码来实现所需功能。添加与修改程序代码来实现所需功能。MFC编程包含
85、三种编程包含三种类型的应用程序:类型的应用程序:单文档界面单文档界面(SDI)应用程序、)应用程序、多文档多文档界面界面(MDI)应用程序和)应用程序和基于对话框基于对话框(Dialog Based)的)的应用程序,它们都可以由应用程序,它们都可以由AppWizard引导建立起来。引导建立起来。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程接口与封装:接口与封装: 在在类类中中必必须须有有
86、一一部部分分成成员员函函数数置置为为公公有有,专专供供类类外外程程序语句访问,这些函数亦称序语句访问,这些函数亦称接口函数接口函数。 其其余余成成员员函函数数是是故故意意对对外外隐隐蔽蔽起起来来的的操操作作,它它们们是是最最复复杂杂最最关关键键的的部部分分,越越是是复复杂杂越越是是关关键键就就越越能能体体现现出出使使用用类封装的必要和优越。类封装的必要和优越。 类类中中故故意意的的隐隐藏藏也也为为以以后后的的升升级级扩扩展展留留下下了了余余地地,只只要要接接口口不不变变,内内部部再再变变,也也不不必必修修改改原原来来的的程程序序,就就象象MFC(微微软软基基础础类类)升升级级后后,由由MFC底
87、底层层类类所所编编的的程程序序完完全不必修改,自动升级。全不必修改,自动升级。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程 封封装装有有助助于于编编程程人人员员在在处处理理好好简简单单接接口口后后,集集中中精精力力处处理理高高层层次次开开发发的的工工作作,MFC能能被被广广泛泛使使用用也也正正是是有有此此优优点点。用用户户界界面面等等的的编编程程是是底底层层的的十十分分复复杂杂和和困困难
88、难的的事事,MFC给给解解决决了了。程程序序员员只只管管自自己己特特定定的的任任务务,编编程程的的效效率率和和可可靠靠性性大大大大提提高。高。使用接口的优点:使用接口的优点:Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程进程和线程进程和线程进程(进程(processprocess) :运行中的程序称为进程,程序是一个静态的概念,进程是一个运行中的程序称为进程,程序是一个静态的概念,进程是一个
89、动态的概念。动态的概念。进程的组成:进程的组成:(1)一段可执行程序(代码)一段可执行程序(代码)(2)程序所需的相关数据(变量、工作空间、缓冲区等)程序所需的相关数据(变量、工作空间、缓冲区等)(3)程序执行的上下文环境程序执行的上下文环境其中其中执行上下文环境执行上下文环境(Execution Context)亦称)亦称进程状态进程状态(Process State),是最为重要的。它包括操作系统管理),是最为重要的。它包括操作系统管理进程以及处理器执行进程所需要的所有信息,包括处理器进程以及处理器执行进程所需要的所有信息,包括处理器的各寄存器的内容,还包括操作系统使用的信息,如进程的各寄存
90、器的内容,还包括操作系统使用的信息,如进程优先级以及进程是否在等待特定的输入输出事件完成。优先级以及进程是否在等待特定的输入输出事件完成。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程进程和线程进程和线程进程的属性与线程(进程的属性与线程(threadthread) :(1)资源所有权:一个进程包括一个保存进程映像的虚拟资源所有权:一个进程包括一个保存进程映像的虚拟地址空间,并随时分配对资
91、源的控制或所有权,包括内地址空间,并随时分配对资源的控制或所有权,包括内存、存、I/O通道、通道、I/O设备和文件。设备和文件。(2)调度调度/执行:进程沿着通过一个或多个程序间的执行路执行:进程沿着通过一个或多个程序间的执行路径运行,它与其他进程的执行路径相互交错。径运行,它与其他进程的执行路径相互交错。把两者分开,把两者分开,执行部分(它实际是被操作系统调度并分配执行部分(它实际是被操作系统调度并分配的实体)称为线程(的实体)称为线程(thread)。而。而资源所有权的部分仍资源所有权的部分仍称作进程称作进程。一个进程可以拥有多个线程。一个进程可以拥有多个线程。Evaluation onl
92、y.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程进程和线程进程和线程线程的优点:线程的优点:与无线程的进程相比速度大为提高,原因是:与无线程的进程相比速度大为提高,原因是:(1)在已有进程中创建一个新线程速度比创建一个全新在已有进程中创建一个新线程速度比创建一个全新的进程快得多(可达的进程快得多(可达10倍)。倍)。(2)终止一个线程比终止一个进程花费时间少。终止一个线程比终止一个进程花费时间少。(3)线程间切换比进程间
93、切换花费时间少。线程间切换比进程间切换花费时间少。(4)同一进程的线程共享存储空间和文件,无需调用操同一进程的线程共享存储空间和文件,无需调用操作系统内核就可进行通信,效率大大提高。作系统内核就可进行通信,效率大大提高。所以所以现代的操作系统多为多进程多线程的操作系统现代的操作系统多为多进程多线程的操作系统。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.4 MFC 编程编程进程和线程进程和线程进程进程- -线程
94、线程- -窗口:窗口:32位位Windows管管理理运运行行的的程程序序的的模模式式。当当创创建建一一个个进进程程的的同同时时也也创创建建了了第第一一个个线线程程,称称为为“主主线线程程”。主主线线程程的的入入口口函函数数是是WinMain (相相当当于于控控制制台台应应用用程程序序的的main函函数数)。之之后后,主主线线程程可可以以在在进进程程中中再再创创建建一一个个或或多多个个线线程程,即即“多多线程线程”,多个线程共享进程的静态部分,多个线程共享进程的静态部分(资源,地址等资源,地址等)。进程进程1进程进程2线程线程1.1线程线程1.2线程线程1.3窗口窗口1.1.1窗口窗口1.1.2
95、窗口窗口1.3.1线程线程2.1窗口窗口2.1.1图图2.9 进程、线程与窗口进程、线程与窗口Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.5 MFC对象和对象和Windows对象对象MFC对象:对象:特指封装了特指封装了Window对象的对象的C+对象。对象。 本节讨论本节讨论MFC对象与对象与Window对象的联系,以最典型的的对象的联系,以最典型的的窗口类(窗口类(CWnd)为例,讨论)为例,讨论CWnd
96、类对象与类对象与Windows窗口窗口对象的关系。对象的关系。.其它成员其它成员m_hWndhwndCWnd类对象类对象HWND句柄类型句柄类型wndwindows对象句柄对象句柄Windows操操 作作 系系 统统窗口对象窗口对象图图2.10 MFC窗口对象与窗口对象与Windows窗口对象的关系窗口对象的关系Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.MFC的的窗窗口口对对象象wnd是是C+类类的的实实例例,
97、即即CWnd类类或或其其派派生生类类的实例。的实例。hwnd是是HWND句句柄柄类类型型的的实实例例,为为它它建建立立了了一一个个Windows操操作作系系统统的的对对象象。然然后后把把这这个个句句柄柄放放入入CWnd类类对对象象wnd的的成成员员数数据据m_hwnd中中。这这样样wnd就就包包含含了了一一个个Windows操操作作系系统的窗口对象。统的窗口对象。参考程序段如下:参考程序段如下: CWnd wnd; /定义窗口类(定义窗口类(CWnd)的对象)的对象wndHWND hwnd; /定义窗口句柄定义窗口句柄hwndhwnd=CreateWindows(.);/调用调用API函数函数
98、CreateWindows(.)建立一个建立一个Windows窗口类实例窗口类实例wnd.Attach(hwd);/把把Windows窗口实例的句柄链到窗口实例的句柄链到CWnd对象对象hwnd上上.Destrory Window(hwnd); /调用调用API函数撤消函数撤消Windows窗口窗口 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.5 MFC对象和对象和Windows对象对象MFCMFC对象和对应
99、对象和对应WindowsWindows对象:对象: MFC封装了几乎所有封装了几乎所有Windows的的API函数,所以上面的函数,所以上面的API函数,可以用函数,可以用CWnd的成员函数代替。的成员函数代替。 成员函数成员函数Create()可以代替可以代替API函数函数CreateWindows()并加上另一个成员函数并加上另一个成员函数Attach()的全部功能,建立一个的全部功能,建立一个Windows操作系统的窗口对象,并把句柄自动保存在操作系统的窗口对象,并把句柄自动保存在MFC窗口对象窗口对象wnd的的m_hwnd成员数据中。通常成员数据中。通常MFC程序员直程序员直接使用接使
100、用CWnd的成员函数就可以了。的成员函数就可以了。 其它的其它的MFC对象和对应对象和对应Windows对象也有类似的关系。对象也有类似的关系。见表见表2.2 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.5 MFC对象和对象和Windows对象对象项目项目MFC类类对象句柄对象句柄应用程序应用程序CWinAppHINSTANCE m_hInstance窗口窗口CWndHWND m_hWnd菜单菜单CMenuH
101、MENU m_hMenu设备环境设备环境CDCHDC m_hDC矩形区域矩形区域CRgnHRGN m_hRgn画刷画刷CBrushHBRUSH m_hBrush画笔画笔CPenHPEN m_hPen字体字体CFontHFONT m_hFont位图位图CBitmapHBITMAP m_hBitmap调色板调色板CPalatteHPALATTE m_hPalatte表表2.2 常用常用MFC类与类与Windows对象句柄对应关系对象句柄对应关系Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0
102、.Copyright 2004-2011 Aspose Pty Ltd.2.5 MFC对象和对象和Windows对象对象 Windows窗口句柄通常是全局量,动窗口句柄通常是全局量,动态建立的态建立的Windows窗口对象也是全局性的。窗口对象也是全局性的。所以一个进程或线程可以取得另一个进程或所以一个进程或线程可以取得另一个进程或线程的窗口句柄,并给它线程的窗口句柄,并给它发送消息发送消息。注意:注意: 一个线程只能使用本线程创建的一个线程只能使用本线程创建的MFC窗窗口对象,不能使用其它线程创建的口对象,不能使用其它线程创建的MFC窗窗口对象。口对象。Evaluation only.Cre
103、ated with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.5 MFC对象和对象和Windows对象对象小结:小结:Windows对象是对象是Windows操作系统的一个内部数据结构的实操作系统的一个内部数据结构的实例,由一个例,由一个Windows系统全局的窗口句柄来唯一标志,由系统全局的窗口句柄来唯一标志,由API函函数数CreatWindow()创建,而由创建,而由DestroyWindow()撤消。撤消。在在MFC编程中,编程中,Windows对象通常在
104、对象通常在MFC对象建立以后,调对象建立以后,调用用Create() 建立建立Windows对象,并链接在对象,并链接在MFC对象上。对象上。建立应用程序的主框架窗口的程序段:建立应用程序的主框架窗口的程序段: CFrameWnd *pFrame=new CFrameWnd; /动态建立框架窗口对象动态建立框架窗口对象pFrame-Create(NULL,”Ex2_xx”,ws_OVERLAPPENDWINDOW,rect,NULL,MAKEINTRESOURCE(IDR_MENUI),0,NULL);/建立与动态框架窗口对象相连的建立与动态框架窗口对象相连的Windows框架窗口框架窗口Ev
105、aluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.6 MFC的消息映射的消息映射消息映射的概念:消息映射的概念: MFC由由CWinApp类检索和派送消息给相应的窗类检索和派送消息给相应的窗口函数,但是所有的口函数,但是所有的MFC窗口函数都使用同一个窗窗口函数都使用同一个窗口函数。口函数。 MFC把设计窗口的任务细化为设计若干消息处把设计窗口的任务细化为设计若干消息处理函数,程序员要做的是理函数,程序员要做的是为每一
106、个要处理的消息提为每一个要处理的消息提供一个消息处理(供一个消息处理(Handling Messages)函数)函数,然,然后系统通过后系统通过MFC提供的一套提供的一套消息映射系统消息映射系统(messages mapping system)来调用相应的消息)来调用相应的消息处理函数。消息映射就是消息与消息处理函数一对处理函数。消息映射就是消息与消息处理函数一对一的联系。一的联系。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose P
107、ty Ltd.2.6 MFC的消息映射的消息映射消息映射的模型:消息映射的模型:首先定义一个首先定义一个Msgmap的结构:的结构:struct Msgmap UINT nMessage; LONG(*pfn)(HWND,UINT,WPARAM,LPARAM); 第一个数据成员为消息标识代码,为无符号整型数。第第一个数据成员为消息标识代码,为无符号整型数。第二个数据成员是指向消息处理函数的长指针(实际上二个数据成员是指向消息处理函数的长指针(实际上Windows下全部为下全部为32位长指针)位长指针)。这样便建立了一个。这样便建立了一个一对一的映射关系。一对一的映射关系。Evaluation
108、only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.6 MFC的消息映射的消息映射 以这样的结构组成一个数组,以以这样的结构组成一个数组,以nMessage(消息代码)为关键字进行排序,(消息代码)为关键字进行排序,采用对半查找,这样可以很快找到所需要的指采用对半查找,这样可以很快找到所需要的指向消息处理函数的指针,进入消息处理函数进向消息处理函数的指针,进入消息处理函数进行消息处理。行消息处理。Evaluation only.Creat
109、ed with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.6 MFC的消息映射的消息映射消息分类:消息分类:窗口消息:窗口消息:由由MFC的窗口类(的窗口类(CWnd)对象来处理,)对象来处理,即这类消息处理函数一般是即这类消息处理函数一般是CWnd类的成员函类的成员函数。有缺省窗口处理函数数。有缺省窗口处理函数控制通知消息:控制通知消息:来自子窗口的通知消息。参数中来自子窗口的通知消息。参数中包含子窗口标识和通知码。通知码是子窗口定包含子窗口标识和通知码。通知码
110、是子窗口定义的一些常量。有缺省处理,但一般要重载。义的一些常量。有缺省处理,但一般要重载。 若若CWnd派生类没有重载上述两类消息处理函数,则消派生类没有重载上述两类消息处理函数,则消息映射机制会转由其基类处理(最终是息映射机制会转由其基类处理(最终是CWnd类);若类);若CWnd类也没有定义对应的消息处理函数,则调用类也没有定义对应的消息处理函数,则调用Windows默认的窗口函数处理。默认的窗口函数处理。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 200
111、4-2011 Aspose Pty Ltd.2.6 MFC的消息映射的消息映射命令消息处理:命令消息处理: 来自菜单、工具栏,加速键的通知消息,参数中来自菜单、工具栏,加速键的通知消息,参数中 包括包括命令标识(命令标识(ID)号,它是应用程序自定义的一)号,它是应用程序自定义的一 些常量,些常量,由程由程序员编写消息处理函数序员编写消息处理函数。MFC也定义了一些缺省的标准命令也定义了一些缺省的标准命令消息处理函数。消息处理函数。VC+有一个有一个 ClassWizard(类向导)(类向导),它会,它会帮助用户建立消息映射和消息处理函数的框架,消息和函数都帮助用户建立消息映射和消息处理函数的
112、框架,消息和函数都由由MFC缺省的命名方式命名。缺省的命名方式命名。 对于命令消息,对于命令消息,MFC应用程序框架会通过消息映射机制,应用程序框架会通过消息映射机制,按一定的按一定的搜索顺序搜索顺序在各个在各个CCmdTarget类(命令处理类)的派类(命令处理类)的派生类中查找对应消息处理函数。参见图生类中查找对应消息处理函数。参见图2.11(a)。 在编程序时应该让在编程序时应该让命令消息尽可能由与其关系密切的类命令消息尽可能由与其关系密切的类来处理来处理。也就是。也就是尽管消息处理函数可以任意安放在某一个类中,尽管消息处理函数可以任意安放在某一个类中,但那样可读性差,同时执行时也可能出
113、问题但那样可读性差,同时执行时也可能出问题。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.图图2.11 消息映射示意图消息映射示意图Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.6 MFC的消息映射的消息映射消息映射(消息映射(Me
114、ssage MappingMessage Mapping):): 图图2.11(a)表的示搜索的路线是按派生关系直线查找。)表的示搜索的路线是按派生关系直线查找。但是,处理消息的但是,处理消息的C+类并不呈直线发展,作为应用程序框类并不呈直线发展,作为应用程序框架的重要结构文档架的重要结构文档/视结构,同样也具有消息处理能力(文视结构,同样也具有消息处理能力(文档档/视结构在视结构在2.7节中讨论)。因此节中讨论)。因此消息的搜索路线消息的搜索路线是迂回曲是迂回曲折的,折的,如图如图2.11(b)所示)所示。 描述这个复杂的搜索路线的向导图就是总的消息映射表描述这个复杂的搜索路线的向导图就是总
115、的消息映射表(Message Map)。)。参见图参见图2.12。在每一个相关类的局部消在每一个相关类的局部消息映射表中查找对应的消息处理函数,直到找到为止。息映射表中查找对应的消息处理函数,直到找到为止。 这里给这里给每一个与消息有关的派生类建立一个局部消息映每一个与消息有关的派生类建立一个局部消息映射表,由系统沿派生关系,从当前所在类逐步向更深层次的射表,由系统沿派生关系,从当前所在类逐步向更深层次的基类搜索消息的处理函数。这样映射表成了一个个相对的较基类搜索消息的处理函数。这样映射表成了一个个相对的较小的表,系统是按一条固定路径去查找。小的表,系统是按一条固定路径去查找。在在MFC中这样
116、复杂中这样复杂分层的消息映射体系是由设计好的宏来完成的。分层的消息映射体系是由设计好的宏来完成的。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.图图2.12 消息映射表安排示意图消息映射表安排示意图Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty
117、Ltd.2.6 MFC的消息映射的消息映射消息映射表结构:消息映射表结构:消息入口表消息入口表为一链表,结点中有一个数据结构:为一链表,结点中有一个数据结构:struct AFX_MSGMAPAFX_MSGMAP* pBaseMessageMap;/指向基类消息映射入口,即入口表链的下一个结点指向基类消息映射入口,即入口表链的下一个结点AFX_M GMAP_ENTRY* lp Entries; /指向局部消息映射表的指针指向局部消息映射表的指针 /注意指针与数组和数组元素的关系注意指针与数组和数组元素的关系入口表第二个指针指向的入口表第二个指针指向的消息和消息处理函数消息和消息处理函数结构结构
118、 :struct AFX_MSGMAP_ENTRYUINT nMessage; /窗口消息的消息值窗口消息的消息值UINT nCode; /控制消息的通知码或控制消息的通知码或WM_NOTIFY码码UINT nID; /控制控制ID(0为窗口消息)为窗口消息)UINT nLastID; /用于指定控制用于指定控制ID的范围的范围UINT nSig; /消息行为类型或指向消息号的指针消息行为类型或指向消息号的指针AFX_PMSG pfn; /消息处理函数指针消息处理函数指针Evaluation only.Created with Aspose.Slides for .NET 3.5 Client
119、 Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.6 MFC的消息映射的消息映射程序程序类型型搜索路径搜索路径SDI单文档文档当前当前视图当前文档当前文档文档模板文档模板主框架窗口主框架窗口应用程序用程序对象象MDI多文档多文档当前当前视图当前文档当前文档创建文档的文档模板建文档的文档模板活活动的子框架窗的子框架窗口口主框架窗口主框架窗口应用程序用程序对象象对话框框当前当前对话框框对话框的父窗口框的父窗口应用程序用程序对象象命令消息相应消息处理函数搜索全过程:命令消息相应消息处理函数搜索全过程:由菜单、工具栏等用户界面对象产生的命令消息
120、,首先送给主框由菜单、工具栏等用户界面对象产生的命令消息,首先送给主框架窗口的标准架窗口的标准MFC窗口函数,然后窗口函数把命令传给窗口函数,然后窗口函数把命令传给MFC主主框架窗口对象,进行命令消息的派送,并按下表的次序进行消息框架窗口对象,进行命令消息的派送,并按下表的次序进行消息匹配。若找不到,则先继续搜索其基类的消息映射入口表,若仍匹配。若找不到,则先继续搜索其基类的消息映射入口表,若仍找不到,再迂回到下一个对象进行处理。找不到,再迂回到下一个对象进行处理。 都找不到,则由缺省的都找不到,则由缺省的Windows消息处理函数结束该命令消息消息处理函数结束该命令消息Evaluation
121、only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.6 MFC的消息映射的消息映射消息缓冲池:消息缓冲池:为了提高消息匹配的效率,为了提高消息匹配的效率,MFC内部有一个内部有一个消息消息缓冲池缓冲池,使用以消息值为关键字的散列(哈希),使用以消息值为关键字的散列(哈希)查找,这里可存放查找,这里可存放512条最近使用过的消息映射入条最近使用过的消息映射入口表项的有关信息(只需放入口表项,即两个指口表项的有关信息(只需放入口表项,即两个指
122、针)。仅在消息缓冲池中匹配不到才进行前文所针)。仅在消息缓冲池中匹配不到才进行前文所叙的搜索过程。叙的搜索过程。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.7 MFC中的文件处理中的文件处理MFC中的文件系统,是广义的文件系中的文件系统,是广义的文件系统。先讨论统。先讨论MFC的文档的文档/视结构视结构(Document/view),再讨论序列化),再讨论序列化(Serialization)与永久保存。)与永
123、久保存。 2.7.1 文档文档/视结构视结构 2.7.2 存档类序列化存档类序列化 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.7.1 文档文档/视结构视结构文档与视的概念:文档与视的概念:文文档档(document)指指的的是是数数据据组组合合的的抽抽象象,它它通通常常对对应应磁磁盘盘文文件件,也也可可以以对对应应I/O端端口口(包包括打印机、键盘)或一块内存空间(串流)。括打印机、键盘)或一块内存空间(串
124、流)。同样的数据,我们可以用不同的方式来表示。同样的数据,我们可以用不同的方式来表示。把纯的数据放在文件中或数据库中。而把显示方把纯的数据放在文件中或数据库中。而把显示方式分离出来,可以让一份数据有多种不同的显示式分离出来,可以让一份数据有多种不同的显示方式,程序中的方式,程序中的数据表现数据表现称为称为“视视” (view)。)。这样就可以这样就可以分别考虑数据的保存分别考虑数据的保存文档文档,和数,和数据的表现据的表现视视。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyr
125、ight 2004-2011 Aspose Pty Ltd.2.7.1 文档文档/视结构视结构 MFC提提供供了了一一种种应应用用程程序序框框架架,其其核核心心就就是是文文档档/视视结结构构。在在三三种种最最基基本本的的MFC程程序序框框架架中中有有两两种种:多多文文档档结结构构和和单单文文档档结结构构。MFC采采用用两两个个既既相互独立又相互紧密联系的类来实现这一结构:相互独立又相互紧密联系的类来实现这一结构:1文档类文档类CDocument,它主要用于存取文档;,它主要用于存取文档;2视图类视图类CView,它主要用于显示和打印文档,它主要用于显示和打印文档,并支持与用户的交互。并支持与用
126、户的交互。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.7.1文档文档/视结构视结构文档与数据:文档与数据:文档类的含义非常广泛。包括复合文档。在多文档文档类的含义非常广泛。包括复合文档。在多文档结构(结构(MDI)中一个子窗口所掌握的数据也称为一个)中一个子窗口所掌握的数据也称为一个文档。文档就是数据,文档。文档就是数据,CDocument就可以简单地理就可以简单地理解为解为负责处理数据的类负责处理数据的类
127、。在。在MFC编程时,我们应该编程时,我们应该把所有要处理的从外部获得的数据全部放在文档类把所有要处理的从外部获得的数据全部放在文档类及其派生类的对象中。及其派生类的对象中。CDocument类是一个预先编类是一个预先编好的类,只是提供了一个好的类,只是提供了一个外壳外壳或者讲或者讲框架框架,程序员,程序员可以在可以在Document中建立实际要用的数据格式及其中建立实际要用的数据格式及其管理方法。最常用的方法当然是派生出自己的文档管理方法。最常用的方法当然是派生出自己的文档类(类(CMyDocument类)。类)。Evaluation only.Created with Aspose.Sli
128、des for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.7.1 文档文档/视结构视结构视的作用: 视类(视类(CView)负责与使用者接触。文档和视是负责与使用者接触。文档和视是数据的两个方面:数据的处理在文档中进行,它使数据的两个方面:数据的处理在文档中进行,它使用的是字节、整数、浮点数等数据,链表、顺序表用的是字节、整数、浮点数等数据,链表、顺序表和树、图等数据结构。而数据的表现和树、图等数据结构。而数据的表现视使用的视使用的是绘图工具:如绘图域、画笔、调色板等等。是绘图工具:如绘图域、画笔、
129、调色板等等。CView是为数据的表现而设计的。是为数据的表现而设计的。 CView还负责程序与用户之间的交互。用户对还负责程序与用户之间的交互。用户对数据的编辑、修改,对程序下达工作指令都要依赖数据的编辑、修改,对程序下达工作指令都要依赖窗口上的鼠标与键盘操作才能完成,这些信息由窗口上的鼠标与键盘操作才能完成,这些信息由View接受后再传给接受后再传给Document(参见图(参见图2.13)。)。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011
130、Aspose Pty Ltd.2.7.1 文档文档/视结构视结构图图2.13 文档文档/视有关系统视有关系统读数据读数据送显送显视图窗口视图窗口数数据据保保存存在在视视图图成成员变量中员变量中视图对象视图对象文档对象文档对象数数据据保保存存在在文文档档的的成成员员变变量量中中由由文文档档实实现现数数据据的的提提取取和和插插入入存档对象存档对象由由视视图图实实现现文文档档数数据据更新更新由由视视图图实实现现数数据更新据更新文件对象文件对象Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.C
131、opyright 2004-2011 Aspose Pty Ltd.2.7.2 文档文档/视结构视结构文档文档/ /视结构的使用:视结构的使用: 文档文档/视结构中,视结构中,MFC类已经把一个应用程序所类已经把一个应用程序所需的需的“数据处理与显示数据处理与显示”的函数空壳都设计好了,的函数空壳都设计好了,这些函数都是虚函数,这样用户可在自己的派生类这些函数都是虚函数,这样用户可在自己的派生类(CMyDocument和和CMyView)中重编它们(多态)。)中重编它们(多态)。有关档案(存档类有关档案(存档类CArchive,在下一小节讨论)的,在下一小节讨论)的读写操作在文档中的读写操作在
132、文档中的Serialize()函数中进行,而有函数中进行,而有关视图窗口的操作在视类中的关视图窗口的操作在视类中的OnDraw () 函数中进函数中进行。所以行。所以在在MFC的编程中,用户主要的工作是编写的编程中,用户主要的工作是编写文档中的数据获得、数据保存和数据处理,视中的文档中的数据获得、数据保存和数据处理,视中的OnDraw()和函数和函数。Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.7.2 存档类
133、序列化存档类序列化 存档类:存档类:存档类(存档类(CArchive类)不是类)不是CObject的派生类,它的派生类,它提供运行时对象模式支持。提供运行时对象模式支持。Serialize()函数的参数是存函数的参数是存档类档类CArchive对象的引用。对象的引用。CArchive类对象是在永久性类对象是在永久性对象(磁盘文件,对象(磁盘文件,CFile类对象)和非永久性对象(内存类对象)和非永久性对象(内存对象,如文档类对象)之间充当一个对象,如文档类对象)之间充当一个过渡角色过渡角色。负责。负责按按一定的顺序和格式在两者之间进行存取一定的顺序和格式在两者之间进行存取。文件一般为二。文件一
134、般为二进制格式文件。而内存对象可以是简单数据变量,也可进制格式文件。而内存对象可以是简单数据变量,也可以是以是C+对象或对象或CObject派生类对象。参见图派生类对象。参见图2.14。 CFile对象对象CArchive对象对象内存对象内存对象读读写写图图2.14 对象永久保存的层次结构对象永久保存的层次结构Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.7.2 存档类序列化存档类序列化序列化使用:序列化使用:
135、 MFC的存储功能被称为序列化(的存储功能被称为序列化(Serialization),),CArchive对象从字面上看是档案,实际上是一个对象从字面上看是档案,实际上是一个内存缓内存缓冲区冲区,其操作速度比文件的操作要快的多。,其操作速度比文件的操作要快的多。Serialize()操作的对象就是操作的对象就是CArchive类对象类对象。 函数函数CObject:Serialize是一个虚函数。实际上函数是一个虚函数。实际上函数体中是空的,但体中是空的,但Microsoft很可能改变函数体中的内容,很可能改变函数体中的内容,所以所以Microsoft要求改写时先查看它。要求改写时先查看它。
136、Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.2.7.2 存档类序列化存档类序列化注意:注意:要使要使CObject派生类真正有可序列化(派生类真正有可序列化(Serializable)的)的功能,必须具备下列条件:功能,必须具备下列条件: 1由由CObject派生出来,以保证有运行时类型识别(派生出来,以保证有运行时类型识别(RTTL,Runtime Type Identification)、动态生成()、动态生
137、成(Dynamic Creation)等机能。)等机能。2 改改写写Serialize虚虚函函数数,使使它它能能适适当当地地把把类类成成员员变变量量写写入入档案。档案。3 要要加加一一个个缺缺省省的的构构造造函函数数(无无参参)。MFC往往往往必必须须先先动动态态生成存档类对象,而且是在无任何参数下生成对象。生成存档类对象,而且是在无任何参数下生成对象。4类声明必须包含一些必要的宏。类声明必须包含一些必要的宏。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 200
138、4-2011 Aspose Pty Ltd.2.7.2 存档类序列化存档类序列化序列化全过程:序列化全过程: 由由CWinApp:OnFileSaveAs()CWinApp:OnFileSaveAs()消消息息处处理理函函数数,打打开开一一个个对对话话框框提提示示输输入入一一个个文文件件名名,并并创创建建一一个个该该文文件件的的CFileCFile对对象象,然然后后把把CFileCFile对对象象绑绑定定到到一一个个CArchiveCArchive对对象象上上,最最后后 调调 用用 文文 档档 类类 的的 Serialize()Serialize()成成 员员 函函 数数 由由 参参 数数 引
139、引 用用CArchiveCArchive对象。对象。CArichiveCArichive对象与内存对象之间对象与内存对象之间数据流的流动方向数据流的流动方向可可用成员函数用成员函数IsStoring()IsStoring()或或IsLoading()IsLoading()来判断当前的数据来判断当前的数据流动方向。当打开文档时,流动方向。当打开文档时,IsStoring()IsStoring()返回返回falsefalse,IsLoadingIsLoading()()返回返回truetrue。当保存文档时,返回值相反。这可避免在程。当保存文档时,返回值相反。这可避免在程序中出现按实际数据流动方向相反操作的异常。序中出现按实际数据流动方向相反操作的异常。 Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.第二章第二章 MFC编程基础知识编程基础知识结束谢谢!Evaluation only.Created with Aspose.Slides for .NET 3.5 Client Profile 5.2.0.0.Copyright 2004-2011 Aspose Pty Ltd.