对assert的改进

第一个宏显示用户定义的信息,并退出。第二个通过dwErrorCode来检索系统错误信息,可以是HRESULT,可以是DWORD,如果这个值为0,则通过GetLastError来获取错误码。

#ifdef _DEBUG
#define DebugAssertFailed(_Msg)				debug_assert_failed_impl((__FILE__), __LINE__, _Msg)
#define DebugFailedWithSysError(_ErrorCode)	debug_failed_with_sys_error_impl(_ErrorCode, __FILE__, __LINE__, __FUNCTION__)
#else
#define DebugAssertFailed(_Msg)				(void)0
#define DebugFailedWithSysError(_ErrorCode)	(void)0
#endif	//! _DEBUG

static void debug_assert_failed_impl(LPSTR strFileName, UINT nLineNumber, LPSTR strErrorMsg)
{
	//User defined error message.
	CStringA str;
	str.Format("Fatal error(file: %s, line: %d): %s!", strFileName, nLineNumber, strErrorMsg);
	MessageBoxA(NULL, str, "Caption", MB_ICONERROR);
	ExitProcess(-1);
}

static void debug_failed_with_sys_error_impl(DWORD dwErrorCode, LPSTR strFileName, UINT nLineNumber, LPSTR strFunctionName)
{
	//Use system error message.dwErrorCode could be HRESULT, if it's 0, try GetLastError() to retrieve the error code.
	LPVOID lpMsgBuf;
	LPVOID lpDisplayBuf;
	if(dwErrorCode == 0)
	{
		dwErrorCode = GetLastError();
	}
	if(dwErrorCode != 0)
	{
		FormatMessageA(
				FORMAT_MESSAGE_ALLOCATE_BUFFER | 
				FORMAT_MESSAGE_FROM_SYSTEM |
				FORMAT_MESSAGE_IGNORE_INSERTS,
				NULL,
				dwErrorCode,
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
				(LPSTR)&lpMsgBuf,
				0, NULL
			);

		lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
			sizeof(CHAR) * (strlen((LPSTR)lpMsgBuf) + strlen(strFunctionName) + 512));

		StringCchPrintfA((LPSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), "%s(file: %s, line: %d) failed with error %d: %s",
			strFunctionName, strFileName, nLineNumber, dwErrorCode, lpMsgBuf);

		MessageBoxA(NULL, (LPSTR)lpDisplayBuf, "error", MB_ICONERROR);
		LocalFree(lpMsgBuf);
		LocalFree(lpDisplayBuf);
		ExitProcess(dwErrorCode);
	}
}

 

 

 

  

 

posted @ 2012-09-04 10:13  Gallagher  阅读(155)  评论(0)    收藏  举报