Click here to Skip to main content
15,895,142 members
Articles / Desktop Programming / MFC

A real time log file viewer

Rate me:
Please Sign up or sign in to vote.
4.81/5 (19 votes)
17 May 20042 min read 172.7K   4.5K   58  
A real time log file viewer.
/* Written By and � 2004 Amleth Ojalen (amleth@amleth.com)

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:


1. Redistributions of source code must retain the above copyright notice, this list 
of conditions and the following disclaimer. 

2. Redistributions in binary form must reproduce the above copyright notice, this list 
of conditions and the following disclaimer in the documentation and/or other 
materials provided with the distribution. 

3. The name of the author may not be used to endorse or promote products derived 
from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#include "StdAfx.h"
#include "cablogfiledraw.h"
#include "MemDC.h"

#define GetRed(dColor)		( dColor & 0x0000FF)
#define GetGreen(dColor)	((dColor & 0x00FF00) >> 8) 
#define GetBlue(dColor)		((dColor & 0xFF0000) >> 16)


CABLogFileDraw::CABLogFileDraw(void)
{
	m_iLineHeight = 0;
	m_iMarginLeft = 0;
	m_iCharWidth = 0;
	m_iTopLine = 0;
	m_Font = NULL;
	m_iTabWidth = 4;

	m_Selection.top = 0;
	m_Selection.left = 0;
	m_Selection.right = 0;
	m_Selection.bottom = 0;


	m_dTextBackColor	= RGB(0xFF, 0xFF, 0xFF);
	m_dTextColor		= RGB(0x00, 0x00, 0x00);
	m_dLineColor		= RGB(0xFF, 0xFF, 0xFF);
	m_dLineBackColor	= RGB(0x88, 0x88, 0x88);
	m_dNewTextColor		= RGB(0xFF, 0x00, 0x00);
	m_dSelColor			= RGB(0xFF, 0xFF, 0xFF);
	m_dSelBackColor		= RGB(0x00, 0x00, 0x00);
	m_dTagColor			= RGB(0xFF, 0x99, 0xFF);

	m_Fade[0] = 0xFFFFFFFF;
}

CABLogFileDraw::~CABLogFileDraw(void)
{
	if (m_Font)
	{
		delete m_Font;
		m_Font = NULL;
	}

}

void CABLogFileDraw::LoadFadeSteps()
{

	// this will load the fade steps into an array for quick access
	int iCounter;
	
	byte bRed;
	byte bGreen;
	byte bBlue;

	int iRed;
	int iGreen;
	int iBlue;

	double dRed;
	double dGreen;
	double dBlue;
	
	iRed = GetRed(m_dNewTextColor) - GetRed(m_dTextColor);
	iGreen = GetGreen(m_dNewTextColor) - GetGreen(m_dTextColor);
	iBlue = GetBlue(m_dNewTextColor) - GetBlue(m_dTextColor);

	dRed = (double)iRed / (double)FADE_STEPS;
	dGreen = (double)iGreen / (double)FADE_STEPS;
	dBlue = (double)iBlue / (double)FADE_STEPS;

	for (iCounter = 0; iCounter < FADE_STEPS; iCounter++)
	{
 		bRed = (byte)(GetRed(m_dTextColor) + (dRed * iCounter));
		bGreen = (byte)(GetGreen(m_dTextColor) + (dGreen * iCounter));
		bBlue = (byte)(GetBlue(m_dTextColor) + (dBlue * iCounter));

		m_Fade[iCounter] = RGB(bRed, bGreen, bBlue);
	}
}

void CABLogFileDraw::Draw(CDC * pDC, CRect * pRect, CABLogBuffer * pBuffer)
{
	// this will draw from the data ontp pDC
	// from m_iTopLine and m_iLeftChar
	
	
	// Create a memory DC from drawing
	CMemDC	dc(pDC, pRect);

	CFont *		pOldFont;
	long lCounter;

	if (m_Font == NULL)
	{
		// if this is the first time around create the font
		m_Font = new CFont;
		m_Font->CreateFont(14,0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,"courier new");
	}

	pOldFont = dc.SelectObject(m_Font);

	if (m_iLineHeight == 0)
	{
		// if this is the first time around get line height
		CSize tSize;
		tSize = dc.GetTextExtent("W_");
		m_iLineHeight = tSize.cy;
	}
	if (m_iCharWidth == 0)
	{
		// if this is the first time around get line Width
		CSize tSize;
		tSize = dc.GetTextExtent("W");
		m_iCharWidth= tSize.cx;

		// make the Tabs
		for (lCounter = 0; lCounter < _MAX_TABS; lCounter ++)
			m_iTabs[lCounter] = lCounter * m_iCharWidth * m_iTabWidth;

	}

	int iDocLineCount;

	// errase the background
	dc.FillSolidRect(pRect, m_dTextBackColor);

	iDocLineCount = pBuffer->GetLineCount();
	if (iDocLineCount > 0)
	{
		// is there any lines to draw
		CABLogBuffer::S_ABLogLine * pLine;

		int iLastLine;
		int iTopOffset;
		int iLineCount;
		CSize	tOutPos;

		// wokr out the last line to display
		iLastLine = m_iTopLine + (pRect->Height() /  m_iLineHeight) + 2;
		if (iLastLine > iDocLineCount) 
			iLastLine = iDocLineCount;
		
		
		iLineCount = m_iTopOffset;
		iTopOffset = m_iTopOffset;
		
		if (m_iMarginLeft == 0)
		{
			// if this is the first time around get the Left margin
			CSize tSize;
			tSize = dc.GetTextExtent("000000");
			m_iMarginLeft = tSize.cx + 6 + m_iCharWidth * 2;
		}

		// fill the margin
		dc.FillSolidRect(0,0, m_iMarginLeft - 2, pRect->Height(), m_dLineBackColor);

		for (lCounter = m_iTopLine; lCounter < iLastLine; lCounter++)
		{
			// do for all the lines that we are displaying
			CString strLineNo;
			int iOffset;
			int iTabOffset;
			int iFadeStep;


			// print line
			dc.SetBkColor(m_dTextBackColor);

			pLine = pBuffer->GetLine(lCounter);

			// work out the TabOffset and the printign offset.
			// this only matters if m_iLeftChar > 0
			iOffset = m_iMarginLeft + m_iLeftOffset - (m_iLeftChar * m_iCharWidth);
			iTabOffset = ((0-m_iLeftChar) * m_iCharWidth) + m_iLeftOffset;

			// draw the line
			WriteLine(&dc, pLine, lCounter, &iOffset, &iTopOffset, 0, iTabOffset, pRect, pBuffer);

			// fill the background for the LineNumbers			
			dc.FillSolidRect(0,iTopOffset, m_iMarginLeft - 2, m_iLineHeight, m_dLineBackColor);
			dc.SetBkColor(m_dLineBackColor);
			//check to see if this is a newly modified line
			// if so change the color.
			pBuffer->HitTest(lCounter, pLine->m_lLineLength-1, NULL, &iFadeStep);
			if (iFadeStep != 0)
				dc.SetTextColor(m_dNewTextColor); 
			else
				dc.SetTextColor(m_dLineColor); 
			// Draw the Line Number
			strLineNo.Format("%06i", lCounter + 1);
			dc.TextOut(m_iCharWidth * 2, iTopOffset, strLineNo);

			// draw the Tag symbol if the line is tagged
			if ((pLine->m_dFlags & LF_TAGGED) == LF_TAGGED)
				dc.FillSolidRect(1, iTopOffset + 1, ((m_iCharWidth* 2) -2), m_iLineHeight -2, m_dTagColor);

			iTopOffset +=m_iLineHeight;
		}
		dc.FillSolidRect(0,iTopOffset, m_iMarginLeft - 2, m_iLineHeight, m_dLineBackColor);

	}
	else
	{
		//blank Document

	}
	dc.SelectObject(pOldFont);
}


void CABLogFileDraw::WriteLine(CDC * pDC, CABLogBuffer::S_ABLogLine * pLine, long lLine, int * iX, int * iY, int iLeftChar, int iTabOffset, CRect * pRect, CABLogBuffer * pBuffer)
{
	// this works out the steps to draw a line

	int		iColorIndex;
	int		iNewColorIndex;
	int		iLineOffset;
	int		iLineStart;
	bool	bSelected;
	bool	bNewSelected;



	if ((pLine->m_lLineLength - iLeftChar) > 0)
	{
		// there is something to draw.
		iLineOffset = iLeftChar;
		iLineStart = iLineOffset;

		// check to first drable character and get is properties.
		pBuffer->HitTest(lLine, iLineOffset, &bSelected, &iColorIndex);
		iLineOffset ++; 
		while (iLineOffset < pLine->m_lLineLength)
		{
			// get the next characters properties.
			pBuffer->HitTest(lLine, iLineOffset, &bNewSelected, &iNewColorIndex);
			if ((bNewSelected != bSelected) || (iNewColorIndex != iColorIndex))
			{
				// the next character is different so draw the previous characters.
				WriteText(pDC, (LPCTSTR)&pLine->m_pLinePointer[iLineStart], iLineOffset - iLineStart, iX, iY, bSelected, m_Fade[iColorIndex], false, iTabOffset, pRect);
				iLineStart = iLineOffset;
				bSelected = bNewSelected;
				iColorIndex = iNewColorIndex;
			}
			// go to the next character
			iLineOffset++;
		} 
		if ((iLineOffset - iLineStart) > 0)
			// if there is any text left over draw it.
			WriteText(pDC, (LPCTSTR)&pLine->m_pLinePointer[iLineStart], iLineOffset - iLineStart, iX, iY, bSelected, m_Fade[iColorIndex], true, iTabOffset, pRect);		
	}
}

void CABLogFileDraw::WriteText(CDC * pDC, LPCTSTR strText, int iLength, int * iX, int * iY, bool bSelected, DWORD dColor, bool bLast, int iTabOffset, CRect * pRect)
{
	// this actually draws the text.
	CSize	tSize;
	if (bSelected)
	{
		// its selected
		pDC->SetBkColor(m_dSelBackColor);
		pDC->SetTextColor(m_dSelColor);
	}
	else
	{
		// its not selected
		pDC->SetBkColor(m_dTextBackColor);
		if (dColor == 0xFFFFFFFF)
			// default color
			pDC->SetTextColor(m_dTextColor);
		else
			pDC->SetTextColor(dColor);
	}
	// draw the text
	tSize = pDC->TabbedTextOut(*iX, *iY, strText, iLength, _MAX_TABS, m_iTabs,  iTabOffset);
	*iX+= tSize.cx;
	if (bLast && bSelected)
	{
		// this is the last character, and it is selected
		// draw a selected background for the rest of the line
		CRect tRect;
		tRect = *pRect;
		tRect.left = *iX;
		tRect.top = *iY;
		tRect.bottom = tRect.top + m_iLineHeight;
		pDC->FillSolidRect(tRect, m_dSelBackColor);
	}


}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Australia Australia
Started programming many many years ago, now a full time C++ developer writing medical software. I have also been known to dabble in electronics. Currently looking to go back to university to study electronic engineering.

Comments and Discussions