【问题标题】:WM_PAINT message is queued message or Nonqueued Messages?WM_PAINT 消息是排队消息还是非排队消息?
【发布时间】:2014-11-01 00:27:21
【问题描述】:

About Messages and Message Queues这篇文章中,有人说WM_PAINT是一种排队消息。

排队的消息

每当用户移动鼠标、单击鼠标按钮或键入 在键盘上,鼠标或键盘的设备驱动程序转换 消息的输入并将它们放入系统消息队列中。 系统从系统中一次删除一条消息 消息队列,检查它们以确定目标窗口,以及 然后将它们发布到创建的线程的消息队列中 目标窗口。线程的消息队列接收所有鼠标和 线程创建的窗口的键盘消息。线程 从其队列中删除消息并指示系统将它们发送到 用于处理的适当窗口过程。

除了 WM_PAINT 消息、WM_TIMER 消息和 WM_QUIT 消息, 系统总是在消息队列的末尾发布消息。这 确保窗口以正确的方式首先接收其输入消息 进先出 (FIFO) 序列。 WM_PAINT 消息,WM_TIMER 消息,而 WM_QUIT 消息则保留在队列中,并且 仅当队列不包含 其他消息。此外,相同的多个 WM_PAINT 消息 窗口被组合成一个 WM_PAINT 消息,合并所有 客户区的无效部分合并为一个单独的区域。结合 WM_PAINT 消息减少了窗口必须重绘的次数 其客户区的内容。

但根据《编程窗口》一书

然而,窗口过程可以调用一个函数来发送 窗口过程另一个消息,在这种情况下窗口过程 必须在函数调用之前完成第二条消息的处理 返回,此时窗口过程继续原来的 信息。例如,当一个窗口过程调用 UpdateWindow 时, Windows 使用 WM_PAINT 消息调用窗口过程。当。。。的时候 窗口过程完成处理 WM_PAINT 消息, UpdateWindowcall 会将控件返回给窗口过程。

如果 WM_PAINT 是排队消息,则应将其添加到消息队列中。 所以它不会处理,直到当前消息和消息队列中的所有其他消息都被处理完。这与上述说法存在争议。

我想知道哪个是正确的,谢谢。

【问题讨论】:

  • 消息从窗口状态发送、发布或合成。 WM_PAINT 属于后者,当窗口的更新矩形不为空时生成。并且没有剩余的已发送或已发布消息。 WM_MOUSEMOVE 是另一个,更间接的是,您不会为鼠标遍历的每个像素都收到该消息。

标签: windows winapi


【解决方案1】:

任何消息都可以使用SendMessage 直接发送到窗口过程,或使用PostMessage 发送到窗口的消息队列。 UpdateWindow 函数使用SendMessageWM_PAINT 消息直接发送到窗口过程,以便立即重绘窗口。当系统出于某种原因需要重新绘制窗口时,它通常会将消息发布到窗口的消息队列中。

所以WM_PAINT 不是排队(已发布)的消息,也不是已发送的消息。这只是一条消息。它可以发送或发布。有些消息仅用于发送或发布,但WM_PAINT 不是其中之一。

【讨论】:

    【解决方案2】:

    这是来自MSDN的关于UpdateWindow函数的文档

    UpdateWindow 函数更新指定的客户区 窗口通过向窗口发送 WM_PAINT 消息,如果窗口的 更新区域不为空。该函数发送 WM_PAINT 消息 直接到指定窗口的窗口过程,绕过 应用程序队列。如果更新区域为空,则没有消息 已发送。

    【讨论】:

      猜你喜欢
      • 2016-06-16
      • 2012-04-02
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      • 2015-09-23
      • 1970-01-01
      • 2022-09-29
      相关资源
      最近更新 更多