windows编程复习纲要.ppt_第1页
windows编程复习纲要.ppt_第2页
windows编程复习纲要.ppt_第3页
windows编程复习纲要.ppt_第4页
windows编程复习纲要.ppt_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

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

文档简介

2020 3 27 1 前言 什么是WindowsAPI 有过编程经验的读者都应该知道 在传统应用程序中要完成某个功能 都是以函数调用的形式实现的 同样 Windows应用程序也是以函数调用的方式来通知操作系统执行相应的功能的 操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应 也就是说 操作系统把它所能够完成的功能以函数的形式提供给应用程序使用 应用程序对这些函数的调用就叫做系统调用 这些函数的集合就是Windows操作系统提供给应用程序编程的接口 ApplicationProgrammingInterface 简称WindowsAPI 如CreateWindow就是一个API函数 应用程序中调用这个函数 操作系统就会按照该函数提供的参数信息产生一个相应的窗口 这些API函数都在windows h中声明 2020 3 27 2 什么是MFC MFC英文全称为MicrosoftFoundationClasses 微软基础类库 是把WindowsAPI进行封装的类库 它是一个类的集合 通过覆盖WindowsAPI 为编程提供了一个面向对象的界面 MFC使Windows程序员能够利用C 面象对象的特性进行编程 前言 2020 3 27 3 为什么要使用MFC 可重用性封装后使方法和属性更紧密的捆绑常用的功能自动化 减少编写代码的数量提供应用程序的框架结构框架结构提供了抽象功能 它远远超出了WindowsAPI的功能 例如 MFC的文档 视图体系结构在API上建造了一个功能强大的基础结构 它把程序中数据的图形表示 或成为视图 与数据本身分开 这种抽象对API而言完全是陌生的 而且在MFC框架结构之外或类似的类库中也不存在 前言 2020 3 27 4 Windows程序内部运行机制 Windows编程模型 事件驱动编程模型 以消息为基础 事件驱动之 WM PAINT WM KEYDOWN WM LBUTTONDOWN 消息响应 消息响应 消息响应 DefWindowProc 来源于操作系统的消息 消息队列 WinMain 消息循环 发送消息 窗口过程 未处理的消息 应用程序 窗口 2020 3 27 5 Windows程序内部运行机制 小小知识点 句柄 句柄 HANDLE 资源的标识 操作系统要管理和操作这些资源 都是通过句柄来找到对应的资源 按资源的类型 又可将句柄细分成图标句柄 HICON 光标句柄 HCURSOR 窗口句柄 HWND 应用程序实例句柄 HINSTANCE 等等各种类型的句柄 操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄 2020 3 27 6 Windows程序内部运行机制 编写Windows应用程序的要素 消息响应 消息响应 消息响应 DefWindowProc WinMain 消息循环 发送消息 窗口过程 未处理的消息 应用程序 1入口函数WinMain2创建窗口3发送消息与消息循环4窗口过程与消息响应 消息 窗口 2020 3 27 7 窗口类第二个成员变量lpfnWndProc指定了这一类型窗口的过程函数 也称回调函数 回调函数的原理是这样的 当应用程序收到给某一窗口的消息时 还记得前面讲过的消息通常与窗口相关的吗 就应该调用某一函数来处理这条消息 这一调用过程不用应用程序自己来实施 而由操作系统来完成 但是 回调函数本身的代码必须由应用程序自己完成 对于一条消息 操作系统到底调用应用程序中的哪个函数 回调函数 来处理呢 操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数 每一种不同类型的窗口都有自己专用的回调函数 该函数就是通过lpfnWndProc成员指定的 Windows程序内部运行机制 窗口过程函数 2020 3 27 8 Windows程序内部运行机制 创建窗口 创建一个完整的窗口需要经过下面四个操作步骤 Step1 设计一个窗口类 Step2 注册窗口类 Step3 创建窗口 Step4 显示及更新窗口 2020 3 27 9 Windows程序内部运行机制 WM PAINT Windows把一个最小的需要重绘的正方形区域叫做 无效区域 当Windows发现了一个 无效区域 后 它就会向该应用程序发送一个WM PAINT消息 通知应用程序重新绘制窗口 当窗口从无到有 改变尺寸 最小化后再恢复 被其他窗口遮盖后再显示时 窗口的客户区都将变为无效 那么 应用程序是如何通知操作系统执行某个功能的呢 2020 3 27 10 Windows程序内部运行机制 自行发送消息的两种方式 发送消息可以使用SendMessage和PostMessage函数 SendMessage将消息直接发送给窗口 并调用该窗口过程进行处理 在窗口过程对消息处理完毕后 该函数才返回 PostMessage函数将消息放入与创建窗口的线程相关联的消息队列后立即返回 2020 3 27 11 虚函数与多态性 当C 编译器在编译的时候 发现基类的函数是虚函数 这个时候C 就会采用迟绑定 latebinding 的技术 在运行时 依据对象的类型 在示例程序中 我们传递的派生类对象的地址 来确认调用的哪一个函数 这种能力就做C 的多态性 在基类的函数前加上virtual关键字 该函数则为虚函数 虚函数派生下去仍为虚函数 而且可以省略virtual关键字 在派生类中重写该函数 运行时将会根据指针实际所指的对象的类型来调用相应的函数 如果对象类型是派生类 就调用派生类的函数 如果对象类型是基类 就调用基类的函数 掌握C 2020 3 27 12 纯虚函数与抽象类 纯虚函数是指被标明为不具体实现的虚函数 纯虚函数可以让类先具有一个操作名称 而没有操作内容 让派生类在继承时再去具体地给出定义 凡是含有纯虚函数的类叫做抽象类 这种可不能实例化对象 只能作为基类为派生类服务 注意 派生类中必须实现基类的纯虚函数 否则 派生类也变成了抽象类 不能实例化对象 纯虚函数多用在一些方法行为的实际上 在设计基类时 不太好确定或将来的行为多种多样 而此行为又是必需的 我们就可以在基类的设计中 以纯虚函数来声明次中行为 而不具体实现它 掌握C 2020 3 27 13 const的使用方法 const成员函数 任何不会修改数据成员的函数都应该声明为const类型 如果在编写const成员函数时 不慎修改了数据成员 或者调用了其它非const成员函数 编译器将指出错误 这无疑会提高程序的健壮性 2020 3 27 14 类中的Static成员变量与函数 静态成员函数与变量的特性 静态成员函数和静态成员变量属于类本身 在类加载的时候 编译阶段 即为它们分配了空间 因此可以通过类名 函数名或类名 变量名来访问 而非静态函数和非静态成员属于对象的方法和数据 也就是应该首先产生类的对象 然后通过类的对象去引用 静态函数不属于某个具体的对象 也就是说 在还没有产生类的任何一个具体对象时 静态函数就已经存在于程序的代码区了 但这是类的非静态成员还没有分配内存空间 这样 在静态成员函数中是没有办法对类非静态成员进行操作的 因此 在静态成员函数中只能访问静态成员变量 不能访问非静态成员函数和非静态成员变量 非静态成员函数中可以调用静态成员函数 2020 3 27 15 MFC框架程序剖析 MFC单文档界面程序初探 简答题 test h test cpp 应用程序类 CTestApp 由CWinApp继承而来 每一个MFC程序有且仅有一个主应用程序类对象theApp 它代表一个程序本体 用于管理和维护主应用程序 MainFrm h MainFrm cpp 主框架类CMainFrame 由CWnd继承而来 主框架是应用程序的主体窗口 其他的窗口 如视类窗口 工具条 状态条 都依附于主框架窗口 覆盖在它上面 2020 3 27 16 MFC框架程序剖析 MFC单文档界面程序初探 续 testView h testView cpp 视图类 CTestView 由CWnd继承而来 负责管理和维护图形显示操作 testDoc h testDoc cpp 文档类 CTestDoc 由CDocumet继承而来 负责显示数据的后台管理和维护 2020 3 27 17 MFC框架程序剖析 MFC中的全局对象theApp 初始化CTestAPP对象 应用程序内存获得配置调用基类CWinApp构造函数 在MFC源码目录的文件中AppCore cpp 初始化完成程序运行时的一些初始化工作 注意 由于theApp是个全局对象 所以CWinApp构造函数会在入口函数WinMain之前运行 2020 3 27 18 图形操作 设备描述表DC 在Windows平台下 窗口的所有图形操作都是利用DC来完成的 如果使用GetDC来得到DC的句柄 在完成图形操作后 必须调用ReleaseDC来释放DC所占用的资源 以避免内存泄漏 利用计算机作图 窗口相当于画布 因此 在获取DC的句柄时 总是和一个指定的窗口相关联 2020 3 27 19 简单绘图 利用CClientDC CWindowDC类绘图 简答题 CClientDC派生于CDC类 并且在构造时调用GetDC函数 在析构时调用ReleaseDC函数 它与CDC一样 都是实现在窗口的客户区绘图 CWindowDC派生于CDC类 并且在构造时调用GetWindowDC函数 在析构时调用ReleaseDC函数 该对象可以访问整个窗口区域 包括客户区与非客户区 2020 3 27 20 简单绘图 绘制彩色线条 使用CPen类 CPenpen PS SOLID 5 RGB 255 0 0 CClientDCdc this CPen pOldPen dc SelectObject 注意 当构造一个GDI对象后 该对象并不会立即生效 必须通过SelectObject函数选入设备描述表 它才会在以后的绘制操作中生效 在完成绘图操作之后 都要利用SelectObject把先前的GDI对象选入设备描述表 以便使其恢复到先前的状态 2020 3 27 21 Windows消息的分类 标准消息除WM COMMAND之外 所有以WM 开头的消息 从CWnd派生的类 都可以接收到这类消息 命令消息来自菜单 加速键或工具栏按钮的消息 这类消息都以WM COMMAND呈现 在MFC中 通过菜单项的标识 ID 来区分不同的命令消息 在SDK中 通过消息的wParam参数识别 从CCmdTarget派生的类 都可以接收到这类消息 通告消息由控件产生的消息 例如 按钮的单击 列表框的选择等均产生此类消息 为的是向其父窗口 通常是对话框 通知事件的发生 这类消息也是以WM COMMAND形式呈现 从CCmdTarget派生的类 都可以接收到这类消息 菜单响应函数 2020 3 27 22 菜单命令消息路由的过程 简答题 当点击某菜单项时 最先接收到这个菜单命令消息的是框架类 框架类把接收到的这个消息传给它的子窗口 即视类 视类根据命令消息映射机制查找自身是否对这个消息进行了响应 如果响应了 则调用自身相应响应函数 如果视类没有对此命令消息作出响应 就交由文档类 文档类同样查找自身是否这个消息进行了响应 如果响应了 则调用自身相应响应函数 如果文档类也未做出响应 就把这个命令消息交还给视类 后者再交还给框架类 框架类查看自己是否对这个命令消息进行了响应 如果它也没有相应 就把这个菜单命令消息交给应用程序类 由后者来处理 菜单响应函数 2020 3 27 23 对话框 对话框是一个窗口 与对话框资源相关的类为CDialog 由CWnd类派生而来 可以将对话框看成是一个大容器 在它上面能够放置各种标准和扩展控件 是用户与程序进行交互的重要手段 在MFC中 所有的控件都是由CWnd派生而来 因此 控件实际上也是窗口 对话框基本知识 2020 3 27 24 对话框的种类 模式对话框 当其显示时 程序会暂停执行 直到关闭这个对话框后 才能继续执行程序中其他任务 例如 文件 打开 对话框 无模式对话框 当其显示时 允许转而执行程序中其他任务 而不用关闭这个对话框 该类型对话框不会垄断用户的操作 用户仍可以与其他界面对象进行交互 例如 查找 对话框 对话框基本知识 2020 3 27 25 DoModal 函数 创建模式对话框需要调用CDialog类的成员函数 DoModal 该函数的功能就是创建并显示一个模式对话框 创建模式对话框 voidCMainFrame OnTest TODO AddyourcommandhandlercodehereCMyDialogdlg dlg DoModal 2020 3 27 26 Create 函数 创建非模式对话框需要调用CDialog类的成员函数 BOOLCreate UINTnIDTemplate CWnd pParentWnd NULL 创建非模式对话框 voidCMainFrame OnTest TODO AddyourcommandhandlercodehereCMyDialogdlg dlg Create IDD DIALOG1 this 注意 运行程序 对话框并未显示 2020 3 27 27 ShowWindow 函数 当利用Create函数创建非模式对话框时 还需要调用ShowWindow函数将这个对话框显示出来 创建非模式对话框 voidCMainFrame OnTest CMyDialogdlg dlg Create IDD DIALOG1 this dlg ShowWindow SW SHOW 注意 运行程序 对话框仍未显示 2020 3 27 28 对话框未显示之原因分析 这里创建的非模式对话框对象 dlg 是一个局部对象 当OnTest函数结束时 dlg这个对象的生命周期也就结束了 它会销毁与之相关联的对话框资源 因此对话框不会显示 在创建模式对话框时 当执行到DoModal函数显示这个对话框时 程序会暂停执行 直到关闭模式对话框之后 程序才继续执行 也就是说 当模态对话框显示时 dlg这个对象的生命周期并未结束 为什么模式对话框不会出现这样的问题 结论 在创建非模式对话框时 不能把对话框对象定义为局部对象 创建非模式对话框 2020 3 27 29 解决方法1 使用成员变量 把对话框对象定义为视类的成员变量 注意 在销毁对话框之前 Create函数只能调用一次 否则会出错 voidCMainFrame OnTest staticBOOLbFlag TRUE if TRUE bFlag dlg Create IDD DIALOG1 this bFlag FALSE dlg ShowWindow SW SHOW 创建非模式对话框 2020 3 27 30 解决方法2 使用推内存 把对话框对象定义为指针 在堆上分配内存 voidCMainFrame OnTest CMyDialog pDlg newCMyDialog pDlg Create IDD DIALOG1 this pDlg ShowWindow SW SHOW 注意 该程序存在问题 由于没有办法释放这个指针变量所指向的那块内存 会出现内存泄漏 消除内存泄漏的办法 1 指针变量定义成全局变量 或者2 重载对话框的PostNcDestroy函数 添加代码deletethis 创建非模式对话框 2020 3 27 31 利用GetDlgItem改变控件文本内容 voidCMyDialog OnNumber1 CStringstr GetDlgItem IDC NUMBER1 GetWindowText str if str Number1 GetDlgItem IDC NUMBER1 SetWindowText 数值1 elseGetDlgItem IDC NUMBER1 SetWindowText Number1 注意 静态文本框在默认状态下是不发送通告消息的 改变这一默认状态 必须在属性窗口选中Notify这个选项 访问控件的七种方法 2020 3 27 32 在窗口创建之前更改 更改窗口大小 标题 风格 如果希望在应用程序窗口创建之前修改它的大小 标题和风格 应该在CMainFrame类的PreCreateWindow成员函数进行 该函数有个类型是CREATESTRUCT结构的参数 如果在修改了这个参数中的成员变量的值 那么这种改变会反映到MFC底层代码中 当MFC底层代码调用CreateWindowEx函数去创建窗口时 它就会使用改变后的参数值去创建这个窗口 2020 3 27 33 在窗口创建之后更改其风格 在应用程序窗口创建之后修改它的风格属性 可在CMainFrame类的ONCreate函数中调用SetWindowLong函数实现 SetWindowLong HWNDhWnd intnIndex LONGdwNewLong 该函数的作用是改变制定窗口的属性 包括设置新的窗口风格 设置新的窗口过程 设置新的应用程序实例局柄等 要改变窗口的风格 则将该函数的第二个参数指定为GWL STYLE 然后由第三个参数指定新的窗口风格 更改窗口大小 标题 风格 2020 3 27 34 在窗口创建之后更改 更改光标 标题栏图标 窗口背景 要在应用程序窗口创建之后修改它的光标 图标和背景 可在OnCreate函数中调用SetClassLong函数实现 SetClassLong HWNDhWnd intnIndex LONGdwNewLong 该函数的作用是 重新设置指定窗口所属窗口类的WNDCLASS结构体中指定数据成员的属性 包括设置新的窗口背景画刷 光标 图标和窗口类样式 2020 3 27 35 注意事项 更改光标 标题栏图标 窗口背景 在MFC中 如果要修改应用程序窗口的图标 则应该框架类中进行 因为框架窗口才有标题栏 如果要修改程序窗口的背景和光标 则应该在视类中进行 2020 3 27 36 程序与进程 简答 进程与线程 程序 计算机指令的集合 它以文件的形式存储在磁盘上 进程 通常被定义为一个正在运行的程序的实例 是一个程序在其自身的地址空间中的一次执行活动 进程是活的 是资源申请 调度和独立运行的单位 因此 它使用系统中的运行资源 而程序是死的 它不占用系统的运行资源 2020 3 27 37 进程与线程 进程与线程 进程是不活泼的 进程从来不执行任何东西 它只是线程的容器 若要使进程完成某项操作 它必须拥有一个在它的环境中运行的线程 此线程负责执行包含在进程的地址空间中的代码 单个进程可能包含若干个线程 这些线程都 同时 执行进程地址空间中的代码 每个进程至少拥有一个线程 来执行进程的地址空间中的代码 当创建一个进程时 操作系统会自动创建这个进程的第一个线程 称为主线程 此后 该线程可以创建其他的线程 2020 3 27 38 获得互斥对象所有权 利用互斥对象实现线程同步 线程必须主动请求共享对象的使用权才能获得该所有权 这可以通过调用WaitForSingleObject函数实现 DWORDWatiForSingleObject HANDLEhHandle DWORDdwMillisecond HANDLEhHandle所请求对象的句柄 本例为互斥对象句柄 hMutex 一旦互斥对象处于有信号状态 则该函数返回 接着 操作系统会将这个互斥对象设为未通知状态 如果该互斥对象处于无信号状态 则该函数会一直等待 这样会暂停线程的执行 DWORDdwMillisecond指定等待的时间 如果指定的时间间隔已过 即使所请求的对象处于无信号状态 该函数也返回 如果该参数为0 该函数立即返回 如果该参数为INFINTE 则该函数永远等待 直到互斥对象处于由信号状态才返回 2020 3 27 39 利用互斥对象实现线程同步 include includeDWORDWINAPIThreadProc1 LPVOIDlpParameter DWORDWINAPIThreadProc2 LPVOIDlpParameter inttickets 1 HANDLEhMutex voidmain HANDLEhThread1 HANDLEhThread2 hThread1 CreateThread NULL 0 ThreadProc1 NULL 0 NULL hThread2 CreateThread NULL 0 ThreadProc2 NULL 0 NULL CloseHandle hThread1 CloseHandle hThread2 hMutex CreateMutex NULL FALSE NULL Sleep 5000 火车站售票系统模拟程序 2020 3 27 40 利用互斥对象实现线程同步 线程1的入口函数 售票窗口1 DWORDWINAPIThreadProc1 LPVOIDlpParameter while TRUE WaitForSingleObject hMutex INFINITE if tickets 100 Sleep 1 cout thread1sellticket tickets endl elsebreak ReleaseMutex hMutex return0 火车站售票系统模拟程序 2020 3 27 41 利用互斥对象实现线程同步 线程2的入口函数 售票窗口2 DWORDWINAPIThreadProc2 LPVOIDlpParameter while TRUE WaitForSingleObject hMutex INFINITE if tickets 100 Sleep 1 cout thread2sellticket tickets endl elsebreak ReleaseMutex hMutex return0 火车站售票系统模拟程序 2020 3 27 42 动态链接库概述 微软任何一个版本的Windows操作系统 动态链接库 DLL 都是其核心和基础 动态链接库不能直接运行 它们是一些独立的文件 其中包含能被可执行程序或其它DLL调用来完成某项工作的函数 只有在其它模块调用动态链接库中的函数时 它才发挥作用 WindowsAPI中的所有函数都包含在DLL中 其中有3个最重要的DLL Kernel32 dll 它包含用于管理内存 进程和线程的各个函数 User32 dll 它包含用于执行用户界面任务 如窗口的创建和消息的传送 的各个函数 GDI32 dll 它包含用于画图和显示文本的各个函数 Dll概述 2020 3 27 43 动态链接库概述 使用动态链接库的好处 简答 增强程序的扩展性可以采用多种编程语言来写提供二次开发的平台简化项目管理节省磁盘空间和内存有助于资源共享 2020 3 27 44 Win32DLL的创建 导出DLL中的函数 注意 应用程序如果想要访问DLL中的函数 那么该函数必须是已经被导出的函数 为了让DLL导出函数 需要在每一个将要被导出的函数前添加标识符 declspec dllexport declspec dllexport intadd inta intb returna b declspec dllexport intsubtract inta intb returna b Build后 在Debug目录下会产生一个动态库Dll1 dll文件和一个引入库文件Dll1 lib 2

温馨提示

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

评论

0/150

提交评论