afxasert.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef _DEBUG // entire file
  12. #ifdef AFX_DBG1_SEG
  13. #pragma code_seg(AFX_DBG1_SEG)
  14. #endif
  15. // NOTE: in separate module so it can replaced if needed
  16. #ifdef _DEBUG
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. #ifdef _AFX_NO_DEBUG_CRT
  21. LONG afxAssertBusy = -1;
  22. LONG afxAssertReallyBusy = -1;
  23. BOOL (AFXAPI* afxAssertFailedLine)(LPCSTR, int);
  24. #endif
  25. BOOL AFXAPI AfxAssertFailedLine(LPCSTR lpszFileName, int nLine)
  26. {
  27. #ifndef _AFX_NO_DEBUG_CRT
  28. // we remove WM_QUIT because if it is in the queue then the message box
  29. // won't display
  30. MSG msg;
  31. BOOL bQuit = PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
  32. BOOL bResult = _CrtDbgReport(_CRT_ASSERT, lpszFileName, nLine, NULL, NULL);
  33. if (bQuit)
  34. PostQuitMessage(msg.wParam);
  35. return bResult;
  36. #else
  37. TCHAR szMessage[_MAX_PATH*2];
  38. // handle the (hopefully rare) case of AfxGetAllocState ASSERT
  39. if (InterlockedIncrement(&afxAssertReallyBusy) > 0)
  40. {
  41. // assume the debugger or auxiliary port
  42. wsprintf(szMessage, _T("Assertion Failed: File %hs, Line %d\n"),
  43. lpszFileName, nLine);
  44. OutputDebugString(szMessage);
  45. InterlockedDecrement(&afxAssertReallyBusy);
  46. // assert w/in assert (examine call stack to determine first one)
  47. AfxDebugBreak();
  48. return FALSE;
  49. }
  50. // check for special hook function (for testing diagnostics)
  51. _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
  52. InterlockedDecrement(&afxAssertReallyBusy);
  53. if (afxAssertFailedLine != NULL)
  54. return (*afxAssertFailedLine)(lpszFileName, nLine);
  55. // get app name or NULL if unknown (don't call assert)
  56. LPCTSTR lpszAppName = afxCurrentAppName;
  57. if (lpszAppName == NULL)
  58. lpszAppName = _T("<unknown application>");
  59. // format message into buffer
  60. wsprintf(szMessage, _T("%s: File %hs, Line %d"),
  61. lpszAppName, lpszFileName, nLine);
  62. if (afxTraceEnabled)
  63. {
  64. // assume the debugger or auxiliary port
  65. TCHAR szT[_MAX_PATH*2 + 20];
  66. wsprintf(szT, _T("Assertion Failed: %s\n"), szMessage);
  67. OutputDebugString(szT);
  68. }
  69. if (InterlockedIncrement(&afxAssertBusy) > 0)
  70. {
  71. InterlockedDecrement(&afxAssertBusy);
  72. // assert within assert (examine call stack to determine first one)
  73. AfxDebugBreak();
  74. return FALSE;
  75. }
  76. // active popup window for the current thread
  77. HWND hWndParent = GetActiveWindow();
  78. if (hWndParent != NULL)
  79. hWndParent = GetLastActivePopup(hWndParent);
  80. // we remove WM_QUIT because if it is in the queue then the message box
  81. // won't display
  82. MSG msg;
  83. BOOL bQuit = ::PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
  84. // display the assert
  85. int nCode = ::MessageBox(hWndParent, szMessage, _T("Assertion Failed!"),
  86. MB_TASKMODAL|MB_ICONHAND|MB_ABORTRETRYIGNORE|MB_SETFOREGROUND);
  87. if (bQuit)
  88. PostQuitMessage(msg.wParam);
  89. // cleanup
  90. InterlockedDecrement(&afxAssertBusy);
  91. if (nCode == IDIGNORE)
  92. return FALSE; // ignore
  93. if (nCode == IDRETRY)
  94. return TRUE; // will cause AfxDebugBreak
  95. AfxAbort(); // should not return (but otherwise AfxDebugBreak)
  96. return TRUE;
  97. #endif // _AFX_NO_DEBUG_CRT
  98. }
  99. #endif // _DEBUG