• 8.windows消息机制(三)


    1.消息队列

      消息队列用于存放消息的一个队列,消息在队列中先入先出。所有窗口程序都具有消息队列,程序可以从队列中获取消息。

    2.消息队列的类型

      系统消息队列 - 由系统维护的消息队列,存放系统产生的消息,例如鼠标、键盘等。

      程序消息队列 - 属于每一个应用程序(线程)的消息队列,由应用程序(线程)维护。

    3.消息队列机制

      所有的消息都先进系统的消息队列,系统每隔一段时间就发到每个进程的消息队列。

      例如:

        当鼠标、键盘产生消息时,会将消息存放到系统消息队列。系统会根据存放的消息,找到对应窗口(进程)的消息队列。

        将消息投递到程序(进程)的消息队列。

      那么系统是怎么准确地发到某个进程的消息队列呢?

      首先通过消息的窗口句柄,找到保存窗口数据的内存地址,然后拿到当前程序实例句柄(即进程)。

      PostMessage,是把消息发到系统队列,为什么?

        因为如果不发到系统队列,直接发到进程队列,那么可能造成后产生的消息先处理。

      SendMessage,把消息既不发到系统消息队列也不发到进程消息队列,那么发到哪里?

         发到消息的窗口处理函数(其实内部是直接调用窗口处理函数),内部简单执行过程:

        SendMessage(...)

        {

          进过一系列匹配找到窗口处理函数

          return WndProc(...);

        }

    4.队列消息和非消息队列的关系

      (1)使用关系

         队列消息:消息的发送和获取,都是通过消息队列完成。

         非队列消息:消息的发送和获取,是直接调用消息的窗口处理完成。

      (2)队列消息 - 消息发送后,先放入系统队列,然后通过消息循环,从队列中获取。

         GetMessage - 从消息队列中获取消息(只能从本进程的队列获取消息)

         PostMessage - 将消息投递到系统队列

         常见队列消息:WM_PAINT、键盘、鼠标、定时器等。

      (3)非消息队列 - 消息发送时,直接查找消息接收窗口的窗口处理函数,调用处理函数,完成消息处理。 

         SendMessage - 直接将消息发送给窗口的处理函数,并等候处理结果。

         常见非队列消息:WM_CREATE、WM_SIZE等。

    5.消息循环

      GetMessage/PeekMessage - 从程序的消息队列中获取消息。

      TranslateMessage - 检查获取的消息,如果是按键消息,产生一个字符消息WM_CHAR,并放入程序的消息队列。

      DispatchMessage - 根据消息找到窗口处理函数,调用窗口处理函数,完成消息处理。

      重点讲一下GetMessage/PeekMessage,目前我们所了解的是GetMessage会到进程的消息队列获取消息,没有就阻塞;如果有,获取消息后返回。

      (1)GetMessage在本程序(进程)消息队列查找消息,如果队列有消息,检查消息是否满足指定条件(HWND,ID范围),不满足就不会取出消息,

                 否则从队列取出消息并返回。

      (2)如果本程序(进程)消息队列没有消息,向系统消息队列获取属于本程序的消息。如果系统消息队列的当前消息属于本程序,系统将消息转发到

                 本程序的消息队列。

      (3)如果系统消息队列没有消息,检查所有窗口需要重新绘制的区域,如果发现有需要绘制的区域,产生WM_PAINT消息,取得消息并返回。

      (4)如果没有重新绘制区域,检查定时器。如果有到时的定时器,产生WM_TIMER消息,取得并返回。

      (5)如果没有到时的定时器消息,整理程序的资源、内存等。

      (6)此时,GetMessage会继续等候下一条消息,而PeekMessage返回FALSE,交出程序的控制权。

      注意:GetMessage如果获取到WM_QUIT,函数返回FALSE。

    6.消息发送

      SendMessage - 用于非队列消息的发送。发送消息到指定的窗口,并等候对象将消息处理,然后返回消息执行结果。

      PostMessage - 用于队列消息的发送。将消息放到系统消息队列,立刻返回。无法获知消息是否被对方处理。

      

  • 相关阅读:
    下载ORACLE中BLOB内容到客户端
    VIEW_PK
    带下拉框的GridView的OnRowEditing
    HyperLinkField
    ArcEngine开发 退出系统报错
    【转载】Winform 中的控件透明设置要点
    【转载】大整数相乘
    c# oracle 分页
    view_fk
    ITopologicalOperator Intersect
  • 原文地址:https://www.cnblogs.com/csqtech/p/5592424.html
Copyright © 2020-2023  润新知