views:

86

answers:

3

I have a pretty basic understanding of the GUI thread and the message loop, but I'm curious as to how that applies to one window starting a modal window. If I had to guess, I'd say that both windows are being run under the same GUI thread and that some parameter indicates that only events with the child window (the modal one) be executed, otherwise point out the modal window to the user.

This is simply a semi-educated guess and I accept that I may be wrong from square one. I'm not even sure if "GUI thread" is the right name for that thread, but people usually can guess what I'm talking about.

So in short, how do threads and modal windows get along together?

A: 

A window, or rather a window's messages, are handled by the thread that created the window: called CreateWindowEx. This might be indirect, with layers of software between the application code and the CreateWindowEx API call, but the call will always be there when creating a new window.

Richard
+2  A: 

Both windows remain on the same thread. That thread -- the GUI thread -- continues to process messages for both windows.

What's special about a modal dialog is:

  • The dialog's owner is set to the main window. This causes the dialog to always appear on top of the main window. It's possible to do this with modeless windows.

  • The owner window stops receiving user input (mouse and keyboard messages) while the dialog is open. The dialog receives user input as normal. This is achieved by disabling the owner window, in the same way that you might disable a control on a dialog box.

Tim Robinson
Note: it is possible, of course, to set the owner to another window, for instance (which is often done wrong by junior programmers), the desktop.
Abel
Random side question, is there an advantage to setting a window's owner to the desktop? I've never heard of this being done.
Corey Ogburn
There is no advantage. The disadvantage is that it breaks Windows.
Tim Robinson
*"I've never heard of this being done"* >> many free, cheap or shareware programs, or programs ported from Java or other to Windows have this problem, which can be noted when the input focus is removed, but the dialog box is not visible, unless you minimize all windows, where one window will remain on top. As Tim says: no advantage at all. Note that this blocking behavior has changed in Vista and changed further in Windows 7. An example is the Apache Monitor tool, when Apache doesn't start as the result of an error. The dialog box owner is the desktop and the window is hidden behind the owner.
Abel
Sounds like a good thing I don't run into this in my own applications.
Corey Ogburn
+3  A: 

This maybe contradictory, but no, no new thread is started for the new windows. However, a new message loop is opened. This keeps messages flowing through Windows and avoids halting other applications.

Messages will arrive and may be dispatched to the owner window's message loop. On the owner window, keyboard and mouse input have been disabled, but all other messages will be send through. Note from Hans Passant: actually, all top level windows of the same thread will be disabled this way.

As an example that you already touch on in your question, WM_PAINT is send through to the parent window. But also WM_TIMER, for instance. A message like WM_NCHITTEST will not be send through, as it is an input message. Nor will WM_KEYDOWN and similar.

This way, a messagebox can be moved, and the underlying owner gets neatly repainted, or a ticking clock still continues ticking.

Information partially from Rector and Newcomer's Win32 Programming, page 752+, old, but still valuable and valid info. This info applies to DialogBox, DialogBoxParam, DialogBoxIndirect and DialogBoxIndirectParam as well as any of the ..Ex versions. Internally, these Win32 API functions are called by WinForms.

Abel
'old' - but these parts of Windows are even older
Tim Robinson
@Tim, that's correct :) I tried to find its origin, but it seems that the [oldest reference Microsoft uses is Windows 2000](http://msdn.microsoft.com/en-us/library/ms645452.aspx), no function, not even [`WinMain`](http://msdn.microsoft.com/en-us/library/ms633559.aspx), goes further back.
Abel
@Abel, that's a nice bit of history rewriting :). Presumably those versions numbers in MSDN are _min(Windows version supported by Microsoft, first Windows version function appeared in)_. I should check my Windows 3.0 edition of Petzold.
Tim Robinson
@Tim: haha, I wasn't serious, I just meant that Microsoft stopped keeping track of older Windows versions (probably part of their end-of-support program).
Abel
+1, this is accurate. Might want to mention that it also iterates the top-level windows owned by the same thread and disables them.
Hans Passant
@Hans P: thanks, I added your note to the solution. There are, actually, more subtleties involved when dealing with modal dialog boxes, that all in all require a chapter in a book ;-)
Abel