#pragma once /* * ÈÕÖ¾¼Ç¼ʵÏÖÍ·Îļþ * Version: 1.03 * Date 2015-07-02 * Description: * 2015-07-02 ÐÞ¸ÄÁËÓë¼Ç¼´°¿ÚµÄ°ó¶¨·½Ê½ * Ôö¼ÓÁ˶¨Ê±Ë¢ÐµĹ¦ÄÜ * 2015-07-03 Ôö¼ÓÁËdettachwnd * ½«»¥³âÁ¿¸ÄΪÁÙ½çÇø * 2015-08-31 ¶¨Ê±Ë¢ÐÂÉý¼¶¸üÐÂ; */ #include #define MAXLOGFILE 10 class Logger { public: BOOL bShowThreadId; BOOL bShowLineCount; //ÏÔʾÐкŠBOOL bShowChannel; //ÏÔʾͨµÀ BOOL bShowDate; //ÏÔʾÈÕÆÚ BOOL bShowTime; //ÏÔʾʱ¼ä BOOL bOneFilePerHour; //°´Ð¡Ê±·ÖÀà BOOL bAutoAppendRN; //×Ô¶¯ÔÚÿÐкó¼ÓÈë»Ø³µ»»ÐÐ BOOL bPauseUpdate; //ÔÝÍ£¸üРBOOL bNoScroll; //ÔÝÍ£¹ö¶¯ CEdit m_LogWnd; CEdit * m_pLogWnd; CRichEditCtrl m_RichLogWnd; CRichEditCtrl *m_pRichLogWnd; int IsLogWndAttached; int AttachedType; //·½Ê½£¬0£¬ËÉ£»1£¬½ô CString LogPath; CString LogFilePrefix; int UsedChannelCount; CString ChannelPrefix[MAXLOGFILE]; double MyStartTime; int bShowLog[MAXLOGFILE]; int bSaveLog[MAXLOGFILE]; int LineCount[MAXLOGFILE]; //µ±Ç°ÐкŠint LogTextLength[MAXLOGFILE]; int bLogChanged[MAXLOGFILE]; CString strChangedLog[MAXLOGFILE]; CString strDisplayedLog[MAXLOGFILE]; CFile CLogFiles[MAXLOGFILE]; //·ÖÏîÈÕÖ¾Îļþ int LogFilesOpened[MAXLOGFILE]; //·ÖÏîÈÕÖ¾ÎļþÊÇ·ñÒѾ­´ò¿ª CCriticalSection myCriticalSection2; public: static int RelPathToAbsPath(CString BasePath1,CString RelPath2, CString &AbsPath) //Ïà¶Ô·¾¶×ª»»Îª¾ø¶Ô·¾¶ { AbsPath=BasePath1+_T("\\")+RelPath2; AbsPath.Replace(_T("/"),_T("\\")); return true; } static int IsAbspath(CString & sPath) { if (sPath.Find(_T(":")) == 1) { return 1;} if (sPath.Find(_T("\\")) == 0){ return 2;} if (sPath.Find(_T("/")) == 0) { return 4;} return false; } int GetDateStr(CString & DateStr) { CTime time1=CTime::GetTickCount(); DateStr.Format(_T("%04d-%02d-%02d"),time1.GetYear(),time1.GetMonth(),time1.GetDay()); return 0; } int GetTimeStr(CString & TimeStr) { SYSTEMTIME st; GetLocalTime(&st); TimeStr.Format(_T("%2d:%02d:%02d.%03d"), st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); return 0; } Logger() { bShowThreadId=0; bShowLineCount=0; bShowChannel = 0; bShowDate = 0; bShowTime=1; bAutoAppendRN=TRUE; bPauseUpdate=FALSE; bNoScroll=FALSE; bOneFilePerHour=0; LogPath=_T(".\\Log"); LogFilePrefix=_T("DefaultLog"); IsLogWndAttached=0; m_pLogWnd=NULL; m_pRichLogWnd=NULL; MyStartTime=GetTickTime(); UsedChannelCount = 1; for (int i=0;i------- ===== \r\n"),i); CLogFiles[i].Close(); } } } public: int SetLogPathName(CString Path,CString FileName) { LogPath=Path; LogFilePrefix=FileName; for (int i=0;iModifyStyle(ES_AUTOHSCROLL|WS_HSCROLL, ES_MULTILINE | ES_AUTOVSCROLL |WS_VSCROLL| ES_SELECTIONBAR | ES_WANTRETURN); m_pLogWnd->Invalidate(); m_pLogWnd->SetLimitText(10485760); IsLogWndAttached=1; }else if (s1.Find(_T("RichEdit"))==0) { if (pCWnd!=NULL) { m_pRichLogWnd=(CRichEditCtrl *)pCWnd; AttachedType=0; } else { ASSERT(CWnd::FromHandlePermanent(hWnd) == NULL); if (hWnd == NULL) return FALSE; m_RichLogWnd.Attach(hWnd); m_pRichLogWnd=&m_RichLogWnd; AttachedType=1; } m_pRichLogWnd->ModifyStyle(NULL,ES_MULTILINE|ES_AUTOVSCROLL|ES_SELECTIONBAR|ES_WANTRETURN); m_pRichLogWnd->Invalidate(); IsLogWndAttached=2; } return true; } int Dettach() { if (IsLogWndAttached==1) { IsLogWndAttached=0; if (AttachedType==1) { m_LogWnd.Detach(); } m_pLogWnd=NULL; }else if (IsLogWndAttached==2) { IsLogWndAttached=0; if (AttachedType==1) { m_RichLogWnd.Detach(); } m_pRichLogWnd=NULL; } return true; } double GetTickTime(double StartTime=0) { LARGE_INTEGER t1,f1; ::QueryPerformanceCounter(&t1); ::QueryPerformanceFrequency(&f1); return (double)t1.QuadPart/f1.QuadPart-StartTime; } void LogTxt(CString s,int channel=0) { if (channel<0||channel>=MAXLOGFILE) { return; } if (bAutoAppendRN) { if (s.Right(2)!=_T("\r\n")) { s.Append(_T("\r\n")); } } CString DateStr, TimeStr; if (bShowDate || bShowTime) { GetDateStr(DateStr); GetTimeStr(TimeStr); CString DateTimeStr; if (bShowDate && bShowTime) { DateTimeStr = _T("[") + DateStr + _T(" ") + TimeStr +_T("] "); }else if (bShowTime) { DateTimeStr = _T("[") + TimeStr + _T("] "); } s = DateTimeStr + s ; } if (bShowLog[channel]) { CString s2; myCriticalSection2.Lock(INFINITE); LineCount[channel]++; int ThreadId=GetCurrentThreadId(); if (bShowThreadId &&bShowChannel) { s2.Format(_T("[%d %4d]"),ThreadId,channel); }else if (bShowChannel) { s2.Format(_T("[%d]"),channel); }else{ s2.Empty(); } if (bShowLineCount) { s2.AppendFormat(_T("[%d]"),LineCount[channel]); } s2+=s; LogTextLength[channel]+=s2.GetLength(); if (bLogChanged[channel]==1) { strChangedLog[channel]+=s2; } else { strChangedLog[channel]=s2; } if (strChangedLog[channel].GetLength()>3000000) { strChangedLog[channel]=strChangedLog[channel].Mid(1000000); LogTextLength[channel]-=1000000; } bLogChanged[channel]=1; } if (bSaveLog[channel]) { LogToFile(s,channel); } myCriticalSection2.Unlock(); } int LogToFile(CString msg,int channel=0) { CString s1; CStringA sa1; CStringA DateStrA,TimeStrA,DateTimeStrA; CStringA msgA; CString DateStrT; CString logfilename; int j; #ifdef UNICODE int l; l=msg.GetLength(); j=WideCharToMultiByte(CP_ACP,0,msg,l,msgA.GetBuffer(l*2),l*2,NULL,NULL); msgA.ReleaseBuffer(j); #else msgA=msg; #endif try { CTime time1=CTime::GetTickCount(); CString timesecstr; timesecstr.Format(_T("%d"),time1); DateStrA.Format("%04d-%02d-%02d",time1.GetYear(),time1.GetMonth(),time1.GetDay()); DateStrT.Format(_T("%04d-%02d-%02d"),time1.GetYear(),time1.GetMonth(),time1.GetDay()); TimeStrA.Format("%02d:%02d:%02d",time1.GetHour(),time1.GetMinute(),time1.GetSecond()); DateTimeStrA=DateStrA+_T(" ")+TimeStrA; CString LogDirPath,LogFilePath; LogDirPath=LogPath+_T("\\")+DateStrT; if (bOneFilePerHour) { if (channel==0&&UsedChannelCount==1) { logfilename.Format(_T("%slog_%s_%02d.log"),LogFilePrefix,DateStrT,time1.GetHour()); LogFilePath=LogDirPath+_T("\\")+logfilename; }else { logfilename.Format(_T("%slog[%d]_%s_%s_%02d.log"),LogFilePrefix,channel,ChannelPrefix[channel],DateStrT,time1.GetHour()); LogFilePath=LogDirPath+_T("\\")+logfilename; } }else { if (channel==0&&UsedChannelCount==1) { logfilename.Format(_T("%slog_%s.log"),LogFilePrefix,DateStrT); LogFilePath=LogDirPath+_T("\\")+logfilename; }else { logfilename.Format(_T("%slog[%d]_%s_%s.log"),LogFilePrefix,channel,ChannelPrefix[channel],DateStrT); LogFilePath=LogDirPath+_T("\\")+logfilename; } } if (channel>=0&&channel------- ===== \r\n",DateTimeStrA); CLogFiles[channel].Write(sa1.GetString(),sa1.GetLength()); CLogFiles[channel].Close(); LogFilesOpened[channel]=0; } } if (!LogFilesOpened[channel]) { CString sAbsPath; if (IsAbspath(LogDirPath)) { sAbsPath=LogDirPath; sAbsPath.Replace(_T("/"),_T("\\")); }else { CString sCurPath; int len=GetCurrentDirectory(MAX_PATH,sCurPath.GetBuffer(MAX_PATH)); sCurPath.ReleaseBuffer(len); RelPathToAbsPath(sCurPath,LogDirPath,sAbsPath); } SHCreateDirectoryEx(NULL,sAbsPath,NULL); CFileException e; if (CLogFiles[channel].Open(LogFilePath,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::shareDenyWrite,&e)) { CLogFiles[channel].SeekToEnd(); sa1.Format("\r\n-< %s >------- ===== \r\n",DateTimeStrA,channel); CLogFiles[channel].Write(sa1.GetString(),sa1.GetLength()); LogFilesOpened[channel]=1; } else { LogFilesOpened[channel]=0; s1.Format(_T("ÈÕÖ¾Îļþ %s ²Ù×÷ʧ°Ü"),LogFilePath); strChangedLog[channel]+=s1+_T("\r\n"); return false; } } if (LogFilesOpened[channel]) { if (bShowTime) { sa1.Format("%s : %s",DateTimeStrA,msgA); } else { sa1=msgA; } CLogFiles[channel].Write(sa1,sa1.GetLength()); return true; } } return false; } catch (CMemoryException* e) { CString s1; CString stre1; e->GetErrorMessage(stre1.GetBuffer(2048),2048); stre1.ReleaseBuffer(); s1.Format(_T("·¢Éú´íÎó %s"),stre1); strChangedLog[channel]+=s1+_T("\r\n"); AfxMessageBox(s1); return false; } catch (CFileException* e) { CString s1; CString stre1; e->GetErrorMessage(stre1.GetBuffer(2048),2048); stre1.ReleaseBuffer(); s1.Format(_T("·¢Éú´íÎó %s"),stre1); strChangedLog[channel]+=s1+_T("\r\n"); AfxMessageBox(s1); return false; } catch (CException* e) { CString s1; CString stre1; e->GetErrorMessage(stre1.GetBuffer(2048),2048); stre1.ReleaseBuffer(); s1.Format(_T("·¢Éú´íÎó %s"),stre1); strChangedLog[channel]+=s1+_T("\r\n"); AfxMessageBox(s1); return false; } return false; } int UpdateLogDisplay(int channel=0) { int i,j,k; if (channel<0 || channel >= MAXLOGFILE) { return 0; } if (bPauseUpdate) { return 0; } if (bLogChanged[channel]==0) { return 0; } if (!myCriticalSection2.Lock(INFINITE)) { return -1; } if (IsLogWndAttached==1 && m_pLogWnd && IsWindow(m_pLogWnd->m_hWnd)) { if (LogTextLength[channel]>2000000) { int len = min(strDisplayedLog[channel].GetLength(),1000000); strDisplayedLog[channel]=strDisplayedLog[channel].Mid(len); m_pLogWnd->SetSel(0,len); m_pLogWnd->Clear(); LogTextLength[channel]-=len; } int line1,line2; line1=m_pLogWnd->GetFirstVisibleLine(); i=m_pLogWnd->GetLineCount(); j=m_pLogWnd->LineIndex(i-1); m_pLogWnd->SetSel(j,j,true); k=m_pLogWnd->LineIndex(-1)+m_pLogWnd->LineLength(-1); m_pLogWnd->SetSel(k,k,true); m_pLogWnd->ReplaceSel(strChangedLog[channel]); line2=m_pLogWnd->GetFirstVisibleLine(); strDisplayedLog[channel]+=strChangedLog[channel]; if (bNoScroll) { m_pLogWnd->LineScroll(line1-line2); } }else if (IsLogWndAttached==2 && m_pRichLogWnd && IsWindow(m_pRichLogWnd->m_hWnd)) { if (LogTextLength[channel]>2000000) { int len = min(strDisplayedLog[channel].GetLength(),1000000); strDisplayedLog[channel]=strDisplayedLog[channel].Mid(len); m_pRichLogWnd->SetSel(0,len); m_pRichLogWnd->Clear(); LogTextLength[channel]-=len; } int line1,line2; line1=m_pRichLogWnd->GetFirstVisibleLine(); i=m_pRichLogWnd->GetLineCount(); j=m_pRichLogWnd->LineIndex(i-1); m_pRichLogWnd->SetSel(j,j); k=m_pRichLogWnd->LineIndex(-1)+m_pLogWnd->LineLength(-1); m_pRichLogWnd->SetSel(k,k); m_pRichLogWnd->ReplaceSel(strChangedLog[channel]); line2=m_pRichLogWnd->GetFirstVisibleLine(); strDisplayedLog[channel]+=strChangedLog[channel]; if (bNoScroll) { m_pRichLogWnd->LineScroll(line1-line2); } } strChangedLog[channel].Empty(); bLogChanged[channel]=0; myCriticalSection2.Unlock(); return 0; } };