模态与无模态对话框中方法的异常处理适配方案咨询
解决方案:适配CDialog1的两种运行模式错误处理
问题背景
CDialog1的Method()方法在模态对话框实例中调用时,异常触发的错误提示能正常显示;但当CDialog1作为隐藏无模态对话框被CDialog2的SomeTask()调用时,错误提示会导致隐藏的对话框意外弹出,不符合需求——此时需要由CDialog2负责错误显示。已知CDialog1提供IsHiddenMode()方法判断当前运行模式。
方案一:返回错误信息,由调用方按需处理
修改CDialog1的Method()
调整方法签名,增加错误信息输出参数,根据运行模式决定是自行处理错误还是将信息传递给调用方:
bool CDialog1::Method(CString* pOutErrorMsg /*= nullptr*/) { try { // 原业务逻辑代码 return true; // 执行成功返回true } catch (CException* e_) { const gsl::not_null<CException*> e{ e_ }; CString errorMsg; e->GetErrorMessage(errorMsg.GetBufferSetLength(MAX_PATH), MAX_PATH); e->Delete(); if (IsHiddenMode()) { // 无模态隐藏模式:将错误信息传递给调用方 if (pOutErrorMsg != nullptr) { *pOutErrorMsg = errorMsg; } return false; } else { // 模态模式:自行显示错误弹窗 AfxMessageBox(errorMsg, MB_OK | MB_ICONERROR); return false; } } catch (const _com_error& e) { CString errorMsg(e.ErrorMessage()); if (IsHiddenMode()) { if (pOutErrorMsg != nullptr) { *pOutErrorMsg = errorMsg; } return false; } else { AfxMessageBox(errorMsg, MB_OK | MB_ICONERROR); return false; } } }
修改CDialog2的SomeTask()
调用Method()时接收错误信息,自行处理显示:
void CDialog2::SomeTask() { if (m_pDialog1 != nullptr) { CString errorMsg; if (!m_pDialog1->Method(&errorMsg)) { // CDialog2负责错误提示 AfxMessageBox(errorMsg, MB_OK | MB_ICONERROR); } } }
方案二:使用自定义错误处理回调(更灵活)
通过传入回调函数,让调用方决定错误处理逻辑,适配更多场景:
修改CDialog1的代码
先定义回调类型,再调整Method()并提取错误处理逻辑:
// 头文件中定义错误处理回调类型 using ErrorHandler = std::function<void(const CString&)>; // Method方法实现 void CDialog1::Method(ErrorHandler customErrorHandler /*= nullptr*/) { try { // 原业务逻辑代码 } catch (CException* e_) { const gsl::not_null<CException*> e{ e_ }; CString errorMsg; e->GetErrorMessage(errorMsg.GetBufferSetLength(MAX_PATH), MAX_PATH); e->Delete(); HandleError(errorMsg, customErrorHandler); } catch (const _com_error& e) { CString errorMsg(e.ErrorMessage()); HandleError(errorMsg, customErrorHandler); } } // 私有方法:统一处理错误逻辑 void CDialog1::HandleError(const CString& errorMsg, ErrorHandler customHandler) { if (IsHiddenMode() && customHandler != nullptr) { // 无模态隐藏模式:使用调用方传入的处理逻辑 customHandler(errorMsg); } else { // 模态模式或无自定义处理:默认弹窗显示 AfxMessageBox(errorMsg, MB_OK | MB_ICONERROR); } }
修改CDialog2的SomeTask()
调用时传入自定义错误处理逻辑:
void CDialog2::SomeTask() { if (m_pDialog1 != nullptr) { m_pDialog1->Method([this](const CString& errorMsg) { // 自定义错误处理:这里示例为弹窗,也可加入日志等逻辑 AfxMessageBox(errorMsg, MB_OK | MB_ICONERROR); }); } }
方案对比
- 方案一:实现简单,适合仅需要传递错误信息的场景,侵入性低。
- 方案二:灵活性更高,支持调用方自定义错误处理(如写入日志、弹窗+日志等组合操作),适合复杂业务场景。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

