A customer wanted to show a dialog box, but they didn’t want it to be attached to any of their existing windows because it was a general dialog that applied to all of their windows. So they had a great idea: Their program already had a message-only window, so they figured, “Hey, I already have this garbage window I can use as the owner of some UI.”
They used their message-only window as the owner of their dialog box, and the dialog showed up on the screen. But wait, they did a closer reading of the message-only window documentation, and it said
To create a message-only window, specify the HWND_MESSAGE constant or a handle to an existing message-only window in the hWndParent parameter of the CreateWindowEx function.
Since their existing message-only window is the owner of the dialog box (passed in the overloaded hwndParent parameter), the expectation is that the dialog box would itself be a message-only window and therefore not appear. Yet it appeared?
The documentation for message-only windows is poorly-worded enough to be incorrect.
The correct wording is that a message-only window is one whose parent or owner is HWND_MESSAGE.
Children of message-only windows are technically not message-only windows, although a lot of message-only behaviors apply to them simply because they are a child of a non-visible parent window: They inherit the non-visibility from their parent, just like any other child window. And child windows are not enumerated by FindWindow, nor do they receive broadcast messages.
(If I’m lucky, the documentation correction will be published before this article goes out.)
But whether the precise definition of a message-only window is correct, it shouldn’t matter whether the mechanism works, because you shouldn’t do it.
Message-only windows are windows that are intended to receive only messages sent or posted directly to them. You use them when you want to use the message queue as a communication channel rather than for hosting UI.
So don’t host UI on a message-only window. That’s not what it’s for. If you want the dialog box to be independent of other top-level windows, you can use NULL as the owner, in which case it appears on the taskbar and in the Alt+Tab list. If you want to hide the dialog from the taskbar and the Alt+Tab list, then create your own hidden window (not message-only) and use that hidden window as the owner.¹
Bonus chatter: If you use HWND_ as the owner window for functions like DialogÂBox or MessageÂBox, you’d think, “Oh, well, the dialog box will just become one big message-only window. The user can’t see it, but I can still manipulate it programmatically.” And then you find that, no, the DialogÂBox and MessageÂBox functions simply fail when given HWND_ as an owner. That’s because those functions, as part of their parameter validation, do an IsWindow(hwndOwner), and IsWindow(HWND_ is FALSE because and HWND_ is not a real window; it’s a sentinel value for CreateÂWindow and FindÂWindowÂEx. As far as DialogÂBox and MessageÂBox are concerned, HWND_ is an invalid window, so passing it as hwndOwner fails with “invalid parameter”.
Bonus bonus chatter: Sometimes we see programs that build an entire universe inside a message-only window, and then use the SetÂParent trick to convert the message-only window into a non-message-only window, as if to say, “Ta-da! Here I am!” Please don’t do that. Building your universe probably involves sending internal messages (for example, child windows may send WM_ messages to their parent), which is sort of what message-only windows don’t want. “Don’t bother me with your own weird messages. I care only about my own messages.” Just keep your top-level window hidden and then show it when you’re ready.
¹ For keyboard accessibility, your options are either to put the dialog box in the Alt+Tab list, or to hide it from the Alt+Tab list but provide some other keyboard mechanism to get focus back to that dialog box. For example, you might say, “Go back to whatever you did to trigger the dialog box in the first place, and trigger it again.” This alternate solution is the mechanism that Windows 95’s Explorer used to put keyboard focus back onto a property sheet: Go back to the original thing and ask for Properties again. (Today, Explorer just puts the property sheet in the Alt+Tab list.)
0 comments
Be the first to start the discussion.