当我在主线程中抛出一个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;
}
答案 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()。