I have noticed a strange piece of behaviour when using MessageDlg and attempting to close my application via the Taskbar close all/group command.
My application is as follows:
- There is a hidden main form which doesn't do anything other than handle some Windows Messages and pass them onto the child windows (if necessary).
- Each child window has its parent set to the desktop (in order to get it displaying on the Taskbar).
- Each child has an OnClose event which pops up a MessageDlg to prompt the user whether they want to save their session (if any content has been modified in anyway)
The issue seems to be it will continually close any windows that haven't been modified, however, when it hits a window that has been, 1 of 2 things are happening intermittently:
- Regardless if I select "Yes/No" the Close All process seems to stop after that particular window is closed.
- The dialog is not displayed and mrCancel is the result. Again the close all process stops after this window is closed.
A change I made was to use the WinAPI MessageBox function in replace of MessageDlg and this did seem to resolve the issue. However, I would really like to know why MessageDlg is acting like this?
My initial thought was when the dialog is being launched in the middle of the Close All perhaps the OS is sending a WM_CLOSE message to the dialog as it is technically part of the group (this would explain the dialog not appearing and defaulting to mrCancel as this is the equivalent of pressing the X). However, that doesn't explain why after I dismiss the dialog the Close All process does not continue to close any other windows in the group!
Any thoughts/idea's on this?
Windows doesn't send
WM_CLOSE
messages to these windows, it postsWM_SYSCOMMAND
with theSC_CLOSE
request. This in turn leads to the sending ofWM_CLOSE
messages if the standard Windows message box is used. If theMessageDlg()
function is used instead, only the first postedWM_SYSCOMMAND
leads to aWM_CLOSE
, the others do not. It's hard to say for sure, but maybe this has something to do with theDisableTaskWindows()
andEnableTaskWindows()
calls that the VCL uses to "fake" modal dialogs. If you replace the Windows function withApplication.MessageBox()
, a wrapper that does useDisableTaskWindows()
andEnableTaskWindows()
, then it doesn't work either (which IMO supports this reasoning).