There’s this thing called a message-only window, which is a very misleading name because receiving messages is the thing a window spends all its time doing anyway. It’s like calling something a water-only swimming pool or a heat-only oven.
It’s also a very misleading name because it doesn’t receive all messages. “Wait, the name of this window says that the only thing it can do is receive messages, and now you’re saying it can’t do even that!”
The point of a message-only window is that it receives only messages sent or posted specifically to it. You use it to set up a private channel between the sender and the window. After creating a message-only window, you can put messages in the window’s queue by calling PostMessage
and passing that window handle, or you can send a non-queued message by calling SendMessage
and passing that window handle.
What makes a message-only window interesting is that it doesn’t particpate in broadcast messages.
Many window messages are sent to all top-level windows. WM_
QUERYENDSESSION
, WM_
SETTINGCHANGE
, WM_
DDE_
INITIATE
. and anything sent with HWND_
BROADCAST
. These messages don’t reach message-only windows.
Internally, message-only windows are treated as child windows of a system-managed common parent window called HWND_
MESSAGE
. This system-managed common parent window is permanently invisible, which results in message-only windows being permanently invisible. And that’s also how message-only windows are invisible to enumeration and broadcasts: Enumeration and broadcasting is done to top-level windows, but message-only windows are internally treated as child windows of HWND_
MESSAGE
and therefore are not considered top-level.
0 comments