简体   繁体   English

c ++,mfc-消息框显示,主窗口有一个取消按钮。 防止在消息框处于活动状态时取消

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

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.". 在该任务期间发生错误,导致显示消息框,提示“ Yikes!出问题了”。
  • 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. 但是,当显示该错误消息框时,我可以高兴地单击该对话框,然后单击“取消”,并假装该错误消息框从未显示。

Rather than have your worker thread bring up a modal message box, it should signal the error condition back to the UI thread. 与其让工作线程显示一个模式消息框,不应该将错误情况发回给UI线程。 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. 我对MFC和多线程的经验是,将所有UI处理在同一线程中会使事情变得更加简单,并消除了这些类型的错误。 Having two threads potentially bringing up modal dialogs at the same time is asking for trouble. 有两个线程可能同时打开模式对话框,这会带来麻烦。

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. 据我所知,SomeDialogClass是模态的,然后父级启动另一个模态对话框,即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. 现在,如果SomeDialogClass是无模式的,则消息框将显示在顶部,因为SomeDialogClass将是整个桌面的子级,而MainWindowClass的唯一子级是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. 另外,我从无模式对话框创建了WM_MESSAGE,返回模态以宣布完成时间,以便无模式可以完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM