1.25k likes | 1.54k Views
Visual C++ MFC 编程基础. 一 . 引言. 为什么学习 Windows 程序设计 微机 OS 霸主 Windows 3.X(16 位 ) Windows 95/NT(32 位 ) 程序设计的特殊性 Windows 工作原理 开发工具的多样性. 主要学习内容. Windows 系统引擎 消息驱动体系 三种编程方法 基于 C 语言与 SDK 工具 基于 C++ 语言和 MFC 类库 基于 Visual C++ 环境. 1.1 Windows 系统的特征. 用户观点 统一的图形用户界面 (GUI)
E N D
一.引言 为什么学习 Windows 程序设计 • 微机 OS 霸主 • Windows 3.X(16位) • Windows 95/NT(32位) • 程序设计的特殊性 • Windows 工作原理 • 开发工具的多样性
主要学习内容 • Windows系统引擎 消息驱动体系 • 三种编程方法 基于 C 语言与 SDK 工具 基于 C++语言和 MFC 类库 基于 Visual C++ 环境
1.1 Windows系统的特征 用户观点 • 统一的图形用户界面(GUI) • 多任务多线程机制 • 设备无关的图形界面 • 即插即用性 (Plug-and-Play)
Windows 系统 对象的图形表示 多种输入方式 统一的窗口格式 统一的操作方法 DOS 系统 对象的文字表示 基于文字的输入 命令行交互方式 自定义的用户界面 用户友好性 • 对相同的对象采用相同的表现方法 • 对相同的操作采用相同的命令方式
同步交互 用户和 DOS系统 (例外:中断) 用户和一个线程 (Windows 95/NT) 异步交互 用户和 Windows 系统 用户和多个进程 (多个程序实例) 用户和多个窗口 人机对话的交互方式
1.2 Windows的控制机制与资源管理 • Windows 系统和应用程序的交互方式 • 系统与一线程同步交互 • 系统与多线程异步交互 • 事件驱动体系(异步交互的实现方法) • 事件:鼠标键盘输入、各种状态改变 • 事件发生时,用系统消息通知系统 • 系统接收消息,提交给各个应用程序
资源与内存管理 • 数据资源(Resource) • 文字信息、位图、图标、光标等等 • 多个程序共享 • 动态连接库(DLL) • 执行中的连接 • 多个程序共享 • 虚存空间 • Win 95/NT:4G
1.3 Windows程序设计的特征 • 消息驱动体系 • Windows系统运行中发生的各种事件,以消息的形式通知系统 • 各应用程序提供消息循环,接收消息,提交给程序中的各个窗口 • 窗口处理 • 每个窗口配备一个窗口函数,负责处理收到的消息(程序设计的主要任务)
交互控制手段 • Windows 系统消息 • 系统控制应用程序的主要手段 • 数百条消息表示各种事件的发生 • API 函数 • 上千个系统函数与专用数据结构 • 提供各种功能服务
Windows API 函数 • 窗口管理 • 图形设备接口(GDI) • 系统服务 • 数据库:ODBC • 网络与通信:RPC/WinSock • OLE支持
1.4 软件开发策略 • 开发需求 • 满足用户需求(功能和友好性) • 保证软件可维护性 • 鼓励开发可重用构件 • 减少低级工具的使用 • 目的:提高工作效率,降低开发投入 • 手段:提供支持程序生成、支持程序综合的各种综合开发工具,
系统开发人员 系统设计与集成 界面设计与实现 系统开发工具 Visual Basic PowerBuilder Visual FoxPro Excel / Access 构件开发人员 可重用构件的设计与实现 构件开发工具 Visual C/C++ MASM SDK Fortran Java 两级组织和开发工具
1.5 为什么选用C++语言 • 学习需求: • Windows 软件结构 • Windows 的消息驱动体系 • 学编程技术,不是使用方法 • 学基础知识,不是技术手册 • 矛盾与学习曲线 • 众多的程序生成工具,方便简单应用系统的开发,隐蔽了技术细节和工作原理。
三种编程方法 1. 基于 C 语言和 SDK 开发工具 • 易于理解 Windows 工作原理 • 庞大的应用程序接口(API、消息) 2. 基于 C++ 语言和 MFC 基本类库 • 消息驱动体系符合面向对象思想 • 以 MFC 作为应用程序接口 3. 基于 AppWizard、ClassWizard 和 MFC • 自动生成应用程序框架 • 提供程序综合支持
二、Windows 程序设计概论 • 2.1 消息驱动体系 • 2.2 应用程序框架 • 2.3 应用程序简例 • 2.4 可执行程序的产生 • 2.5 几种常见的系统消息
2.1 消息驱动体系 键盘输入 鼠标输入 状态改变 Windows 系统消息队列 应用程序队列 应用程序队列 应用程序队列 消息循环 消息循环 消息循环 应用程序 应用程序 窗口 窗口 窗口 窗口 窗口 窗口 窗口 窗口 窗口
控制关系 • Windows 系统是主控方 • 通过消息控制 应用程序的各个窗口 • 各种输入由 Windows 系统接受 • 不受应用程序的控制 • 应用程序有多个程序入口 • 多个窗口函数 • Windows 系统本身的工作 • 也依靠消息驱动体系
2.2 应用程序框架程序开发过程 开发工具 源程序 *.C/*.CPP 编译器 资源描述 *.RC 资源编译 目标程序 *.OBJ 模块定义 *.DEF 连接器 可执行程序 *.EXE 资源连接 资源文件 *.RES 库函数 *.LIB 可执行文件 *.EXE
程序员编制的文件 • 源程序文件(*.C/*.CPP) • 提供程序入口、消息循环 • 提供窗口创建、窗口函数 • 资源描述文件(*.RC) • 描述常数字符串、位图、图标、光标 • 由 SDK 工具、App Wizard 工具生成 • 模块定义文件(*.DEF) • 描述内存分配、属性 • 库函数的引入、引出
窗口的程序结构(1/3) • 登记窗口类 WNDCLASS ws; ws.lpszClassName = 窗口类名; ws.lpfnWndProc = 窗口函数名; …… RegisterClass( &ws ); /* 给定的窗口函数负责该类窗口的消息响应 */
窗口的程序结构(2/3) • 创建窗口、显示窗口 窗口句柄 = CreateWindow(窗口类名, 标题, …); ShowWindow(窗口句柄,显示状态); /* 窗口句柄是窗口的唯一标识 */
窗口的程序结构(3/3) • 定义窗口函数 LRESULT CALLBACK 窗口函数 ( 窗口句柄,消息标识,字参数,长参数 ) { switch( iMsg ) { case WM_PAINT: ...... case ...... } } // 识别收到的各种消息,完成消息响应
WinMain 的程序结构 • 应用程序入口 WinMain( 程序实例句柄,上一程序实例句柄, 命令行参数,显示状态 ) { if( 是首次实例 ) 登记主窗口所属的窗口类; 创建主窗口; 显示主窗口; 消息循环; }
消息循环 MSG msg; /* 消息结构 */ while( GetMessage(&msg,0,0,0) ) { /* 从消息队列取消息 */ TranslateMessage( &msg ); /* 翻译消息 */ DispatchMessage( &msg ); /* 发送消息 */ } /* 收到消息 WM_QUIT 时退出循环
2.3 应用程序简例 • WinMain 函数 • 设置并登记窗口类“WinAPIDemo”,指定 WndProc 为窗口函数 • 创建并显示该类的主窗口 • 进入消息循环 • WndProc 窗口函数 • 鼠标消息 WM_LBUTTONDOWN • 鼠标消息 WM_RBUTTONDOWN • 撤消消息 WM_DESTROY • 其余消息交给 DefWindowProc
消息的接收与识别 • 消息接收 窗口函数( HWND hwnd, // 窗口句柄 WORD msg, // 消息标识 WPARAM wParam, // 字参数 LPARAM lParan) // 长参数 • 消息识别 msg wParam
窗口函数的实现 各 case 分支 设计消息响应代码 MessageBox 标准信息窗 MessageBeep 标准发声函数 PostQuitMessage 发送 WM_QUIT 消息 DefWindowProc 缺省消息处理函数 其他 API GetStockObject 获得系统预定义对象 LoadCursor 装入光标 LoadIcon 装入图标
Windows 窗口的缺省功能 • 缺省功能 • 最大最小化、复原、关闭 • 移动、缩放、激活显示、切换 • 系统菜单、鼠标选择、按钮选择 • 实现方法 • 依靠 Windows 消息驱动体系 • 包括:DefWindowProc
窗口函数设计要领 • 根据应用需求的消息响应,设计 case 语句 • 其余消息必须交给 DefWindowProc • 可能递归调用窗口函数 • 可以利用缺省的消息响应 • 如:发送WM_CLOSE 来关闭窗口 • 需要状态信息时,使用静态变量
模块定义文件(*.DEF) • NAME 程序名称 • EXETYPE 目标程序类型 • CODE 代码段属性 • DATE 数据段属性 • HEAPSIZE 局部堆尺寸 • STACKSIZE 栈尺寸 • EXPORTS 引出函数 • IMPORTS 引入函数
资源描述文件 • 菜单模板 菜单名 MENU 属性 BEGIN MenuItem “菜单项文本”,项标识符 POPUP “子菜单项” BEGIN …… END END • 菜单的指定 • 指定 ws.lpszMenuName = 菜单名,或在 CreateWindow 调用中指定 • 菜单消息中的 wParam 为项标识符
程序的创建 • 工程文件的使用 创建工程文件,加入 .CPP 源程序、 .C 源程序、 .RC 资源描述文件、 .DEF 模块定义文件 • 通过工程文件,完成源程序的编译、目标程序的连接和可执行文件的生成。
程序的调试 • 跟踪调试 F10 单步(进入函数) F11 单步(不进入函数) Shift F7 执行到函数出口 • 程序中断 F5 继续执行 F9 断点设置与撤消 • 窗口函数的跟踪 在函数入口加断点
鼠标输入 WM_MOUSEMOVE 鼠标移动 WM_LBUTTONDOWN 鼠标左键按下 WM_LBUTTONUP 鼠标左键释放 键盘输入 WM_KEYDOWN 键按下 WM_KEYUP 键释放 WM_CHAR 字符键入 重画消息 WM_PAINT 重画窗口用户区 2.4 几种常见的系统消息
文本输出例 HDC hDC; // 输出设备句柄 PAINTSTRUCT ps; // 重画信息结构 switch( msg ) { …… case WM_PAINT: // 重画消息入口 hDC = BeginPaint(hwnd, &ps); // 获得设备 TextOut(hDC, 10, 10,“Hello”, 5); // 文本输出 EndPaint(hWnd, &ps); // 释放设备 break; } // hDC 代表窗口用户区
窗口重画 • 显示原理 • 系统不保存被覆盖的窗口,仅将需要显示的部分设置 为无效区; • 系统自动向有无效区的窗口发 WM_PAINT 消息; • 各种输出函数应在 WM_PAINT 的消息响应中调用 • WM_PAINT消息的程序产生 • ShowWindow、UpdateWindow、 InvalidateRect 等 API 函数调用时
图形输出例 int x = LOWORD( lParam ); // 获得鼠标位置 int y = HIWORD( lParam ); HDC hDC = GetDC( hWnd ); // 获取设备句柄 switch( msg ) { …… case WM_LBUTTONDOWN: // 鼠标按下 MoveTo(hDC, x, y); break; // 设置当前点 case WM_LBUTTONUP: // 鼠标释放 LineTo(hDC, x, y); break; // 画线至指定点 } ReleaseDC(hWnd, hDC); // 释放设备句柄
补充说明 • 消息属性的获取 • 参数中可保存多个属性 • 常用 LOWORD 和 HIWORD 分解 lParam • 输出设备 • hDC 标识窗口用户区及其设备描述表 • 两种获取 hDC 的方法 • WM_PAINT 响应(BeginPaint, EndPaint) • 其他消息响应(GetDC, ReleaseDC)
本章小结 • 1. 消息驱动体系 • 系统队列、应用队列 • 2. 程序结构 • 登记窗口类、创建窗口、消息循环 • 3. 窗口函数与消息响应 • CASE 分支、缺省处理 • 4. 常用消息和重画机制 • 设备句柄、无效区与 WM_PAINT
上机题 1 • 用 C 语言扩充65页的程序,实现以下功能: 1 . 当鼠标左键按下时,将鼠标当前坐标显示在窗口中; 2 . 随着鼠标移动,持续显示鼠标当前坐标; 3 . 鼠标右键按下时,清屏。
上机题 2 • 扩充上机题 1,实现以下功能: 1 . 当鼠标左键按下时,以鼠标位置为圆心,画出一个直径为 10 的圆。 Ellipse( hDC, left, top, right, bottom ) 2 . 要求圆随着鼠标移动,直到鼠标左键抬起 3 . 再次按下鼠标时,该圆消失,画出新的圆 4 . 要求随着窗口移动、重置大小或被其他窗口覆盖,圆和坐标显示保持原有位置。
三、MFC 程序设计初步 基本思想: 以基本类库的形式,支持 Windows 应用程序基本框架和常用模 块,覆盖 API 函数,提供高级编程接口。 • 3.1 OOP 与 Windows 消息驱动体系 • 3.2 MFC 基本类库与应用程序框架 • 3.3 CWnd 类和消息处理机制 • 3.4 MFC 典型应用例
3.1 面向对象程序设计与 Windows 的消息驱动体系 面向对象方法: 1. 若干对象组成软件系统 2. 对象是封装的数据及其相关操作(方法) 3. 消息传递提供对象通信手段 4. 对象激活方法来响应消息
面向对象程序设计 1. 确认对象及其相互关系 • 整体部分关系 • 一般特殊关系 2. 分析系统的工作 • 确认消息传递关系 3. 设计对象类 • 用数据结构描述对象的属性与状态 • 用成员函数描述外部操作
Windows系统的面向对象分析 1. 对象: • 各种窗口、各种设备和 GDI 对象 2. 对象通信: • Windows 消息、API 函数调用 3. 消息传递: • 调用窗口函数处理 Windows 消息 4. 消息响应: • 窗口函数 case 语句的各个分支 • 设备和 GDI 对象的 API 函数
使用 OO 方法的好处: 1. 面向对象方法和 Windows 消息驱动体系的完美结合 2. 面向对象程序设计语言的支持 • 提供基本类库 3. 信息隐蔽 • 以类定义接口代替 API 接口 4. 程序结构的模块化 • 分离消息识别和消息响应
OOPL支持Windows 程序设计提供程序基本框架 • 各种窗口基本类 • 封装窗口函数、窗口句柄和 API,提供常用操作和消息响应函数。 • 各种设备和 GDI对象类 • 封装句柄、相关数据结构和 API。 • 应用程序类和类模板 • 封装 Windows 应用程序的基本结构