消息发送(Message Routing)

消息发送(Message Routing)
       系统利用两种方法发送消息到窗口过程函数:1.把消息发送到一个先进先出(First-in,First-out)的队列,这个队列是系统定义的临时存放消息的内存对象。2.直接把消息传递给窗口过程函数。
       被发送给消息队列的消息是队列消息。它们主要是用户通过鼠标和键盘输入引起的消息,例如WM_MOUSEMOVE,WM_LBUTTONDOWN,WM_KEYDOWN,WM_CHAR。其他的队列消息包括:定时器消息,绘画消息,退出消息(WM_TIMER,WM_PAINT,WM_QUIT)。大部分被直接传递给窗口过程函数的消息是非队列消息。
    
       队列消息(Queued Message)
       系统可以一次显示许多窗口。系统利用消息队列来发送鼠标和键盘输入到合适的窗口。
       系统维持一个唯一的系统消息队列和针对每个GUI线程的线程消息队列。为了避免为非GUI线程创建消息队列的开销,所有的线程创建之初都没有消息队列。只有当线程第一次调用Win32 User或GUI函数时,系统才为次线程创建线程消息队列。
    当用户移动鼠标,点击鼠标按键或用键盘打字时,鼠标或键盘的设备驱动会把这种输入转换为消息,并把消息放在系统的消息队列中。系统每次从系统消息队列中取出一个消息,通过检查消息来决定消息的目标窗口。然后把这个消息发送到创建目标窗口的线程的消息队列中。一个线程的消息队列为其创建的窗口接收所有的鼠标和键盘消息。线程从其消息队列中取出消息,然会指示系统把消息传递给合适的窗口过程函数处理。
       除了WM_PAINT消息,系统总是把消息放到消息队列的末尾。这可以确保窗口以先进先出(FIFO)的方式接受输入消息。然而WM_PAINT消息被保存在队列中,并且只有当队列中没有其它消息时,才会被发送到窗口过程处理。对于同一窗口的多个WM_PAINT消息会被组合成一个单个的WM_PAINT消息,把客户区所有无效的部分合并成一个单独的区域。组合WM_PAINT消息可以减少窗口重绘客户区内容的次数。
       系统通过填充一个MSG结构,并把这个结构复制到消息队列的方式来发送一个消息到线程消息队列。MSG结构包含的信息如下:消息的目标窗口句柄,消息标识符,两个消息变量,消息发送的时间,鼠标光标的位置。通过利用PostMessage函数或PostThreadMessage函数,一个线程可以发送一个消息到其自己的消息队列中或到其它线程的消息队列中。
        应用程序可以通过利用GetMessage函数从其消息队列中移除一条消息。也可以利用PeekMessage函数,在不把消息移除消息队列的情况下,检查一个消息。这个函数利用这个消息的信息填充MSG。
        在从消息队列中移除一条消息后,应用程序可以利用DispatchMessage函数指示系统把这条消息发送的窗口过程处理。DispatchMessage函数的参数是指向MSG的指针。这个MSG结构是通过调用GetMessage或PeekMessage函数填充的。DispatchMessage函数把窗口句柄,消息标识符和两个消息参数传递给窗口过程,但是它不会传递消息发送时间或鼠标光标位置。应用程序在处理消息时,可以通过GetMessageTime和GetMessagePos函数获取消息发送时间以及鼠标光标位置的信息。
       当一个线程队列中没有消息时,线程可以利用WaitMessage函数把控制权转移给另外的线程。函数会挂起线程,直到一个新的消息被放到线程的消息队列中。
       你可以调用SetMessageExtraInfo函数把一个值关联到当前线程消息队列。然后通过调用GetMessageExtraInfo函数获取关联到最新消息的值,这个消息可以是通过调用GetMessage或PeekMessage函数获取的。
    
        非队列消息(Nonqueued Message)
        通过系统消息队列和线程消息队列,非队列消息被直接送到目标窗口过程。系统通常发送非队列消息通知窗口事件。例如当用户激活一个新的应用程序窗口时,系统会发送一系列消息,包括WM_ACTIVATE,WM_SETFOCUS,和WM_SETCURSOR。这些消息会告知窗口已被激活,键盘输入已被指向该窗口,鼠标光标已经移动到窗口的边界内。当应用程序调用某个系统函数,非队列消息也可以作为结果。例如在程序利用SetWindowPos函数移动窗口之后,系统会发送一个WM_WINDOWPOSCHANGED消息。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值