WM_USER与WM_APP的区别

17
我希望工作线程向 UI 线程的消息队列发送一个用户定义的消息,但我不确定是否应该使用 WM_USER 还是 WM_APP。关于 WM_APP 的文档说:

WM_APP 到 0xBFFF

可供应用程序使用的消息。

那么,我应该使用 WM_APP 吗?


4
WM_APP是更安全的选择,不太可能与控件使用的消息发生冲突。但这假设您知道其他后台线程正在干涉UI线程。如果您想确保绝对安全,并保证永远不会发生冲突,则应使用RegisterWindowMessage()。 - Hans Passant
@David Haim 是的,我会使用主窗口的句柄来发送消息。 - Tom
@David Haim 但是我怎么知道WinAPI不使用哪些整数呢?! - Tom
例如,在此处:http://wiki.winehq.org/List_Of_Windows_Messages,列出了Windows消息的列表。 - David Haim
3
@DavidHaim:Windows RT是Windows API的本地后继者。你剩下的评论基本上是误导的,甚至没有解决被问到的问题。未来的读者可以安全地跳过它们。 - IInspectable
显示剩余11条评论
2个回答

11

Microsoft在其API方面非常保守,因此当您看到消息 WM_APP 到0xBFFF时不会与系统消息发生冲突,您可以放心使用。除非Windows API有重大变化,否则该规则需要被打破,而许多其他应用程序也无法幸存。

唯一相关的问题是:您是否需要在 WM_USER 范围或 WM_APP 范围内使用消息?

MSDN说

第二个范围内的消息号(从WM_USER到0x7FFF)可以由应用程序定义和使用,以便在一个私有窗口类内发送消息。这些值不能用来定义整个应用程序中有意义的消息,因为一些预定义的窗口类已经在此范围内定义了值。例如,预定义的控件类如BUTTON、EDIT、LISTBOX和COMBOBOX可能会使用这些值。除非应用程序已经设计好了交换消息并将相同的含义附加到消息号上,否则不应将这个范围内的消息发送到其他应用程序

第三个范围内的消息号(从0x8000到0xBFFF)可供应用程序用作私有消息。这个范围内的消息不会与系统消息发生冲突。

(强调是我的)

如果您明确将这些消息发布到一个专门设计用于以特定方式处理它们的窗口,并且不是Windows控件的子类,则可以使用 WM_USER 范围。如果它们直接由消息循环处理(如 WM_QUIT ),或者如果存在疑问,使用 WP_APP 范围。

换句话说,由于您不需要很多此类消息,并且希望将它们发布到UI线程消息队列中,因此只需使用 WM_APP 范围中尚未被应用程序使用的一个范围,并确保为以后的维护记录它们。


1
发送到窗口的消息通常不由消息循环处理。消息循环将它们分派给适当的接收者进行处理。WM_QUIT不同,它是一条发送到线程而不是窗口的消息。 - IInspectable
3
@IInspectable表示OP说该消息应该发布到“UI线程消息队列”。好的,我刚看到OP在评论中说它将由其主窗口处理,所以WM_USER应该是安全的……前提是其主窗口没有从对话框窗口子类化。这就是为什么我的建议是如果不确定,请使用WM_APP范围。 - Serge Ballesta

3
如果您完全控制目标窗口的窗口类(即您定义了它,您没有子类化/超类化另一个类,并且您不在您的窗口上使用IsDialogMessage),那么您可以使用WM_USER + xxx(其中x>= 0)。
否则,您应该至少使用WM_APP + xxx,前提是您控制包含窗口的应用程序。
如果以上都不行,唯一剩下的选择就是RegisterWindowMessage()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接