// This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1998 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #include "stdafx.h" #ifdef _DEBUG // entire file #ifdef AFX_DBG1_SEG #pragma code_seg(AFX_DBG1_SEG) #endif // NOTE: in separate module so it can replaced if needed #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #ifdef _AFX_NO_DEBUG_CRT LONG afxAssertBusy = -1; LONG afxAssertReallyBusy = -1; BOOL (AFXAPI* afxAssertFailedLine)(LPCSTR, int); #endif BOOL AFXAPI AfxAssertFailedLine(LPCSTR lpszFileName, int nLine) { #ifndef _AFX_NO_DEBUG_CRT // we remove WM_QUIT because if it is in the queue then the message box // won't display MSG msg; BOOL bQuit = PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); BOOL bResult = _CrtDbgReport(_CRT_ASSERT, lpszFileName, nLine, NULL, NULL); if (bQuit) PostQuitMessage(msg.wParam); return bResult; #else TCHAR szMessage[_MAX_PATH*2]; // handle the (hopefully rare) case of AfxGetAllocState ASSERT if (InterlockedIncrement(&afxAssertReallyBusy) > 0) { // assume the debugger or auxiliary port wsprintf(szMessage, _T("Assertion Failed: File %hs, Line %d\n"), lpszFileName, nLine); OutputDebugString(szMessage); InterlockedDecrement(&afxAssertReallyBusy); // assert w/in assert (examine call stack to determine first one) AfxDebugBreak(); return FALSE; } // check for special hook function (for testing diagnostics) _AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); InterlockedDecrement(&afxAssertReallyBusy); if (afxAssertFailedLine != NULL) return (*afxAssertFailedLine)(lpszFileName, nLine); // get app name or NULL if unknown (don't call assert) LPCTSTR lpszAppName = afxCurrentAppName; if (lpszAppName == NULL) lpszAppName = _T(""); // format message into buffer wsprintf(szMessage, _T("%s: File %hs, Line %d"), lpszAppName, lpszFileName, nLine); if (afxTraceEnabled) { // assume the debugger or auxiliary port TCHAR szT[_MAX_PATH*2 + 20]; wsprintf(szT, _T("Assertion Failed: %s\n"), szMessage); OutputDebugString(szT); } if (InterlockedIncrement(&afxAssertBusy) > 0) { InterlockedDecrement(&afxAssertBusy); // assert within assert (examine call stack to determine first one) AfxDebugBreak(); return FALSE; } // active popup window for the current thread HWND hWndParent = GetActiveWindow(); if (hWndParent != NULL) hWndParent = GetLastActivePopup(hWndParent); // we remove WM_QUIT because if it is in the queue then the message box // won't display MSG msg; BOOL bQuit = ::PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); // display the assert int nCode = ::MessageBox(hWndParent, szMessage, _T("Assertion Failed!"), MB_TASKMODAL|MB_ICONHAND|MB_ABORTRETRYIGNORE|MB_SETFOREGROUND); if (bQuit) PostQuitMessage(msg.wParam); // cleanup InterlockedDecrement(&afxAssertBusy); if (nCode == IDIGNORE) return FALSE; // ignore if (nCode == IDRETRY) return TRUE; // will cause AfxDebugBreak AfxAbort(); // should not return (but otherwise AfxDebugBreak) return TRUE; #endif // _AFX_NO_DEBUG_CRT } #endif // _DEBUG