从模态对话框中抛出异常的最佳做法是什么?

时间:2012-03-13 04:34:01

标签: c++ exception atl

我有一个显示模型对话框并等待用户做某事的函数,但是,它很复杂并且可能出错了,在这种情况下会抛出异常。

以下是使用异常处理调用此函数的假定代码:

try {
    CMyDialog mydialog();
    mydialog.DoModal();
}
catch(std::logic_error &e){
    DoExceptionHandling();
}

对话框UI是用ATL编写的,让我们假设有一个按钮OnClick处理程序如下:

LRESULT CMyDialog::OnBnClickedBlah(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/){
    ...
    throw std::logic_error("BlahBlah");
}

然而,当运行上面的代码时,一旦抛出异常,在调试模式下我触发了一个ATL断言,声称该对话框的HWND应为空(但实际上它尚未清除)。

我想知道的是如何解决这个问题并允许调用者捕获异常,并确保所有资源都已正确释放?

2 个答案:

答案 0 :(得分:1)

一些建议:

我会尽量不跨越消息边界抛出异常,尤其是不同的模态消息循环。有几个介入层,即使它有效(在这种情况下似乎没有),它也在寻找麻烦。

我建议您在出错时使用EndDialog,并在对话框类本身中存储某种错误代码,调用者可以在对话框中检查“意外”结果代码(例如:IDCANCEL)。这样,对话框在出错时仍然“消失”,所有内容都可以正常清理,而且您不必担心确保一切都能正常处理非标准对话框错误。我的2c。

答案 1 :(得分:1)

致电EndDialog应该可以解决您的问题:

CMyDialog mydialog();
try {
    mydialog.DoModal();
}
catch(std::logic_error &e){
    mydialog.EndDialog(IDABORT);
    DoExceptionHandling();
}

是的,不建议跨模块边界传递异常。