在程序的调试版本中,我创建了一个可见的窗口,WM_QUERYENDSESSION
消息由其WNDPROC
接收。在发布版本中,该窗口应该只是消息,所以在调用CreateWindowEx()
时,我将HWND_MESSAGE
指定为hWndParent
。不幸的是,我再也没有收到WM_QUERYENDSESSION
消息了。
WM_QUERYENDSESSION
是这里提到的广播消息之一吗?
仅消息窗口[…]不接收广播消息。
MSDN给出了"仅消息窗口"的良好定义:
仅限消息的窗口允许您发送和接收消息。它不可见,没有z顺序,无法枚举,并且不接收广播消息。该窗口只是发送消息。
突出显示相关详细信息。
您可以使用它们来利用自己代码中的消息调度机制。最典型的是让工作线程以线程安全的方式与UI线程进行对话。消息循环是生产者-消费者问题的通用解决方案。例如,COM中的单元封送处理是通过仅消息窗口实现的。显然,这样的窗口应该被隐藏,只获取应用程序定义的消息。
调用CreateWindowEx时,不要将HWND_MESSAGE用作hWndParent。
将hWndParent的HWND_MESSAGE替换为NULL,您应该会得到您想要的行为。
Per Raymond Chen的博客:
仅消息窗口可以接收什么类型的消息?
。。。
纯消息窗口的意义在于,它只接收专门发送或张贴给它的消息。您可以使用它在发件人和窗口之间设置一个专用通道。创建仅消息窗口后,您可以通过调用Postmessage并传递该窗口句柄将消息放入窗口的队列中,也可以通过调用sendmessage并传达该窗口句柄来发送未排队的消息。
仅消息窗口之所以有趣,是因为它不参与广播消息。
许多窗口消息被发送到所有顶级窗口。WM_QUERYENDSESSION、WM_SETTINGCHANGE、WM_DDE_INITIATE。以及使用HWND_BROADCAST发送的任何内容这些消息不会到达仅限消息的窗口。
在内部,仅消息窗口被视为系统管理的公共父窗口HWND_message的子窗口。此系统管理的通用父窗口是永久不可见的,这将导致只显示消息的窗口永久不可见。这也是仅消息窗口对枚举和广播不可见的原因:对顶级窗口执行枚举和广播,但仅消息窗口在内部被视为HWND_message的子窗口,因此不被视为顶级。