简体   繁体   English

使用std :: runtime_error而不是CException

[英]Using std::runtime_error instead of CException

When I throw a CException in the main thread, it is neatly caught by the framework and a nice MessageBox shows the error text. 当我在主线程中抛出CException时,框架会很好地捕获它,并且一个不错的MessageBox会显示错误文本。 When I throw an std::runtime_error the application just crashes. 当我抛出std :: runtime_error时,应用程序崩溃了。 The problem is I don't see the text of the exception, and I have to spend time to figure out it's actually something I've 'thrown' instead of simply an access violation. 问题是我看不到异常的文字,我必须花时间弄清楚它实际上是我“抛出”的东西,而不仅仅是访问冲突。

So I'm wondering if there's a way to make std::exception be caught and its text displayed in a similar way as CException. 所以我想知道是否有一种方法可以捕获std :: exception并以类似于CException的方式显示其文本。

I'd like to be able to throw an std::runtime_error from any message handler without crashing my program, without wrapping every message handler in try...catch. 我希望能够从任何消息处理程序中引发std :: runtime_error而不会导致程序崩溃,而无需在try ... catch中包装每个消息处理程序。 This is already possible for CException, because there is a try...catch somewhere in the code for the event pump (I think it's CWinApp::Run - but I'm not sure). 对于CException,这已经是可能的,因为在事件泵的代码中有一个try ... catch(我认为是CWinApp :: Run-但我不确定)。

[Edit] I found the function that catches CExceptions, but I'm not sure if it's possible to override it. [编辑]我发现了捕获CExceptions的函数,但是我不确定是否可以覆盖它。 I've posted the code below. 我已经在下面发布了代码。 The TRY...CATCH_ALL...END_CATCH_ALL statements are catching the CExceptions. TRY ... CATCH_ALL ... END_CATCH_ALL语句正在捕获CException。

/////////////////////////////////////////////////////////////////////////////
// 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;
}

So I'm wondering if there's a way to make std::exception be caught and its text displayed in a similar way as CException. 所以我想知道是否有一种方法可以捕获std :: exception并以类似于CException的方式显示其文本。

Yes- by catching it, and displaying it's text via MessageBox. 是的-通过捕获它,并通过MessageBox显示它的文本。

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

There is, but you have to do it yourself. 有,但是您必须自己做。 :-) :-)

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

Somewhere within MFC's implementation of the main message loop it has a try/catch setup that gives the behavior you see when CException types are thrown. 在MFC的主消息循环实现中的某个地方,它具有try / catch设置,该设置提供了抛出CException类型时看到的行为。

You could wrap your own code in various try/catch statements to catch the exceptions, as already stated by others. 您可以将自己的代码包装在各种try / catch语句中,以捕获异常,正如其他人已经指出的那样。

It would also be possible to wrap MFC's message loop with a kind of "top level" handler to catch anything not caught otherwise. 也可以用一种“顶级”处理程序包装MFC的消息循环,以捕获其他未捕获的内容。 To do this, override CWinApp::Run in your derived application class, implement your desired try/catch, and call the base CWinApp::Run from within your try block. 为此,请在派生的应用程序类中重写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
    }
}

如果您有可以合理地继续执行的异常,则还可以替代CWinApp :: Run()或在CWinApp :: Run()之外重写CWinApp :: PumpMessage()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM