home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / afxasert.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-16  |  3.5 KB  |  120 lines

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