1
votes

I have a queer sort of problem. Consider the following scenario:

  • Main window creates a child dialog on click of some button.
  • Child dialog does some task in a worker thread.
  • An error occurs during that task causing a message box to be displayed saying something along the lines of "Yikes! Something went wrong.".
  • Child dialog's 'Cancel' button is clicked on causing the child dialog to be closed.
  • Message box is still active! Clicking on anything in the message box = crash.

Pseudocode of how things are happening: (please ignore syntactic correctness here)

MainWindowClass mainObj;

void MainWindowClass::OnSomeButtonClick()
{
    SomeDialogClass someDialogObj;
    someDialogObj.DoModal();
}

int MainWindowClass::doTask()
{
    // Do work
    if(ERROR)
    {
        MessageBox("Yikes! Something went wrong.", "Error", MB_OK);
        return ERROR;
    }
} 

///////////////////////////////////////////////////////////////////
// Meanwhile, in another file,

extern MainWindowClass mainObj;

void SomeDialogClass::OnCancel()
{
    // Do all cleanup and close dialog
}

int SomeDialogClass::workerThreadFunc()
{
    return mainObj.doTask();
}

int SomeDialogClass::DoModal()
{
    AfxBeginThread(workerThreadFunc);
    // Do all other work and then wait for the worker thread
}

My question is twofold:

  1. On cancel, is there a way to know if any message boxes/dialogs in the same application are active?
  2. Is my entire design wrong and should I be doing something else altogether?

I thought one of the main reasons to use a modal dialog was its ability to prevent focus from going to parent dialogs. Yet, when that error message box is shown, I can happily click on the dialog and then click on 'Cancel' and pretend that the error message box never showed.

2
I suspect that on Cancel things aren't being cleaned up properly, and therefore you get a crash.Tony The Lion
@TonyTheLion, The crash doesn't occur if I dismiss the error before clicking on 'Cancel'. The crash occurs because the IsWindow() assert fails for the message box.Anish Ramaswamy
so what is your question then?Tony The Lion
"On cancel, is there a way to know if any message boxes/dialogs in the same application are active?"Anish Ramaswamy
@TonyTheLion, I'm so sorry for shooting down your suggestion. I made some dumb assumptions. Should I post my results as answer/question/comment? Thanks for your comment btwAnish Ramaswamy

2 Answers

5
votes

Rather than have your worker thread bring up a modal message box, it should signal the error condition back to the UI thread. My experience of MFC and multi-threading is that having all UI handled in the same thread makes things much simpler and removes these types of error. Having two threads potentially bringing up modal dialogs at the same time is asking for trouble.

0
votes

I'm kind of new at this, but my suggestions would be if the child is going to be cancelled when there is an error then destroy it before launching the error.

As far as I can tell, the SomeDialogClass is modal, then the parent launches another modal dialog, the MessageBox. Now, if SomeDialogClass was modeless then the message box would appear on top since SomeDialogClass would then be a child of the entire desktop and the sole child of MainWindowClass would be the MessageBox.

I'm under the impression that modal only prevents focus from going to things underneath the modal dialog, not what is launched on top or after it is open. I've done a modal dialog, launched a modeless from it, and could move both around the screen just fine. Additionally, I created a WM_MESSAGE from the modeless dialog back to the modal to announce when it was done so the modeless could finish.