我有一个显示模型对话框并等待用户做某事的函数,但是,它很复杂并且可能出错了,在这种情况下会抛出异常。
以下是使用异常处理调用此函数的假定代码:
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应为空(但实际上它尚未清除)。
我想知道的是如何解决这个问题并允许调用者捕获异常,并确保所有资源都已正确释放?
答案 0 :(得分:1)
一些建议:
我会尽量不跨越消息边界抛出异常,尤其是不同的模态消息循环。有几个介入层,即使它有效(在这种情况下似乎没有),它也在寻找麻烦。
我建议您在出错时使用EndDialog,并在对话框类本身中存储某种错误代码,调用者可以在对话框中检查“意外”结果代码(例如:IDCANCEL)。这样,对话框在出错时仍然“消失”,所有内容都可以正常清理,而且您不必担心确保一切都能正常处理非标准对话框错误。我的2c。
答案 1 :(得分:1)
致电EndDialog
应该可以解决您的问题:
CMyDialog mydialog();
try {
mydialog.DoModal();
}
catch(std::logic_error &e){
mydialog.EndDialog(IDABORT);
DoExceptionHandling();
}
是的,不建议跨模块边界传递异常。