【发布时间】:2011-07-15 23:50:35
【问题描述】:
当我在主线程中抛出一个 CException 时,它会被框架巧妙地捕获,并且一个漂亮的 MessageBox 会显示错误文本。当我抛出 std::runtime_error 时,应用程序就会崩溃。问题是我没有看到异常的文本,我必须花时间弄清楚它实际上是我“抛出”的东西,而不是简单的访问冲突。
所以我想知道是否有办法让 std::exception 被捕获并以与 CException 类似的方式显示其文本。
我希望能够从任何消息处理程序中抛出 std::runtime_error 而不会导致我的程序崩溃,也不需要将每个消息处理程序包装在 try...catch 中。这对于 CException 来说已经成为可能,因为在事件泵的代码中某处有一个 try...catch(我认为它是 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;
}
【问题讨论】: