【发布时间】:2019-06-19 08:42:02
【问题描述】:
我有一个 MFC 对话框项目。主对话框中有一个下载按钮,点击它会提示一个进度条并开始下载。下载完成后,我希望它自动关闭。
void CProgressBarTest::DoDataExchange(CDataExchange* pDX)
{
static auto funDownload = [&]() {
m_downloadRetValue = ::SomeDownloadAPI(funDownloadCallback);
//When download finished, close the current dialog (progress bar). Here are two options:
//EndDialog(IDYES); // causes crash
//::PostMessage(this->GetSafeHwnd(), WM_CLOSE, 0, 0);// doesn't crash, but without return valud IDYES.
};
m_thDownload = std::thread(funDownload);
}
这里有两种关闭进度条的方法:
EndDialog(IDYES):它会导致崩溃。
::PostMessage(this->GetSafeHwnd(), WM_CLOSE, 0, 0):它可以关闭窗口而不崩溃,但也没有返回值(IDYES)。
我想在外面做这样的检查,
void CGUIThreadTestDlg::OnBnClickedButton3()
{
CProgressBarTest dlg(this);
INT_PTR nRet = dlg.DoModal();
switch (nRet)
{
case -1:
AfxMessageBox(_T("Dialog box could not be created!"));
break;
case IDYES:
AfxMessageBox(_T("Yes!"));
break;
case IDOK:
// Do something
break;
case IDCANCEL:
AfxMessageBox(_T("IDCANCEL!"));
break;
default:
// Do something
break;
}
}
【问题讨论】:
-
您以这种方式创建的两个对话框都属于主 (UI) 线程。
EndDialog()必须从“对话过程”中调用,这也在主线程中运行。所以问题似乎是你从下载线程调用EndDialog()。一个简单的解决方法(并且 imo 技术上正确)可能是在下载完成或失败时从下载线程向对话框窗口发布自定义消息(例如WM_APP + nn)。响应此消息,您可以使用所需的返回值调用EndDialog()。
标签: c++ multithreading mfc