You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模态与无模态对话框中方法的异常处理适配方案咨询

解决方案:适配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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:35:33