Lorsque je lance une CException dans le thread principal, elle est attrapée par le framework et un message MessageBox affiche le texte de l'erreur. Quand je lance une erreur std :: runtime_error, l'application se bloque. Le problème est que je ne vois pas le texte de l'exception, et je dois passer du temps à comprendre que c'est quelque chose que j'ai 'lancé' au lieu d'une simple violation d'accès.Utilisation de std :: runtime_error au lieu de CException
Donc je me demande s'il y a un moyen de faire que std :: exception soit interceptée et que son texte soit affiché de la même manière que CException. J'aimerais pouvoir lancer std :: runtime_error à partir de n'importe quel gestionnaire de message sans écraser mon programme, sans encapsuler tous les gestionnaires de messages dans try ... catch. C'est déjà possible pour CException, parce qu'il y a un essai ... attrape quelque part dans le code pour la pompe d'événement (je pense que c'est CWinApp :: Run - mais je ne suis pas sûr).
[Éditer] J'ai trouvé la fonction qui attrape CExceptions, mais je ne suis pas sûr qu'il soit possible de le contourner. J'ai posté le code ci-dessous. Les instructions TRY ... CATCH_ALL ... END_CATCH_ALL capturent les 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;
}
Merci, j'ai trouvé quelle fonction attrape les CExceptions (c'est AfxCallWndProc), et j'ai édité ma question. Mais je ne suis pas sûr de pouvoir l'ignorer, car ce n'est pas vraiment une fonction virtuelle. CWinApp :: Run l'appelle, mais il est comme 20-30 entrées au-dessus dans la pile d'appels. – sashoalm