ch1Win32基本程序观念.ppt

上传人:牧羊曲112 文档编号:5421230 上传时间:2023-07-05 格式:PPT 页数:29 大小:437.50KB
返回 下载 相关 举报
ch1Win32基本程序观念.ppt_第1页
第1页 / 共29页
ch1Win32基本程序观念.ppt_第2页
第2页 / 共29页
ch1Win32基本程序观念.ppt_第3页
第3页 / 共29页
ch1Win32基本程序观念.ppt_第4页
第4页 / 共29页
ch1Win32基本程序观念.ppt_第5页
第5页 / 共29页
点击查看更多>>
资源描述

《ch1Win32基本程序观念.ppt》由会员分享,可在线阅读,更多相关《ch1Win32基本程序观念.ppt(29页珍藏版)》请在三一办公上搜索。

1、Ch1:Win32基本程序观念,内容提要,Win32程序开发流程以消息为基础,以事件驱动之一个具体而微的Win32程序Console程序及其与DOS程序的差别实例介绍,Win32程序开发流程,以消息为基础,以事件驱动之,一个具体而微的Win32程序,程序进入点WinMain窗口类之注册与窗口之诞生消息循环窗口的生命中枢:窗口函数消息映射(Message Map)的雏形模块定义文件(.DEF)资源描述文件(.RC)Windows程序的生与死空闲时间的处理:OnIdle,程序进入点WinMain,WinMain则是Windows程序的进入点:,Main是一般C程序的进入点:,当Windows的”外

2、壳”(shell,例如Windows的文件管理器或资源管理器)侦测到用户欲执行一个Windows程序,于是调用加载器把该程序加载,然后调用C starup code,后者再调用WinMain,开始执行程序.WinMain的四个参数由操作系统传进来,窗口类之注册与窗口之诞生,注册窗口-RegisterClass设定窗口属性(外貌和行为)创建窗口-CreateWindow显示窗口-ShowWindow,消息循环,初始化工作完成后,WinMain进入所谓的消息循环:While(GetMessage(/分派消息DispatchMessage会将消息传给窗口函数去处理。没有指定函数名称,却可以将消息传送

3、过去,岂不是很玄?这是因为消息发生之时,操作系统已根据当时状态,为它标明了所属窗口,而窗口所属的窗口类又已经明白标示了窗口函数,所以DispatchMessage自有脉络可寻。消息循环中的GetMessage是Windows 3.x系统非强制性(non-preemptive)多任务的关键。应用程序籍由此操作,提供了释放控制权的机会:如果消息队列上没有属于我的消息,我 就把机会让给别人。通过程序之间彼此协调让步的方式,达到多任务能力。Windows 9x和Windows NT具备强制性多任务能力,不再非靠GetMessage释放CPU控制权不可,但程序写法依然不变,因为应用程序仍然需要靠消息推动

4、。,窗口的生命中枢:窗口函数,消息循环中的DispatchMessage把消息分配到哪里呢?它通过USER模块的协助,送到该窗口的窗口函数去了。窗口函数通常利用switch/case方式判断消息种类,以决定处理方式。由于它是被Windows系统所调用(我们并没有在应用程序的任何地方调用此函数),所以这是一种call back函数,意思是指“在你的程序中,被Windows系统调用的函数,这些函数由你设计,但是永远不会也不该被你调用,它们是为Windows系统准备的。在程序进行过程中,消息由输入装置,经由消息循环的抓取,源源传送给窗口并进而送到窗口函数中去。窗口函数的形式:LRESULT CALL

5、BACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)注意,不论什么消息,都必须被处理,所以switch/case指令中的default:处必须调用DefWindowProc,这是Windows内部默认的消息处理函数。我想很多人都会问这个问题:为什么Windows Programming Modal要把窗口函数设计为一个call back函数?为什么不让程序在抓到消息(GetMessage)之后直接调用它?原因是,除了你需要调用它,有很多时候操作系统也要调用你的窗口函数(例如当某个消息产生或某个事件发生)。窗口函数设计为

6、callback形式,才能开放出一个接口给系统调用,消息映射(Message Map)的雏形(1),首先定义一个MSGMAP_ENTRY结构和一个dim宏:请注意MSGMAP_ENTRY的第二个元素pfn是一个函数指针,该指针所指的函数处理nMessage消息。这正是面向对象观念中把“数据”和“处理数据的方法”封装起来的一种具体实现,消息映射(Message Map)的雏形(2),接下来,组织两个数组_messageEntries 和_commandEntries,把程序中欲处理的消息以及消息处理例程的关联性建立起来,消息映射(Message Map)的雏形(3),于是窗口函数可以这么设计:O

7、nCommand函数可以这么设计:,消息映射(Message Map)的雏形(4),这么一来,WndProc和OnCommand永远不必改变,每当有新的要处理的消息,只要在_messageEntries 和_commandEntries 两个数组中加上新元素,并针对新消息撰写新的处理例程即可。这种观念及做法就是MFC的Message Map雏形。MFC把其中的操作封装得更好更精致,成为一张庞大的消息地图,程序一旦获得消息,就可以按图上溯,直到被处理为止。,对话框的运行,Windows的对话框依其与父窗口的关系,分为两类:1.令其父窗口无效,直到对话框结束-modal对话框 2.父窗口与对话框共

8、同运行-modeless对话框为了做出一个对话框,程序员必须准备两样东西:1.对话框模版(dialog template)。这是在RC文件中定义的一个对话框外貌,以各种方式决定对话框的大小、字形、内部有哪些控件、各在什么位置等。2.对话框函数(dialog procedure)。其型态非常类似于窗口函数,但是它通常只处理WM_INITDIALOG和WM_COMMAND两个消息。对话框中的各个控件也都是小小窗口,各有自己的窗口函数,它们以消息与其管理者(父窗口,也就是对话框)沟通。而所有的控件传来的消息都是WM_COMMAND,再由其参数分辨哪一种控件以及哪一种通知消息(notification

9、)对话框的结束与激活,靠的是DialogBox和EndDialog两个API函数。,对话框的诞生、运行、结束,模块定义文件(.DEF),Windows程序需要一个模块定义文件,将模块名称、程序段和数据段的内存特性、模块堆(heap)大小、堆栈(stack)大小,所有callback函数名称等等登记下来。,在Visual C+开发环境中开发程序,不再需要特别准备.DEF文件,因为模块定义文件中的设定都有默认值。模块定义文件中的STUP指令用来指定所谓的stub程序(埋在windows程序中的一个DOS程序,你所看到的This Program Requires Microsoft windows或

10、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

11、消息,准备让消息循环中的GetMessage取得,如步骤2,消息循环结束。,为什么结束一个程序如此复杂?因为操作系统与应用程序职责不同,二者是相互合作的关系,所以必须各做各的份内事,并互以消息通知对方。如果不依据这个游戏规则没,则可能就会有麻烦产生。你可以作一个小实验,在窗口函数中拦截WM_DESTROY,但不调用PostQuitMessage。你会发现当选择系统菜单中的Close时,屏幕上的这个窗口消失了(因为窗口销毁及数据结构的释放是DefWindowProc调用DestroyWindow完成的),但是应用程序本身并没有结束(因为消息循环结束不了),它还留在内存中。,1.程序初始化过程中调

12、用CreatWindow,为程序建立了一个窗口,作为程序的屏幕舞台。CreatWindow产生窗口之后会送出WM_CREATE消息给窗口函数,后者于是可以在此时做些初始化工作(例如配置内存、打开文件、读取数据.),2.在程序或者的过程中,不断以GetMessage从消息队列中抓取消息。如果这个消息是WM_QUIT,GetMessage会传回0而结束while循环,进而结束整个程序.,3.DispatchMessage通过windows USER模块的协助与监督,把消息分派至窗口函数.消息将在该处被判别并处理。,4.程序不断进行2.和3.的操作。,5.当使用者按下系统菜单中的Close命令项时,

13、系统送出WM_CLOSE。通常程序的窗口函数不拦截此消息,于是DefWindowProc处理它。,6.DefWindowProc收到WM_CLOSE后,调用DestroyWindow把窗口清除。DestroyWindow本身又送出WM_DESTROY。,7.程序对WM_DESTROY的标准反应是调用PostQuitMessage。,窗口的生命周期,空闲时间的处理:OnIdle,所谓空闲时间是指“系统中没有任何消息等待处理”的时间后台工作最适宜在空闲时间完成。传统的SDK程序如果要处理空闲时间,可以以下列循环取代WinMain中传统的消息循环:原因是PeekMessage和GetMessage的

14、性质不同。它们都是到消息队列中抓消息,如果抓不到,程序的主执行线程(primary thread,是一个UI执行线程)会被操作系统挂起。当操作系统再次回来照顾这一执行线程时,发现消息队列仍然是空的,这时候两个API函数的行为就由不同了:GetMessage会过门不入,于是操作系统再去照顾其他人。PeekMessage会取回控制权,使程序得以执行一段时间。于是上述消息循环进入了OnIdle函数中。,内容提要,Win32程序开发流程以消息为基础,以事件驱动之一个具体而微的Win32程序Console程序及其与DOS程序的差别,Console程序,并非所有的Win32程序都如Windows GUI程

15、序那么复杂可怖。你也可以在Visual C+中写一个DOS-like程序,而且仍然可以调用部分的、不牵扯到图形使用者接口(GUI)的Win32 API。这种程序称为console程序。甚至你还可以在console程序中使用部分的MFC类(同样必须是与GUI没关联的),例如处理数组、链表等数据结构的collection classes(CArray、Clist、Cmap)、与文件有关的CFile、CStdioFile。除了DOS-like,console程序还另有妙用。如果你的程序与使用者之间是以巨量文字来互动,或许你会选择使用edit控件(或MFC的CEditView)。但是你知道,计算机在一

16、个纯粹的“文字窗口”(也就是console窗口)中处理文字的显示与滚动比较快,你的程序操作也比较简单。,Console与DOS程序的差别,编写方式:在Windows环境下的Dos Bos中,或是在windows版本的各种C+的编译器套件的集成开发环境中,利用windows编译器、链接器作出来的程序,都是所谓的win32程序。如果程序是以main为进入点,调用C runtime函数和“不牵扯GUI”的win32 API函数,那么就是一个console程序,console窗口将成为其标准输入和输出装置(cin和cout)。过去在DOS环境下开发的程序,称为DOS程序,它也是以main为进入点,可以

17、调用C runtime函数,但不可能调用win32 API。程序功能:过去的Dos程序仍然可以在Windows的DOS Box中运行。由于Console程序可以调用部分的Win32 API(尤其是KERNEL32.DLL模块所提供的那一部份),所以它可以使用Windows提供的各种高级功能.它可以产生进程(processes),产生执行线程(thread)、取得虚拟内存的信息、刺探操作系统的各种数据。但是它不能有华丽的外表-因为它不能调用与GUI有关的各种API 函数。DOS程序和Console程序两者都可以做 printf输出和cout输出,也都可以做scanf 输入和cin输入,内容提要,

18、Win32程序开发流程以消息为基础,以事件驱动之一个具体而微的Win32程序Console程序及其与DOS程序的差别实例介绍,JBACKUP:Win32 Console程序设计(例1),本程序检查SrcDir中所有的文件和DstDir中所有的文件,把比较新的文件从SrcDir中拷贝到DstDir去,并把DstDir中多出来的文件删除,使SrcDir和DstDir两个目录文件保持完全一致。本程序使用到以下API:,JBACKUP(2),在处理完毕命令行参数中的SrcDir和DstDir之后,本程序先把SrcDir中的所有文件(不含子目录文件)搜寻一遍,储存在一个数组srcFiles中,每个数组元

19、素是自定义的一个数据结构:,JBACKUP(3),再把DstDir中的所有文件(不包含子目录)搜寻一遍,储存在一个dstFiles数组中,每个数组元素是一个自定义的数据结构:,JBACKUP(4),然后对比srcFiles和dstFiles之中的所有文件名称及创建日期,找出srcFiles中哪些文件比dstFiles中的文件更新,然后将其bIsNew字段设为TRUE。同时也对存在于dstFiles中而不存在于srcFiles中的文件,令其bMatch字段为FALSE。最后检查srcFiles中的文件,将bIsNew为TRUE者,拷贝到dstFiles。并检查dstFiles中的所有文件,将bMatch为FALSE者统统杀掉,MFCCON:MFC Console程序设计(例2),在MFC中,CFile用来处理正常的文件I/O操作。CStudioFile衍生自Cfile,一个CStdioFile对象代表以C runtime函数fopen所开启的一个stream文件。Stream文件有缓冲区,可以以文字模式(默认状态)或二进制模式开启。Cstring对象代表一个字符串,是一个完全独立的类.本例用来计算小于100的所有Fabonacci sequence(头两个字为1,接下来的每一个数是前两个数之和),

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号