4

In the debug version of the program, I create a visible window, and the WM_QUERYENDSESSION message is received by its WNDPROC. In the release version, the window is supposed to be message-only, so I specify HWND_MESSAGE as the hWndParent when calling CreateWindowEx(). Unfortunately, I then don't receive the WM_QUERYENDSESSION message anymore.

Is WM_QUERYENDSESSION one of those broadcast messages mentioned here?

A message-only window [...] does not receive broadcast messages.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Andreas Haferburg
  • 5,189
  • 3
  • 37
  • 63

3 Answers3

5

MSDN gives a decent definition of a "message-only window":

A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.

Relevant detail highlighted.

You use them to take advantage of the message dispatch mechanism in your own code. Most typically to get a worker thread to talk to the UI thread in a thread-safe way. A message loop is the universal solution to the producer-consumer problem. Apartment marshaling in COM is implemented with a message-only window for example. Clearly such a window should be hidden and only get the messages that are defined by the app.

Don't use HWND_MESSAGE as hWndParent when calling CreateWindowEx.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I see. I know that `FindWindowExA(HWND_MESSAGE, ...)` would work, but Windows probably doesn't use it when it sends `WM_QUERYENDSESSION`. Why would it, really. Anyways, thank you. – Andreas Haferburg Jan 15 '14 at 15:41
  • @Hans Passant: 1) "Don't use HWND_MESSAGE as hWndParent when calling CreateWindowEx" - but what about "CreateWindowEx... hWndParent... To create a message-only window, supply HWND_MESSAGE" (from MSDN) ? – kero Jan 15 '14 at 17:32
  • @Hans Passant: 2) "cannot be enumerated" (from MSDN) - but what about enumeration via EnumChildWindows(GetAncestor(FindWindowEx(HWND_MESSAGE,0,0,0),GA_PARENT))...) ? – kero Jan 15 '14 at 17:32
  • I don't understand why you are asking me. I never saw any point in writing code like that so I don't know. Just try it yourself if you want to find out. – Hans Passant Jan 15 '14 at 17:43
  • @Hans Passant: Because I'm interested in the meaning of the term "enumerated" by MSDN. As for the code - I checked it already long ago (http://files.rsdn.ru/42164/wintreesnap.zip) – kero Jan 15 '14 at 18:00
3

Replace HWND_MESSAGE with NULL for hWndParent and you should get the behavior you intend.

Vans S
  • 1,743
  • 3
  • 21
  • 36
2

Per Raymond Chen's blog:

What kind of messages can a message-only window receive?

...

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 Post­Message and passing that window handle, or you can send a non-queued message by calling Send­Message 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_QUERY­END­SESSION, WM_SETTING­CHANGE, 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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770