在这篇文章关于消息和消息队列中,据说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是排队消息,则应将其添加到消息队列中。 因此,直到当前消息和消息队列中的所有其他消息都已处理完毕后,它才会处理。这与上面的说法有争议。
我想知道哪个是正确的,谢谢。
任何消息都可以使用
SendMessage
直接发送到窗口过程,或者使用 PostMessage
发布到窗口的消息队列。 UpdateWindow
函数使用SendMessage
直接向窗口过程发送WM_PAINT
消息,以便立即重绘窗口。当系统出于某种原因需要重新绘制窗口时,它通常会将消息发布到窗口的消息队列中。
因此
WM_PAINT
不是排队(已发布)消息,也不是已发送消息。这只是一条消息。它可以发送或邮寄。有些消息只能发送或发布,但 WM_PAINT
不是其中之一。
这里是来自MSDN
关于UpdateWindow函数的文档UpdateWindow函数更新指定窗口的客户区 通过向窗口发送 WM_PAINT 消息(如果窗口是 更新区域不为空。该函数发送WM_PAINT消息 直接到指定窗口的窗口过程,绕过 应用程序队列。如果更新区域为空,则不显示任何消息 已发送。
WM_PAINT
实际上并没有被系统发布到消息队列上,与WM_TIMER
相同。如果您尝试从 WM_PAINT
循环中打印 GetMessage
,您将看不到任何内容。 DispatchMessage
不会在 WM_PAINT
消息上调用。
我认为它的工作原理是这样的:操作系统问题
WM_PAINT
总是直接发生。但是,如果不通过 UpdateWindow
调用,它首先检查队列并等待,直到队列完全为空,只有在此之后才使用 SendMessage
调用 WM_PAINT
。这样,您仍然可以在绘制之前处理队列中的所有输入消息。