Когда я добавляю CException в основной поток, он аккуратно перехватывается платформой, и красивый MessageBox показывает текст ошибки. Когда я выкидываю std :: runtime_error, приложение просто падает. Проблема в том, что я не вижу текст исключения, и мне приходится тратить время на то, чтобы понять, что на самом деле я что-то «выбросил», а не просто нарушение прав доступа.
Поэтому мне интересно, есть ли способ сделать так, чтобы std :: исключение было перехвачено и его текст отображался так же, как CException.
Я бы хотел иметь возможность генерировать std :: runtime_error из любого обработчика сообщений без сбоя моей программы, без включения каждого обработчика сообщений в try ... catch. Это уже возможно для CException, потому что есть попытка ... поймать где-нибудь в коде для насоса событий (я думаю, что это CWinApp :: Run - но я не уверен).
[Изменить]
Я нашел функцию, которая перехватывает CExceptions, но я не уверен, можно ли ее переопределить. Я разместил код ниже. Операторы TRY ... CATCH_ALL ... END_CATCH_ALL перехватывают исключения CEx.
/////////////////////////////////////////////////////////////////////////////
// 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;
}