MFC -消息框显示,主窗口有一个取消按钮.消息框处于活动状态时防止取消

c++, mfc - messagebox display, main window has a cancel button. prevent cancel while messagebox is active

本文关键字:消息 取消 活动状态 按钮 有一个 显示 窗口 MFC      更新时间:2023-10-16

我有一个奇怪的问题。考虑以下场景:

  • 主窗口在点击某个按钮时创建子对话框。
  • 子对话框在工作线程中执行一些任务。
  • 在该任务期间发生错误,导致显示一个消息框,上面写着"哎呀!出问题了".
  • 子对话框的"取消"按钮被点击导致子对话框被关闭。
  • 消息框仍处于激活状态!点击消息框中的任何东西=崩溃。

事情如何发生的伪代码:(请忽略这里的语法正确性)

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
}

我的问题是双重的:

  1. 在取消,有没有办法知道是否有消息框/对话框在相同的应用程序是活动的吗?
  2. 我的整个设计是错误的,我应该做其他事情吗?

我认为使用模态对话框的主要原因之一是它能够防止焦点转移到父对话框。然而,当显示错误消息框时,我可以愉快地单击对话框,然后单击"取消"并假装错误消息框从未显示。

与其让你的工作线程弹出一个模态消息框,它应该把错误情况返回给UI线程。我对MFC和多线程的经验是,在同一个线程中处理所有UI使事情变得更简单,并消除了这些类型的错误。有两个线程可能同时出现模态对话框,这是自找麻烦。

我是一种新的,但我的建议是,如果孩子是要取消时,有一个错误,然后在启动错误之前销毁它。

据我所知,SomeDialogClass是模态的,然后父类启动另一个模态对话框,MessageBox。现在,如果SomeDialogClass是非模态的,那么消息框将出现在顶部,因为SomeDialogClass将是整个桌面的子类,MainWindowClass的唯一子类将是MessageBox。

我的印象是,模态只会阻止焦点转到模态对话框下面的东西,而不是在顶部或打开后启动的东西。我做了一个模态对话框,从它启动了一个非模态对话框,并且可以在屏幕上很好地移动这两个对话框。此外,我创建了一个WM_MESSAGE从非模态对话框返回到模态,以宣布何时完成,以便非模态可以完成。