Windows消息机制-摘要&理解


Windows系统是一个消息驱动的系统

1.消息是一个结构体类型的记录,大致包括:hwnd-窗口句柄、uint-消息常量标识符、wparam-32位消息特定附加信息、lparam32位消息特定附加信息、dword-消息创建时的时间、tpoint-消息创建时鼠标坐标

2.消息队列,Windows能够为所有的应用程序维护一个消息队列,应用程序必须从消息队列中获取消息,然后分派给某个窗口。(应用程序主动去消息队列里获取?)(消息队列可以有多个?)(每个线程都有一个消息队列)

3.消息循环,通过这个循环机制应用程序从消息队列中检索消息,再把它分派给适当的窗口,然后继续从消息队列中检索下一条消息,再分派给适当的窗口,一次进行。(应用程序主动参与循环寻找消息?相当于一个 while(true)无限循环?)(每个应用程序都有自己的消息循环,在循环中得到属于自己的消息,在没有消息时消息循环就将控制权交给系统)
消息循环是应用程序能够持续存在的根本原因。如果循环退出,则应用程序就结束了。

4.窗口过程,每个窗口都有一个窗口过程来接收传递给窗口的消息,它的任务就是获取消息然后响应它,窗口过程是一个回调函数;处理了一个消息后,它通常要返回一个值给Windows。(一个应用程序可以有多个窗口)(回调函数是程序中的一种函数,它是由Windows或外部模块调用的)

一个消息从产生到被一个窗口响应,有五个步骤:

1.系统中发生了某个事件。(DataReceive事件如何被触发?)

2.Windows把这个事件翻译为消息,然后把它放到消息队列中。

3.应用程序从消息队列中接收到这个消息,把它存放在TMsg记录中。

4.应用程序把消息传递给一个适当的窗口的窗口过程。(窗口过程是不是一个系统函数)

5.窗口过程响应这个消息并进行处理。

步骤3,4构成了应用程序的消息循环。消息循环往往是Windows应用程序的核心,因为消息循环使一个应用程序能够响应外部的事件。消息循环的任务就是从消息队列中检索消息,然后把消息传递给适当的窗口。如果消息队列中没有消息,Windows就允许其他应用程序处理它们的消息。

Windows操作系统最大的特点就是其图形化的操作界面,其图形化界面是建立在其消息处理机制这个基础之上的。

Windows消息控制中心就像是一颗心脏,消息就像是血液。

Windows消息控制中心一般是三层结构,其顶端就是Windows内核。Windows内核维护着一个消息队列。第二级控制中心一般是各Windows应用程序的Application对象,从这个消息队列中获取属于自己管辖的消息,后做出处理,有些消息直接处理掉,有些还要发送给下一级窗体(Window)或控件(Control)。第三级控制中心就是Windows窗体对象,每一个窗体都有一个默认的窗体过程,这个过程负责处理各种接收到的消息。

窗体:包括窗口,以及有句柄的控件;control指控件,控件本身也可能是一个window,也可能不是;Application即应用程序,应用程序也可能不会用到Windows消息机制。

1.标准Windows消息,这种消息以WM_打头。

2.通知消息,是针对标准Windows控件的消息。(包括:按钮(Button)、组合框(ComboBox)、编辑框(TextBox)、ListView控件、Treeview控件、工具条(Toolbar)、菜单(Menu)等。每种消息以不同的字符串打头。

3.自定义消息,编程人员还可以自定义消息。

只有具有句柄(handle)的控件才能做到接收消息,转发消息和绘制自身。有句柄的控件本质上都是一个窗体(window),它们可以独立存在,可以作为其它控件的容器,而没有句柄的控件,如Label,是不能独立存在的,只能作为窗口控件的子控件,它不能绘制自身,只能依靠父窗体将它绘制来。

句柄的本质是一个系统自动维护的32位的数值,在整个操作系统的任一时刻,这个数值是唯一的。但该句柄代表的窗体释放后,句柄也会被释放,这个数值又可能被其它窗体使用。也就是说,句柄的数值是动态的,它本身只是一个唯一性标识,操作系统通过句柄来识别和查找它所代表的对象。

然而,并非所有的句柄都是窗体的句柄,Windows系统中还中很多其它类型的句柄,如画布(hdc)句柄,画笔句柄,画刷句柄,应用程序句柄(hInstance)等。这种句柄是不能接收消息的。但不管是哪种句柄,都是系统中对象的唯一标识。本文只讨论窗体句柄。

从消息队列获取消息:可以通过PeekMessage或GetMessage函数从Windows消息队列中获取消息。Windows保存的消息队列是以线程(Thread)来分组的,也就是说每个线程都有自己的消息队列。

发送消息,到指定窗体一般通过以下两个函数完成:SendMessage和PostMessage。两个函数的区别在于:PostMessage函数只是向线程消息队列中添加消息,如果添加成功,则返回True,否则返回False,消息是否被处理,或处理的结果,就不知道了。而SendMessage则有些不同,它并不是把消息加入到队列里,而是直接翻译消息和调用消息处理(线程向自己发送消息才是这样),直到消息处理完成后才返回。所以,如果我们希望发送的消息立即被执行,就应该调用SendMessage。

窗体过程实际上是一个回调函数。所谓的回调函数,实际上就是由Windows操作系统或外部程序调用的函数。回调函数一般都有规定的参数格式,以地址方式传递给调用者。窗口过程中是Windows操作系统调用了,在一个窗口创建的时候,在分配窗体句柄的时候就需要传入回调函数地址。那为什么我们平时编程看不到这个回调函数呢?这是由于我们的编程工具已经为我们生成了默认的窗体过程,这个过程的要做的事情就是判断不同的消息类型,然后做出不同的处理。例如可以为键盘或鼠标输入生成事件等。

事件本质上是对消息的封装,是IDE编程环境为了简化编程而提供的有用的工具。这个封装是在窗体过程中实现的。每种IDE封装了许多Windows的消息,例如:
OnActivate-WM_ACTIVATE
OnClick-WM_XBUTTONDOWN
OnCreate-WM_CREATE
OnDblClick-WM_XBUTTONDBLCLICK
OnKeyDown-WM_KEYDOWN
OnKeyPress-WM_CHAR
OnKeyUp-WIN_KEYUP
OnPaint-WM_PAINT
OnResize-WM_SIZE
OnTimer-WM_TIMER

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值