Search code examples
winapicommfcmodal-dialog

How can a dialog become responsive while waiting for a call to DoModal() to return?


A button on a dialog causes a child dialog to be created, and displayed modally.

e.g:

void ParentDialog::OnButton()
{
 ChildDialog dlg;
 int ret = dlg.DoModal();
}

The parent dialog is initially unresponsive as expected. But, the child dialog also makes COM calls to a server module, which causes the server to make COM calls back to the parent dialog... to update displayed data, etc. In one case, this causes the parent dialog to suddenly become responsive again even though the child dialog is still on screen. Both dialogs can now be interacted with even though the parent dialog is still patiently waiting for OnButton()to return.

How can this happen? I'm trawling the code but is there anything specific I should be looking for?


Solution

  • The dialog has its own message pump/loop and inside the call it has a loop where it keeps receiving and dispatching window messages. This includes COM related messages worker windows receive and convert to COM callbacks you are seeing. Once the dialog is closed, respective windows are destroyed, the function exits from the loop and returns control to your code.

    That is, without returning control to your code immediately, window message dispatching still keeps working as usually and UI is responsive.

    MSDN:

    ... The function displays the dialog box, disables the owner window, and starts its own message loop to retrieve and dispatch messages for the dialog box.

    When the dialog box procedure calls the EndDialog function, DialogBox destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the nResult parameter specified by the dialog box procedure when it called EndDialog.