![WINDOWS的消息机制与回调机制_第1页](http://file4.renrendoc.com/view/92e56a2bbf916975704de3014475b4f9/92e56a2bbf916975704de3014475b4f91.gif)
![WINDOWS的消息机制与回调机制_第2页](http://file4.renrendoc.com/view/92e56a2bbf916975704de3014475b4f9/92e56a2bbf916975704de3014475b4f92.gif)
![WINDOWS的消息机制与回调机制_第3页](http://file4.renrendoc.com/view/92e56a2bbf916975704de3014475b4f9/92e56a2bbf916975704de3014475b4f93.gif)
![WINDOWS的消息机制与回调机制_第4页](http://file4.renrendoc.com/view/92e56a2bbf916975704de3014475b4f9/92e56a2bbf916975704de3014475b4f94.gif)
![WINDOWS的消息机制与回调机制_第5页](http://file4.renrendoc.com/view/92e56a2bbf916975704de3014475b4f9/92e56a2bbf916975704de3014475b4f95.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
WINDOWS的消息机制与回调机制声明CALLBACK调用(calling)机制从汇编时代起已经大量使用:准备一段现成的代码,调用者可以随时跳转至此段代码的起始地址,执行完后再返回跳转时的后续地址。CPU为此准备了现成的调用指令,调用时可以压栈保护现场,调用结束后从堆栈中弹出现场地址,以便自动返回。借堆栈保护现场,它使调用者和被调者可以互不相识,于是才有了后来的函数和构件.此调用机制并非完美。回调函数就是一例。例如,写一个快速排序函数供他人调用,其中必包含比较大小。麻烦来了:此时并不知要比较的是何类数据--整数、浮点数、字符串?于是只好为每类数据制作一个不同的排序函数。更通行的办法是在函数参数中列一个回调函数地址,并通知调用者:君需自己准备一个比较函数,其中包含两个指针类参数,函数要比较此二指针所指数据之大小,并由函数返回值说明比较结果。排序函数借此调用者提供的函数来比较大小,借指针传递参数,可以全然不管所比较的数据类型。被调用者回头调用调用者的函数(够咬嘴的),故称其为回调(callback)。Windows系统还包含着另一种更为广泛的回调机制,即消息机制。消息本是Windows的基本控制手段,乍看与函数调用无关,其实是一种变相的函数调用。发送消息的目的是通知收方运行一段预先准备好的代码,相当于调用一个函数。消息所附带的WParam和LParam相当于函数的参数,只不过比普通参数更通用一些。应用程序可以主动发送消息,更多情况下是坐等Windows发送消息。一旦消息进入所属消息队列,便检感兴趣的那些,跳转去执行相应的消息处理代码。操作系统本是为应用程序服务,由应用程序来调用。而应用程序一旦启动,却要反过来等待操作系统的调用。这分明也是一种回调,或者说是一种广义回调。其实,应用程序之间也可以形成这种回调。假如进程B收到进程A发来的消息,启动了一段代码,其中又向进程A发送消息,这就形成了回调。这种回调比较隐蔽,弄不好会搞成递归调用,若缺少终止条件,将会循环不已,直至把程序搞垮。若是故意编写成此递归调用,并设好终止条件,倒是很有意思。但这种程序结构太隐蔽,除非十分必要,还是不用为好。利用消息也可以构成狭义回调。上面所举排序函数一例,可以把回调函数地址换成窗口handle。如此,当需要比较数据大小时,不是去调用回调函数,而是借API函数SendMessage向指定窗口发送消息。收到消息方负责比较数据大小,把比较结果通过消息本身的返回值传给消息发送方。所实现的功能与回调函数并无不同。当然,此例中改为消息纯属画蛇添脚,反倒把程序搞得很慢。但其他情况下并非总是如此,特别是需要异步调用时,发送消息是一种不错的选择。假如回调函数中包含文件处理之类的低速处理,调用方等不得,需要把同步调用改为异步调用,去启动一个单独的线程,然后马上执行后续代码,其余的事让线程慢慢去做。一个替代办法是借API函数PostMessage发送一个异步消息,然后立即执行后续代码。这要比自己搞个线程省事许多,而且更安全。如今我们是活在一个object时代。只要与编程有关,无论何事都离不开object。但object并未消除回调,反而把它发扬光大,弄得到处都是,只不过大都以事件(event)的身份出现,镶嵌在某个结构之中,显得更正统,更容易被人接受。应用程序要使用某个构件,总要先弄清构件的属性、方法和事件,然后给构件属性赋值,在适当的时候调用适当的构件方法,还要给事件编写处理例程,以备构件代码来调用。何谓事件?它不过是一个指向事件例程的地址,与回调函数地址没什么区别。不过,此种回调方式比传统回调函数要高明许多。首先,它把让人不太舒服的回调函数变成一种自然而然的处理例程,使编程者顿觉气顺。再者,地址是一个危险的东西,用好了可使程序加速,用不好处处是陷阱,程序随时都会崩溃。现代编程方式总是想法把地址隐藏起来(隐藏比较彻底的如VB和Java),其代价是降低了程序效率。事件例程使编程者无需直接操作地址,但并不会使程序减速。回调函数:它是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象、全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的函数地址传递给该对象(被调用者)。这个函数就是调用者和被调用者之间的一种通知约定,当约定的事件发生时,被调用者(一般会包含一个工作线程)就会按照回调函数地址调用该函数,并向被调用者返回一个结果。这种方式,调用者在一个线程,被调用者在另一个线程。句柄:handle,handle的本意是把柄,把手的意思,就是一个标号。是你与操作系统打交道的东东。举个通俗的例子,比如你考上了大学,入学后,学校(操作系统)会给你一个学生证号。注意,这个号码是学校指定的,你无法自选。有了这个号码(学生证,假设一证多用)就可以享受学校提供的服务:如你就可以去图书馆借书,去食堂吃饭,去教室上课等等。但你不能到食堂里买啤酒,因为学校不允许这种服务。而在计算机中系统提供的服务就是API调用,你有了HANDLE,就可以理直气壮地向系统提出调用API的服务。而指针的权力就大多了,有了指针你可以到处去喝酒,打架,学校(操作系统)管不着,所以句柄和指针的区别在于句柄只能调用系统提供的服务。而句柄虽然是一个能相互区别的号码,但与我们普通的ID号又有区别,普通的ID号是可以由程序员自己定义的,而句柄不行,它是对象生成时系统指定的,是为了区别系统中存在的各个对象,这个句柄不是由程序员符给的。实际应用中,最常用的就是文件句柄和窗口句柄。例如,窗口句柄的值是一个长整数,每个窗体都用一个句柄来表示。所以句柄是不会重复的,很多的函数都会用到窗体的句柄。消息:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)组成。windows的消息机制:消息”是windows运行机制中一个基本而又重要的概念。消息是一个报告事件发生的通知,消息驱动是围绕消息的产生与处理展开的,并依靠消息循环机制来实现。某条消息可被视为某个事件的发生,比如点击鼠标。事件即可以由用户引发,也可以由应用程序产生,当然windows本身也能发出消息。windows是一个多任务操作系统,所以没有哪一个程序能够独占系统的资源,资源都是由windows统一管理的。那么某个程序是如何获得用户的信息呢?事实上,windows在时刻监视着用户的每个举动,一旦发生了动作,就由windows捕捉而不是应用程序,windows分析该动作与哪一个程序相关,然后将动作以消息的形式发送给当前的应用程序。相反,应用程序也在时时等着消息的到来,一旦发现它的消息队列中有未处理的信息,就获取并分析该消息,并根据消息所包含的内容采取适当的动作来响应,并将结果返回给系统。例如窗口程序,当用户点击按钮时候,这一动作被windows捕捉,并且以消息(ID和参数)的形式发给该窗口的消息队列,该窗口发现队列中有消息,就根据消息调用相应的过程进行处理,并将返回结果返回给系统。每个窗口本身都有一个窗口函数,未处理的消息就由它处理,例如拖动。windows为每个线程维护了相应的消息队列,应用程序的任务就是不停地从特定的消息队列中获取消息、分析消息并处理消息,直到消息(WM_QUIT)为止。这个过程的程序结构称为''消息循环”。函数回调与消息机制:可以看出,消息机制是一种特殊的函数回调。因为应用程序本是调用系统函数的,但是一旦启动就等待系统发来的消息,等到消息调用相应过程进行处理,相当于系统进行了回调。所以消息机制是一种广义的函数回调。Windows消息机制要点1.窗口过程每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(WindowHandle),消息ID(MessageID),和两个消息参数(wParam,IParam),当窗口收到消息时系统就会调用此窗口过程来处理消息。(所以叫回调函数)2消息类型1)系统定义消息(System-DefinedMessages)在SDK中事先定义好的消息,非用户定义的,其范围在[0x0000,0x03ff]之间,可以分为以下三类:1>窗口消息(WindowsMessage)与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口等。可以是一般的窗口,也可以是Dialog,控件等。如:WM_CREATE,WM_PAINT,WM_MOUSEMOVE,WM_CTLCOLOR,WM_HSCROLL...2>命令消息(CommandMessage)与处理用户请求有关,如单击菜单项或工具栏或控件时,就会产生命令消息。WM_COMMAND,LOWORD(wParam)表示菜单项,工具栏按钮或控件的ID。如果是控件,HIWORD(wParam)表示控件消息类型3>控件通知(NotifyMessage)控件通知消息,这是最灵活的消息格式,其Message,wParam,lParam分别为:WM_NOTIFY,控件ID,指向NMHDR的指针。NMHDR包含控件通知的内容,可以任意扩展。2)程序定义消息(Application-DefinedMessages)用户自定义的消息,对于其范围有如下规定:WM_USER:0x0400-0x7FFF(ex.WM_USER+10)WM_APP(winver>4.0):0x8000-0xBFFF(ex.WM_APP+4)RegisterWindowMessage:0xC000-0xFFFF消息队歹列(MessageQueues)Windows中有两种类型的消息队列系统消息队列(SystemMessageQueue)这是一个系统唯一的Queue,设备驱动(mouse,keyboard)会把操作输入转化成消息存在系统队列中,然后系统会把此消息放到目标窗口所在的线程的消息队列(thread-specificmessagequeue)中等待处理线程消息队歹J(Thread-specificMessageQueue)每一个GUI线程都会维护这样一个线程消息队列。(这个队列只有在线程调用GDI函数时才会创建,默认不创建。然后线程消息队列中的消息会被送到相应的窗口过程WndProc)处理.注意:线程消息队列中WM_PAINT,WM_TIMER只有在Queue中没有其他消息的时候才会被处理,WM_PAINT消息还会被合并以提高效率。其他所有消息以先进先出(FIFO)的方式被处理。队列消息(QueuedMessages)和非队列消息(Non-QueuedMessages)1)队列消息(QueuedMessages)消息会先保存在消息队列中,消息循环会从此队列中取消息并分发到各窗口处理如鼠标,键盘消息。2)非队列消息(NonQueuedMessages)消息会绕过系统消息队列和线程消息队列直接发送到窗口过程被处理如:WM_ACTIVATE,WM_SETFOCUS,WM_SETCURSOR,WM_WINDOWPOSCHANGED注意:postMessage发送的消息是队列消息,它会把消息Post到消息队列中;SendMessage发送的消息是非队列消息,被直接送到窗口过程处理PostMessage(PostThreadMessage),SendMessagePostMessage:把消息放到指定窗口所在的线程消息队列中后立即返回。PostThreadMessage:把消息放到指定线程的消息队列中后立即返回。SendMessage:直接把消息送到窗口过程处理,处理完了才返回。GetMessage,PeekMessagePeekMessage会立即返回可以保留消息GetMessage在有消息时返回会删除消息TranslateMessage,TranslateAcceleratorTranslateMessage:把一个virtual-key消息转化成字符消息(charactermessage),并放到当前线程的消息队列中,消息循环下一次取出处理。TranslateAccelerator:将快捷键对应到相应的菜单命令。它会把WM_KEYDOWN或WM_SYSKEYDOWN转化成快捷键表中相应的WM_COMMAND或WM_SYSCOMMAND消息,然后把转化后的WM_COMMAND或WM_SYSCOMMAND直接发送到窗口过程处理,处理完后才会返回。8(消息死锁(MessageDeadlocks)假设有线程A和B,现在有以下下步骤1)线程ASendMessage给线程B,A等待消息在线程B中处理后返回2)线程B收到了线程A发来的消息,并进行处理,在处理过程中,B也向线程ASendMessgae,然后等待从A返回。因为此时,线程A正等待从线程B返回,无法处理B发来的消息,从而导致了\线程A,B相互等
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度古建筑修复施工合同文化保护要求
- 2025年度化工原料国际贸易代理合同
- 2025年度城市排水系统机电安装与施工合同范本
- 2025年度竣工资料承包与咨询服务一体化合同
- 2025年度大蒜品牌授权与合作推广合同
- 2025年度护士护理安全管理体系建设合同
- 2025年度红土烧结瓦再生资源回收与循环利用合同
- 2025年度知识产权授权使用合同范本规范
- 2025年度广场砖铺贴施工与城市地下空间开发合同
- 2025年度公司注册办公场地租赁及清洁服务合同
- 湖北省武汉市2024-2025学年度高三元月调考英语试题(含答案无听力音频有听力原文)
- 商务星球版地理八年级下册全册教案
- 天津市河西区2024-2025学年四年级(上)期末语文试卷(含答案)
- 北京市北京四中2025届高三第四次模拟考试英语试卷含解析
- 2024年快递行业无人机物流运输合同范本及法规遵循3篇
- 地下商业街的规划设计
- 伤残抚恤管理办法实施细则
- 中国慢性冠脉综合征患者诊断及管理指南2024版解读
- 提升模组良率-六西格玛
- DL-T+5196-2016火力发电厂石灰石-石膏湿法烟气脱硫系统设计规程
- 2024-2030年中国产教融合行业市场运营态势及发展前景研判报告
评论
0/150
提交评论