[quoted text, click to view] > I don't understand this: When I click the X, WM_CLOSE is sent. This is true
> for modeless and modal Forms (I checked it by overriding WndProc). WM_CLOSE
> should close the window (DestroyWindow). This happens when calling
> Application.DoEvents. After calling DoEvents, the handle should have been
> destroyed. Why is there a difference between modeless and modal forms?
Yes, WM_CLOSE is sent. However, AFAIK, if the form is modal, then
WM_CLOSE sets ModalResult instead of immediately destroying the window
handle.
[quoted text, click to view] > Application.Run is a message loop just like ShowDialog, so I don't see the
> difference.
Well, I'm not totally sure. But keep in mind that Application.Run has
totally arbitrary exit conditions, which aren't even specified by the
Application class -- IIRC, it keeps looping until someone (usually the
ApplicationContext) calls ThreadTerminate.
Form.ShowDialog has very specific exit conditions: it exits when the
form's DialogResult changes to something other than DialogResult.None.
It's actually not that simple -- the code is a tangled maze about six
methods deep -- so there may be other factors.
So there's not necessarily an automatic reason why Application.Run
should behave the same as Form.ShowDialog. Yes, it might be nice if
they were similar, but I suspect there are a lot of details in the way.
[quoted text, click to view] > Why does ShowDialog interpret WM_CLOSE and destroys the window? I thought
> it's the window procedure that catches wm_close and destroys itself, and the
> window procedure is the same in modal and modeless forms.
You're asking for a little more depth of knowledge than I've got, but
I'll hazard some guesses. First, I don't think ShowDialog processes
WM_CLOSE; I think the Form processes WM_CLOSE, but uses it to set
DialogResult instead of destroying its window handle immediately. (I
haven't confirmed this, but the code that's invoked as a result of
ShowDialog is a real mess, and aside from your questions I haven't had
any reasons to dive too far into it.)
A non-modal form *has* to destroy its own window handle, because there's
nobody else to clean up after it. A modal form *can* wait for someone
else (ShowDialog) to clean up after it, but exactly why they chose to
make it work that way, I'm not sure. I do have some guesses. In
particular, ShowDialog sets up some application state (disabling all
other forms) -- and if resetting that state is non-trivial, it would
make more sense for ShowDialog to do it. ShowDialog probably has local
variables that store various bits of initial state, and it's cleaner to
have ShowDialog restore that state than to somehow pass it into the
Form. And it's plausible enough that some of that state-restoration
could require the form's window handle still exist at the time.
But bottom line, I'm not sure. I guess I haven't had any reason to
worry about it too much yet. <grin> If you don't have Lutz Roeder's
Reflector yet, download it and take a look at the ShowDialog code.