使用std :: runtime_error而不是CException

时间:2011-03-15 17:27:54

标签: c++ exception mfc

当我在主线程中抛出一个CException时,它被框架巧妙地捕获,一个漂亮的MessageBox显示错误文本。当我抛出一个std :: runtime_error时,应用程序就崩溃了。问题是我没有看到异常的文本,我必须花时间弄清楚它实际上是我“抛出”而不仅仅是访问冲突。

所以我想知道是否有办法让std :: exception被捕获,其文本显示方式与CException类似。

我希望能够从任何消息处理程序中抛出一个std :: runtime_error,而不会崩溃我的程序,而不会在try ... catch中包装每个消息处理程序。这对于CException来说已经是可能的了,因为有一个尝试...捕获事件泵的代码中的某个地方(我认为它是CWinApp :: Run - 但我不确定)。

[编辑] 我找到了捕获CExceptions的函数,但我不确定是否可以覆盖它。我已经发布了以下代码。 TRY ... CATCH_ALL ... END_CATCH_ALL语句正在捕获CExceptions。

/////////////////////////////////////////////////////////////////////////////
// Official way to send message to a CWnd

LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg,
    WPARAM wParam = 0, LPARAM lParam = 0)
{
    _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
    MSG oldState = pThreadState->m_lastSentMsg;   // save for nesting
    pThreadState->m_lastSentMsg.hwnd = hWnd;
    pThreadState->m_lastSentMsg.message = nMsg;
    pThreadState->m_lastSentMsg.wParam = wParam;
    pThreadState->m_lastSentMsg.lParam = lParam;

#ifdef _DEBUG
    _AfxTraceMsg(_T("WndProc"), &pThreadState->m_lastSentMsg);
#endif

    // Catch exceptions thrown outside the scope of a callback
    // in debug builds and warn the user.
    LRESULT lResult;
    TRY
    {
#ifndef _AFX_NO_OCC_SUPPORT
        // special case for WM_DESTROY
        if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL))
            pWnd->m_pCtrlCont->OnUIActivate(NULL);              
#endif

        // special case for WM_INITDIALOG
        CRect rectOld;
        DWORD dwStyle = 0;
        if (nMsg == WM_INITDIALOG)
            _AfxPreInitDialog(pWnd, &rectOld, &dwStyle);

        // delegate to object's WindowProc
        lResult = pWnd->WindowProc(nMsg, wParam, lParam);

        // more special case for WM_INITDIALOG
        if (nMsg == WM_INITDIALOG)
            _AfxPostInitDialog(pWnd, rectOld, dwStyle);
    }
    CATCH_ALL(e)
    {
        lResult = AfxProcessWndProcException(e, &pThreadState->m_lastSentMsg);
        TRACE(traceAppMsg, 0, "Warning: Uncaught exception in WindowProc (returning %ld).\n",
            lResult);
        DELETE_EXCEPTION(e);
    }
    END_CATCH_ALL

    pThreadState->m_lastSentMsg = oldState;
    return lResult;
}

4 个答案:

答案 0 :(得分:4)

  

所以我想知道是否有办法   make std :: exception被抓住了   文本以类似的方式显示   了CException。

是的 - 通过捕获它,并通过MessageBox显示它的文本。

int main() {
    try {
        //....
    }
    catch(const std::exception& except) {
        MessageBox(NULL, except.what(), "OMGWTF FATAL ERROR", MB_OK);
    }
}

答案 1 :(得分:2)

有,但你必须自己做。 : - )

int main()
{
    try
    {
        SomeFunction();
    }
    catch (const std::exception & ex)
    {
        ::MessageBox(0, ex.what(), 0, 0);
    }
}

答案 2 :(得分:1)

在MFC主要消息循环的实现中,它有一个try / catch设置,它提供了在抛出CException类型时看到的行为。

您可以将自己的代码包装在各种try / catch语句中以捕获异常,正如其他人已经说过的那样。

还可以使用一种“顶级”处理程序来包装MFC的消息循环,以捕获未捕获的任何内容。要执行此操作,请在派生的应用程序类中覆盖CWinApp::Run,实现所需的try / catch,并从try块中调用基础CWinApp::Run

int CMyApp::Run()
{
    try
    {
        return CWinApp::Run();
    }
    catch(const std::exception& ex)
    {
        MessageBox(NULL, ex.what(), "Error", MB_OK | MB_ICONERROR);
        return 1;  // or some appropriate code
    }
}

答案 3 :(得分:0)

如果您有可能合理地继续的异常,您也可以覆盖CWinApp :: PumpMessage()而不是CWinApp :: Run()。