log.cpp

来自「◆◆◆ 《投掷飞镖记分工具》◆◆◆ 操作系统 : Windows Mobil」· C++ 代码 · 共 256 行

CPP
256
字号
#include "StdAfx.h"
#include "PublicFunc.h"
#include "Log.h"
#include <Afxmt.h>

TCHAR					*g_lpCurDir = NULL;
TCHAR					*g_szLogFilePrefix = NULL;
HWND					g_hWnd_RecvLogMsg = NULL;
CStringArray			m_StrAry_LastLogText;
CUIntArray				m_UIntAry_LastLogLevel;
::CCriticalSection		m_CSFor_StrAry_LastLog;

//
// 得到翻译文本
//
CString GetMLTextPub ( LPCTSTR lpszEnglishText, ... )
{
	TCHAR szTransString[1024] = {0};

	va_list  va;
	va_start ( va, lpszEnglishText );
	_vsnprintf_hw ( szTransString, sizeof(szTransString) - 1, lpszEnglishText, va);
	va_end(va);

	return szTransString;
}

// 日志级别
const TCHAR *g_szLogLevelString[] = 
{
	_T("VERBOSE"),_T("NORMAL"),_T("WARNING"),_T("ERROR"),_T("DEBUG"),_T("INVALID"),
};
const UINT g_nMsgBoxType[] =
{
	MB_ICONINFORMATION, MB_ICONINFORMATION, MB_ICONWARNING, MB_ICONERROR, MB_ICONERROR, 0,
};
const UINT g_nMsgTextColor[] =
{
	RGB(64,64,64), RGB(0,0,128), RGB(128,0,0), RGB(255,0,0), RGB(255,0,0), RGB(0,0,0),
};

//
// 确保日志文件
//
void ValidateLogFile ( LPCTSTR lpszLogFileName )
{
	ASSERT ( lpszLogFileName );
	if ( hwGetFileAttr ( lpszLogFileName ) > LOGFILE_MAX_SIZE )
		DeleteFile ( lpszLogFileName );
}

//
// 获取日志文件名
//
CString GetLogFileName ()
{
	CString csLogFileName = GenerateDateFileName ( g_lpCurDir, g_szLogFilePrefix, _T("txt") );
	return csLogFileName;
}

//
// 保存日志文件
//
BOOL SaveLogInfoToFile ( LPCTSTR lpszLogBuf, int nBytes )
{
#ifndef _DEBUG
	if ( !g_lpCurDir || lstrlen(g_lpCurDir) < 1 )
		return FALSE;
	if ( !g_szLogFilePrefix || lstrlen(g_szLogFilePrefix) < 1 )
		return FALSE;
#endif
	ASSERT ( lpszLogBuf );
	CString csLogFileName = GetLogFileName ();
	ValidateLogFile ( csLogFileName );
	return ( WriteDataToFile ( csLogFileName, (char*)lpszLogBuf, nBytes, _T("ab+") ) == nBytes );
}

//
// 输出日志信息的函数
//
void Log ( UINT nLevel, LPCTSTR format, ...)
{
	TCHAR LogBuf[MAX_LOGBUF_SIZE] = {0};
	int nLen = 0;
	// 获取当前时间
	nLen += hwSnprintf ( LogBuf+nLen, MAX_LOGBUF_SIZE-nLen-3, _T("[") );
	nLen += GetCurTimeString ( LogBuf+nLen );
	nLen += hwSnprintf ( LogBuf+nLen, MAX_LOGBUF_SIZE-nLen-3, _T("] ") );

	// 日志级别
	int nLogLevel = (nLevel & 0xf);
	ASSERT ( nLogLevel >= L_VERBOSE && nLogLevel < L_LOGNUM );
	nLen += hwSnprintf ( LogBuf+nLen, MAX_LOGBUF_SIZE-nLen-3, _T("<%s> "),
		GetMLTextPub(g_szLogLevelString[nLogLevel]) );
#ifdef _DEBUG
	if ( nLogLevel == L_ERROR )
	{
		TRACE ( _T("ERROR\n") );
	}
#endif
	// 格式化日志信息
	va_list  va;
	va_start (va, format);
	int nRet = _vsnprintf_hw ( LogBuf+nLen, MAX_LOGBUF_SIZE-nLen-3, format, va);
	va_end(va);
	int nLogInfoPos = nLen;
	if ( nRet > 0 ) nLen += nRet;
	else nLen = (int)lstrlen(LogBuf);

	// 添加回车换行符
	strncat_hw ( LogBuf, _T("\r\n"), LENGTH(LogBuf) );
	nLen += 2;

	// 保存日志到文件
	SaveLogInfoToFile ( LogBuf, nLen*sizeof(TCHAR) );

	// 显示日志信息
	if ( !(nLevel&L_ONLY_LOGFILE) )
	{
		if ( !::IsWindow(g_hWnd_RecvLogMsg) || (nLevel&L_OUT_DLG) )
		{
			ASSERT ( nLogInfoPos > 2 );
			LogBuf[nLen-2] = _T('\0');
			if ( nLogLevel == L_WARNING || nLogLevel == L_ERROR || (nLevel&L_OUT_DLG) )
			{
				hwMsgBox ( NULL, NULL, g_nMsgBoxType[nLogLevel], LogBuf+nLogInfoPos );
			}
		}
		else
		{
			m_CSFor_StrAry_LastLog.Lock ();
			m_StrAry_LastLogText.Add ( LogBuf );
			m_UIntAry_LastLogLevel.Add ( nLevel );
			m_CSFor_StrAry_LastLog.Unlock ();
			if ( nLevel&L_BALLOON )
				::SendMessage ( g_hWnd_RecvLogMsg, WM_SHOWLOG, WPARAM(nLevel), LPARAM(NULL) );
			else
				::PostMessage ( g_hWnd_RecvLogMsg, WM_SHOWLOG, WPARAM(nLevel), LPARAM(NULL) );
		}
	}

#ifdef _DEBUG
	if ( nLevel&L_TRACE )
	{
		int nPartLength = 16;
		CString csLogBuf = LogBuf;
		while ( !csLogBuf.IsEmpty() )
		{
			nPartLength = MIN ( csLogBuf.GetLength(), nPartLength );
			CString csOnePart = csLogBuf.Left (nPartLength);
			TRACE ( _T("%s"), csOnePart );
			csLogBuf = csLogBuf.Mid ( nPartLength );
		}
	}
#endif
}

int hwMsgBox (
		HWND hWnd,
		LPCTSTR lpCaption, 
		UINT uType,
		LPCTSTR lpText,
		...
	)
{
	ASSERT ( lpText );
	TCHAR szText[255] = {0};
	// 格式化日志信息
	va_list  va;
	va_start (va, lpText);
	_vsnprintf_hw ( szText, sizeof(szText)-1, lpText, va);
	va_end(va);

	return ::MessageBox ( hWnd, szText, lpCaption?lpCaption:AfxGetAppName(), uType );
}

void GetLastLogStrAry ( CStringArray *pStrAry, CUIntArray *pUIntAry )
{
	if ( !pStrAry || !pUIntAry ) return;

	m_CSFor_StrAry_LastLog.Lock ();
	pStrAry->Append ( m_StrAry_LastLogText );
	pUIntAry->Append ( m_UIntAry_LastLogLevel );
	m_StrAry_LastLogText.RemoveAll ();
	m_UIntAry_LastLogLevel.RemoveAll ();
	m_CSFor_StrAry_LastLog.Unlock ();
}

void AddLogTextToEditCtrl (
#ifdef WINCE
		CEdit *pEditLog,
#else
		CRichEditCtrl *pEditLog,
#endif
		LPCTSTR lpszLogText,
		int nLevel
	)
{
	int nLogLevel = (nLevel & 0xf);
	ASSERT ( nLogLevel >= 0 && nLogLevel < LENGTH(g_nMsgTextColor) );
	ASSERT ( lpszLogText );
	if ( !pEditLog || !::IsWindow ( pEditLog->m_hWnd ) )
		return;
	CString csLog;
	pEditLog->GetWindowText ( csLog );
	int nTextLen_Org = csLog.GetLength ();
	CString csAddText = lpszLogText;
	if ( ::IsWindow ( pEditLog->m_hWnd ) )
	{
		if ( nTextLen_Org < EDIT_MAX_TEXT )
		{
			pEditLog->SetSel ( nTextLen_Org, -1 );
		}
		else
		{
			pEditLog->SetSel ( 0, -1 );
			nTextLen_Org = 0;
		}
		pEditLog->ReplaceSel( csAddText );
		pEditLog->SetSel ( nTextLen_Org, nTextLen_Org+csAddText.GetLength() );

#ifndef WINCE
		// 设置文本颜色
		CHARFORMAT cf;
		pEditLog->GetSelectionCharFormat(cf);
		if (cf.dwEffects & CFE_AUTOCOLOR)
			cf.dwEffects -= CFE_AUTOCOLOR;
		cf.crTextColor = g_nMsgTextColor[nLogLevel];
		cf.dwMask = CFM_COLOR;	
		pEditLog->SetSelectionCharFormat(cf);
		pEditLog->HideSelection(TRUE, FALSE);
		pEditLog->SetSel ( -1, -1 );
#endif
		// 滚动在最底行
		pEditLog->SendMessage ( WM_VSCROLL, (WPARAM)SB_BOTTOM, (LPARAM)NULL );
	}
}

void MsgBoxErr ( LPCTSTR lpszErrorMsg, ... )
{
	ASSERT ( lpszErrorMsg );
	TCHAR szErrorMsg[256] = {0};
	va_list  va;
	va_start (va, lpszErrorMsg);
#ifdef UNICODE
	_vsnwprintf( szErrorMsg,LENGTH(szErrorMsg)-sizeof(TCHAR), (const wchar_t*)lpszErrorMsg, va);
#else
	_vsnprintf_hw (szErrorMsg,LENGTH(szErrorMsg)-sizeof(TCHAR), (const char*)lpszErrorMsg, va);
#endif
	va_end(va);

	CString csMsg;
	csMsg.Format ( _T("%s\r\nError NO : %d"), szErrorMsg, GetLastError() );
	AfxMessageBox ( csMsg );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?