⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logview.cpp

📁 串口调试助手的源代码
💻 CPP
字号:
// Written by JHCC, 1997

// LogView.cpp : implementation file
//

#include "stdafx.h"
#include "JHHB.h"
#include "JHHBDoc.h"
#include "RowView.h"
#include "LogView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLogView

IMPLEMENT_DYNCREATE(CLogView, CRowView)

CLogView::CLogView()
{
	m_header.nLogCount = 0;
	m_header.nLogLength = sizeof(m_record);
	m_header.nExtraHeaderLength = sizeof(m_extraHeader);

	m_extraHeader.nFirstLogNo = 0;
	m_extraHeader.dwFileSignature = JHHB_LOG_SIGNATURE;

	m_nActiveLog = 0;
}

CLogView::~CLogView()
{
}

CJHHBDoc*	CLogView::GetDocument(void)
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CJHHBDoc)));
	return  (CJHHBDoc*)m_pDocument;
}

BOOL	CLogView::Open(LPCTSTR  lpszPathName)
{
	CString	strLogPathName;
	if (lpszPathName == NULL || ::lstrlen(lpszPathName) == 0)
	{
		// Show an open file dialog to get the name
		CFileDialog	dlg(TRUE,	// open
			NULL,	// no default extension
			NULL,	// no initial file name
			OFN_HIDEREADONLY,
			"Log files (*.Log)|*.LOG|All files (*.*)|*.*||");
		if (dlg.DoModal() == IDOK)
		{
			strLogPathName = dlg.GetPathName();
		}
		else
		{
			return  FALSE;
		}

		CString	strCtrlSection;
		strCtrlSection.LoadString(IDS_CTRLSECTION);

		CString	strLogFilePathItem;
		strLogFilePathItem.LoadString(IDS_LOGFILEPATHITEM);

		::AfxGetApp()->WriteProfileString(strCtrlSection, strLogFilePathItem, strLogPathName);
	}
	else
		strLogPathName = lpszPathName;

	ASSERT(m_file.m_hFile == CFile::hFileNull);
	CFileException	e;
	if (!m_file.Open(strLogPathName,
		CFile::modeReadWrite | CFile::shareExclusive, &e))
	{
		if (e.m_cause == CFileException::fileNotFound)
		{
			if (!m_file.Open(strLogPathName,
				CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive, &e))
				return  FALSE;
		}
	}

	// If the file is too long,we need remove and re_create it 
	//so that we can look it easy		add at 07/24/1997

	if (m_file.GetLength() >= 50*1024L)//2001年6月1日改,原50处为1024
	{
		m_file.Close();
		CFile::Remove( strLogPathName );
		if (!m_file.Open(strLogPathName,
			CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive, &e))
			return  FALSE;
	}

	// If the file is empty, that is so because the application has
	// just created a new file.
	// It this case, we need to create a header for the new file.
	// We pass bNewHeader=TRUE to WriteHeader so that the CLogView
	// takes the opportunity to write the first record in its override
	// of OnWriteHeader.

	if (m_file.GetLength() == 0L)
	{
		WriteHeader(&m_file, TRUE);
	}
	else
	{
		return (ReadHeader(&m_file));
	}

	return  TRUE;
}

void	CLogView::WriteHeader(CFile*  pFile, BOOL  bNewHeader)
{
	pFile->Seek(0L, CFile::begin);
	pFile->Write(&m_header, sizeof(m_header));
	if (m_header.nExtraHeaderLength > 0)
	{
		// OnWriteExtraHeader must be implemented by the derived class
		OnWriteExtraHeader(pFile, bNewHeader);
	}
}

BOOL CLogView::OnReadExtraHeader(CFile*  pFile)
{
	// and verify the file signature to make sure we're not
	// reading a non-Log file.

	if (pFile->Read(&m_extraHeader, sizeof(m_extraHeader)) < sizeof(m_extraHeader))
		return  FALSE;

	return  (m_extraHeader.dwFileSignature == JHHB_LOG_SIGNATURE);
}

void CLogView::OnWriteExtraHeader(CFile*  pFile, BOOL  bNewHeader)
{
	pFile->Write(&m_extraHeader, sizeof(m_extraHeader));

	// If this is a new header (that is, if the first is first being
	// created), then create the first record.
	if (bNewHeader)
	{
		ASSERT(pFile == &m_file);

		CString	strLogBegin;
		strLogBegin.LoadString(IDS_LOGBEGIN);
		AddNewLog(strLogBegin);
//		CreateNewRecord();
	}
}

BOOL CLogView::ReadHeader(CFile*  pFile)
{
	pFile->Seek(0L, CFile::begin);
	if (pFile->Read(&m_header, sizeof(m_header)) < sizeof(m_header))
		return  FALSE;

	if (m_header.nExtraHeaderLength < 1)
		return  TRUE;

	// OnReadExtraHeader is implemented by the derived class.
	return  OnReadExtraHeader(pFile);
}

//UINT	CLogView::CreateNewRecord(void)
UINT	CLogView::AddNewLog(CString  strMemo)
{
	// CreateNewRecord is called by the view to create a new fixed
	// length record.  Increment the record count and update the
	// the header to reflect the addition of a new record in the file.
	// Notify all views about the new record.
	UINT	nNewRecordIndex = m_header.nLogCount ++;
	WriteHeader(&m_file, FALSE);
	FileSeekRecord(nNewRecordIndex);
	void*	pNewRecord = OnCreateNewRecord(nNewRecordIndex, strMemo);
	m_file.Write(pNewRecord, m_header.nLogLength);

#ifdef _DEBUG
	// Read back the record just written to see if were written correctly.
	void*	pCompareRec = malloc(m_header.nLogLength);
	FileSeekRecord(nNewRecordIndex);
	if (m_file.Read(pCompareRec, m_header.nLogLength) < m_header.nLogLength)
		ASSERT(FALSE);
	ASSERT(memcmp(pCompareRec, pNewRecord, m_header.nLogLength) == 0);
	free(pCompareRec);
#endif

	UpdateRow(nNewRecordIndex);
	return  nNewRecordIndex;
}

void*	CLogView::OnCreateNewRecord(int  nNewLogIndex, CString  strMemo)
{
	// format a new log record (in memory).
	CTime	time = CTime::GetCurrentTime();
	CString	strDate = time.Format(_T("%Y/%m/%d"));
	CString	strTimeFmt = _T("%02i:%02i:%02i");
	CString	strTime;
	strTime.Format(strTimeFmt, time.GetHour(), time.GetMinute(), time.GetSecond());

	PackRecord(strDate, strTime, strMemo);
	m_nActiveLog = nNewLogIndex;
	return  &m_record;
}

void	CLogView::PackRecord(LPCTSTR  lpszDate, LPCTSTR  lpszTime, LPCTSTR  lpszMemo)
{
	lstrcpyn(m_record.szDate, lpszDate, sizeof(m_record.szDate) / sizeof(TCHAR));
	m_record.szDate[sizeof(m_record.szDate) / sizeof(TCHAR) - 1] = 0;

	lstrcpyn(m_record.szTime, lpszTime, sizeof(m_record.szTime) / sizeof(TCHAR));
	m_record.szTime[sizeof(m_record.szTime) / sizeof(TCHAR) - 1] = 0;

	lstrcpyn(m_record.szMemo, lpszMemo, sizeof(m_record.szMemo) / sizeof(TCHAR));
	m_record.szMemo[sizeof(m_record.szMemo) / sizeof(TCHAR) - 1] = 0;
}

void	CLogView::ParseRecord(CString&  strDate, CString& strTime, CString&  strMemo)
{
	strDate = m_record.szDate;
	strTime = m_record.szTime;
	strMemo = m_record.szMemo;
}

UINT	CLogView::GetRecordCount(void)
{
	return  m_header.nLogCount;
}

UINT CLogView::GetActiveLogNo(void)
{
	return  m_nActiveLog + m_extraHeader.nFirstLogNo;
}

UINT CLogView::GetFirstLogNo(void)
{
	return  m_extraHeader.nFirstLogNo;
}

UINT	CLogView::GetLastLogNo(void)
{
	return  m_extraHeader.nFirstLogNo + GetRecordCount() - 1;
}


void	CLogView::GetLog(UINT  nLogNo, CString&  strDate,
		CString&  strTime, CString&  strMemo)
{
	//nCheckNo - m_extraHeader.nFirstCheckNo
	GetRecord(nLogNo, &m_record);
	ParseRecord(strDate, strTime, strMemo);
}

///////////////////////////////////////////////////////////////////////
// Implementation

void CLogView::FileSeekRecord(UINT nRecord)
{
	m_file.Seek(sizeof(m_header) + m_header.nExtraHeaderLength
		+ nRecord * m_header.nLogLength,
		CFile::begin);
}

void	CLogView::GetRecord(UINT  nRecordIndex, void*  pRecord)
{
	FileSeekRecord(nRecordIndex);
	if (m_file.Read(pRecord, m_header.nLogLength) <
		m_header.nLogLength)
		ASSERT(FALSE);
}

void	CLogView::UpdateRecord(CView*  pSourceView, UINT  nRecordIndex,
	void*  pRecord)	// called by view
{
	FileSeekRecord(nRecordIndex);
	m_file.Write(pRecord, m_header.nLogLength);
}

void CLogView::GetRowWidthHeight(CDC*  pDC, int&  nRowWidth, int&  nRowHeight)
{
	TEXTMETRIC	tm;
	pDC->GetTextMetrics(&tm);
	nRowWidth = tm.tmAveCharWidth * ROW_WIDTH;
	nRowHeight = tm.tmHeight; // 1 lines of text
}

int	CLogView::GetActiveRow()
{
	return  GetActiveLogNo() - GetFirstLogNo();
}

int	CLogView::GetRowCount()
{
	return  GetLastLogNo() - GetFirstLogNo() + 1;
}

void CLogView::ChangeSelectionNextRow(BOOL  bNext)
{
	if (bNext)
	{
		if (m_nActiveLog < (GetRecordCount() - 1))
		{
			++ m_nActiveLog;
//			InvalidateRect(NULL, FALSE);
			UpdateRow(m_nActiveLog);
		}
	}
	else
	{
		if (m_nActiveLog > 0)
		{
			-- m_nActiveLog;
//			InvalidateRect(NULL, FALSE);
			UpdateRow(m_nActiveLog);			
		}
	}
}

void	CLogView::ChangeSelectionToRow(int  nRow)
{
	m_nActiveLog = nRow + GetFirstLogNo();
//	InvalidateRect(NULL, FALSE);
	UpdateRow(m_nActiveLog);
}

void	CLogView::OnDrawRow(CDC*  pDC, int  nRow, int  y, BOOL  bSelected)
{
	// Prepare for highlighting or un-highlighting the check, depending
	// on whether it is the currently selected check or not.  And
	// paint the background (behind the text) accordingly.
	CBrush	brushBackground;

	// save colors for drawing selected item on the screen
	COLORREF	crOldText = 0;
	COLORREF	crOldBackground = 0;

	if (!pDC->IsPrinting())
	{
		if (bSelected)
		{
			brushBackground.CreateSolidBrush(::GetSysColor(COLOR_HIGHLIGHT));
			crOldBackground = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
			crOldText = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
		}
		else
		{
			brushBackground.CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
		}

		CRect	rectSelection;
		pDC->GetClipBox(&rectSelection);
		rectSelection.top = y;
		rectSelection.bottom = y + m_nRowHeight;
		pDC->FillRect(&rectSelection, &brushBackground);
	}

	// Get the data for the specific check.
	int nLogNo = nRow + GetFirstLogNo();
	CString	strDate;
	CString	strTime;
	CString	strMemo;
	GetLog(nLogNo, strDate, strTime, strMemo);

	TEXTMETRIC	tm;
	pDC->GetTextMetrics(&tm);

	// Display the log in one lines of text.
	// line 1
	pDC->TextOut(DATE_COL * tm.tmAveCharWidth, y, strDate);
	pDC->TextOut(TIME_COL * tm.tmAveCharWidth, y, strTime);
	pDC->TextOut(MEMO_COL * tm.tmAveCharWidth, y, strMemo);

	// Restore the DC.
	if (!pDC->IsPrinting() && bSelected)
	{
		pDC->SetBkColor(crOldBackground);
		pDC->SetTextColor(crOldText);
	}
}

BEGIN_MESSAGE_MAP(CLogView, CRowView)
	//{{AFX_MSG_MAP(CLogView)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLogView drawing

void CLogView::OnInitialUpdate()
{
	CRowView::OnInitialUpdate();

	CSize sizeTotal;
	// TODO: calculate the total size of this view
	sizeTotal.cx = sizeTotal.cy = 100;
	SetScrollSizes(MM_TEXT, sizeTotal);

	CString	strCtrlSection;
	strCtrlSection.LoadString(IDS_CTRLSECTION);

	CString	strLogFilePathItem;
	strLogFilePathItem.LoadString(IDS_LOGFILEPATHITEM);

	CString	strLogFilePath;
	strLogFilePath = ::AfxGetApp()->GetProfileString(strCtrlSection, strLogFilePathItem);

	Open(strLogFilePath);
}

/////////////////////////////////////////////////////////////////////////////
// CLogView diagnostics

#ifdef _DEBUG
void CLogView::AssertValid() const
{
	CRowView::AssertValid();
}

void CLogView::Dump(CDumpContext& dc) const
{
	CRowView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CLogView message handlers
/*
int CLogView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) 
{
	// side-step CRowView's implementation since we don't want to activate
	// this view
	return  CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
*/

⌨️ 快捷键说明

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