ch1Win32基本程序观念.ppt_第1页
ch1Win32基本程序观念.ppt_第2页
ch1Win32基本程序观念.ppt_第3页
ch1Win32基本程序观念.ppt_第4页
ch1Win32基本程序观念.ppt_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

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

文档简介

Ch1:Win32基本程序观念 内容提要 Win32程序开发流程 以消息为基础,以事件驱动之 一个具体而微的Win32程序 Console程序及其与DOS程序的差别 实例介绍 Win32程序开发流程 以消息为基础,以事件驱动之 一个具体而微的Win32程序 程序进入点WinMain 窗口类之注册与窗口之诞生 消息循环 窗口的生命中枢:窗口函数 消息映射(Message Map)的雏形 模块定义文件(.DEF) 资源描述文件(.RC) Windows程序的生与死 空闲时间的处理:OnIdle 程序进入点WinMain WinMain则是Windows 程序的进入点: Main是一般C程序的进入点: 当Windows的”外壳”(shell,例如 Windows的文件管理器或资源管理器) 侦测到用户欲执行一个Windows程序, 于是调用加载器把该程序加载,然后调 用C starup code,后者再调用WinMain, 开始执行程序.WinMain的四个参数由 操作系统传进来 窗口类之注册与窗口之诞生 注册窗口-RegisterClass设定窗口属性(外貌和行为) 创建窗口-CreateWindow 显示窗口-ShowWindow 消息循环 初始化工作完成后,WinMain进入所谓的消息循环: While(GetMessage(/转换键盘消息 DispatchMessage(/分派消息 DispatchMessage会将消息传给窗口函数去处理。没有指定函数名称, 却可以将消息传送过去,岂不是很玄?这是因为消息发生之时,操作系 统已根据当时状态,为它标明了所属窗口,而窗口所属的窗口类又已经 明白标示了窗口函数,所以DispatchMessage自有脉络可寻。 消息循环中的GetMessage是Windows 3.x系统非强制性(non- preemptive)多任务的关键。应用程序籍由此操作,提供了释放控制权 的机会:如果消息队列上没有属于我的消息,我 就把机会让给别人。通 过程序之间彼此协调让步的方式,达到多任务能力。Windows 9x和 Windows NT具备强制性多任务能力,不再非靠GetMessage释放CPU控 制权不可,但程序写法依然不变,因为应用程序仍然需要靠消息推动。 窗口的生命中枢:窗口函数 消息循环中的DispatchMessage把消息分配到哪里呢?它通过USER模 块的协助,送到该窗口的窗口函数去了。窗口函数通常利用switch/case方 式判断消息种类,以决定处理方式。由于它是被Windows系统所调用( 我们并没有在应用程序的任何地方调用此函数),所以这是一种call back函数,意思是指“在你的程序中,被Windows系统调用的函数,这些 函数由你设计,但是永远不会也不该被你调用,它们是为Windows系统 准备的。 在程序进行过程中,消息由输入装置,经由消息循环的抓取,源源传送 给窗口并进而送到窗口函数中去。窗口函数的形式: LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) 注意,不论什么消息,都必须被处理,所以switch/case指令中的default: 处必须调用DefWindowProc,这是Windows内部默认的消息处理函数。 我想很多人都会问这个问题:为什么Windows Programming Modal要把 窗口函数设计为一个call back函数?为什么不让程序在抓到消息( GetMessage)之后直接调用它?原因是,除了你需要调用它,有很多 时候操作系统也要调用你的窗口函数(例如当某个消息产生或某个事件 发生)。窗口函数设计为callback形式,才能开放出一个接口给系统调 用 消息映射(Message Map)的雏形(1) 首先定义一个MSGMAP_ENTRY结构和一个dim宏 : 请注意MSGMAP_ENTRY的第二个元素pfn是一个 函数指针,该指针所指的函数处理nMessage消息 。这正是面向对象观念中把“数据”和“处理数据的方 法”封装起来的一种具体实现 消息映射(Message Map)的雏形(2) 接下来,组织两个数组_messageEntries 和 _commandEntries ,把程序中欲处理的消息 以及消息处理例程的关联性建立起来 消息映射(Message Map)的雏形(3) 于是窗口函数可以这么设计: OnCommand函数可以这么设计: 消息映射(Message Map)的雏形(4) 这么一来,WndProc和OnCommand永远不 必改变,每当有新的要处理的消息,只要在 _messageEntries 和_commandEntries 两 个数组中加上新元素,并针对新消息撰写新 的处理例程即可。 这种观念及做法就是MFC的Message Map雏 形。MFC把其中的操作封装得更好更精致,成 为一张庞大的消息地图,程序一旦获得消息,就 可以按图上溯,直到被处理为止。 对话框的运行 Windows的对话框依其与父窗口的关系,分为两类: 1.令其父窗口无效,直到对话框结束-modal对话框 2.父窗口与对话框共同运行-modeless对话框 为了做出一个对话框,程序员必须准备两样东西: 1.对话框模版(dialog template)。这是在RC文件中定义 的一个对话框外貌,以各种方式决定对话框的大小、字形、 内部有哪些控件、各在什么位置等。 2.对话框函数(dialog procedure)。其型态非常类似于窗 口函数,但是它通常只处理WM_INITDIALOG和 WM_COMMAND两个消息。对话框中的各个控件也都是小 小窗口,各有自己的窗口函数,它们以消息与其管理者(父 窗口,也就是对话框)沟通。而所有的控件传来的消息都是 WM_COMMAND,再由其参数分辨哪一种控件以及哪一种 通知消息(notification) 对话框的结束与激活,靠的是DialogBox和EndDialog两个 API函数。 对话框的诞生、运行、结束 模块定义文件(.DEF) Windows程序需要一个模块定义文件,将模块名称、程序段和数据段的内存特性 、模块堆(heap)大小、堆栈(stack)大小,所有callback函数名称等等登记下来 。 在Visual C+开发环境中开发程序,不再需要特别准备.DEF文件,因为模块定义 文件中的设定都有默认值。模块定义文件中的STUP指令用来指定所谓的stub程序 (埋在windows程序中的一个DOS程序,你所看到的This Program Requires Microsoft windows或This Program Can Not Run in DOS mode就是此程序发出来 的),win16允许程序员自设一个stub程序,但win32不允许,换句话说在win32之 中Stub指令已经失效 资源描述文件(.RC) RC文件是一个以文字描述资源的地方。常用 的资源有九项之多,分别是ICON、 CURSON、BITMAP、FONT、DIALOG、 MENU、ACCELERATOR、STRING、 VERSIONINFO、TOOLBAR等。这些文字描 述需经过RC编译器,才产生可使用的二进制 代码。 Windows程序的生与死 8.PostQuitMessage没什么其他操作,就只送出WM_QUIT消息,准备让消息循环中的 GetMessage取得,如步骤2,消息循环结束。 为什么结束一个程序如此复杂?因为操作系统与应用程序职责不同,二者是相互合 作的关系,所以必须各做各的份内事,并互以消息通知对方。如果不依据这个游戏 规则没,则可能就会有麻烦产生。你可以作一个小实验,在窗口函数中拦截 WM_DESTROY,但不调用PostQuitMessage。你会发现当选择系统菜单中的 Close时,屏幕上的这个窗口消失了(因为窗口销毁及数据结构的释放是 DefWindowProc调用DestroyWindow完成的),但是应用程序本身并没有结束(因 为消息循环结束不了),它还留在内存中。 1 .程序初始化过程中调用CreatWindow,为程序建立了一个窗口,作为程序的屏幕舞 台。 CreatWindow产生窗口之后会送出WM_CREATE消息给窗口函数,后者于是可 以在此时做些初始化工作(例如配置内存、打开文件、读取数据.) 2.在程序或者的过程中,不断以GetMessage从消息队列中抓取消息。如果这个 消息是WM_QUIT,GetMessage会传回0而结束while循环,进而结束整个程序. 3.DispatchMessage通过windows USER模块的协助与监督,把消息分派至窗口函 数.消息将在该处被判别并处理。 4.程序不断进行2.和3.的操作。 5.当使用者按下系统菜单中的Close命令项时,系统送出WM_CLOSE。通常程序的窗口函 数不拦截此消息,于是DefWindowProc处理它。 6.DefWindowProc收到WM_CLOSE后,调用DestroyWindow把窗口清除。 DestroyWindow本身又送出WM_DESTROY。 7.程序对WM_DESTROY的标准反应是调用PostQuitMessage。 窗口的生命周期 空闲时间的处理:OnIdle 所谓空闲时间是指“系统中没有任何消息等待处理”的时间 后台工作最适宜在空闲时间完成。传统的SDK程序如果要处理空闲时间 ,可以以下列循环取代WinMain中传统的消息循环: 原因是PeekMessage和GetMessage的性质不同。它们都是到消息队列 中抓消息,如果抓不到,程序的主执行线程(primary thread,是一个UI 执行线程)会被操作系统挂起。当操作系统再次回来照顾这一执行线程 时,发现消息队列仍然是空的,这时候两个API函数的行为就由不同了 : GetMessage会过门不入,于是操作系统再去照顾其他人。 PeekMessage会取回控制权,使程序得以执行一段时间。于是上述消息 循环进入了OnIdle函数中。 内容提要 Win32程序开发流程 以消息为基础,以事件驱动之 一个具体而微的Win32程序 Console程序及其与DOS程序的差别 Console程序 并非所有的Win32程序都如Windows GUI程序那么复杂可怖 。你也可以在Visual C+中写一个DOS-like程序,而且仍然 可以调用部分的、不牵扯到图形使用者接口(GUI)的 Win32 API。这种程序称为console程序。甚至你还可以在 console程序中使用部分的MFC类(同样必须是与GUI没关 联的),例如处理数组、链表等数据结构的collection classes(CArray、Clist、Cmap)、与文件有关的CFile、 CStdioFile。 除了DOS-like,console程序还另有妙用。如果你的程序与 使用者之间是以巨量文字来互动,或许你会选择使用edit控 件(或MFC的CEditView)。但是你知道,计算机在一个纯 粹的“文字窗口”(也就是console窗口)中处理文字的显示与 滚动比较快,你的程序操作也比较简单。 Console与DOS程序的差别 编写方式: 在Windows环境下的Dos Bos中,或是在windows版本的各种C+的编 译器套件的集成开发环境中,利用windows编译器、链接器作出来的程 序,都是所谓的win32程序。如果程序是以main为进入点,调用C runtime函数和“不牵扯GUI”的win32 API函数,那么就是一个console程 序,console窗口将成为其标准输入和输出装置(cin和cout)。 过去在DOS环境下开发的程序,称为DOS程序,它也是以main为进入点 ,可以调用C runtime函数,但不可能调用win32 API。 程序功能: 过去的Dos程序仍然可以在Windows的DOS Box中运行。 由于Console程序可以调用部分的Win32 API(尤其是KERNEL32.DLL模 块所提供的那一部份),所以它可以使用Windows提供的各种高级功能.它 可以产生进程(processes),产生执行线程(thread)、取得虚拟内存的信息 、刺探操作系统的各种数据。但是它不能有华丽的外表-因为它不能调用 与GUI有关的各种API 函数。 DOS程序和Console程序两者都可以做 printf输出和cout输出,也都可以 做scanf 输入和cin输入 内容提要 Win32程序开发流程 以消息为基础,以事件驱动之 一个具体而微的Win32程序 Console程序及其与DOS程序的差别 实例介绍 JBACKUP:Win32 Console程序设计(例1) 本程序检查SrcDir中所有的文件和DstDir中所有的文件,把比较新的文 件从SrcDir中拷贝到DstDir去,并把DstDir中多出来的文件删除,使 SrcDir和DstDir两个目录文件保持完全一致。本程序使用到以下API: JBACKUP(2) 在处理完毕命令行参数中的SrcDir和DstDir之后,本程序先把SrcDir中的

温馨提示

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

评论

0/150

提交评论