www.pudn.com > ScrollText.zip > TextScroller.cpp


// TextScroller.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "TextScroller.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CTextScroller 
 
CTextScroller::CTextScroller() 
{ 
	m_CurrentY		= 0; 
	m_bFirstTime	= TRUE; 
	m_TextColor		= RGB(0,0,0); 
	m_BkColor		= RGB(204,204,255); 
	m_bDecreasePos	= TRUE; 
	m_nHeight		= 0; 
	m_nWidth		= 0; 
	::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf); 
	m_font.CreateFontIndirect(&m_lf); 
} 
 
CTextScroller::~CTextScroller() 
{ 
	FreeList(); 
	m_font.DeleteObject(); 
} 
 
 
BEGIN_MESSAGE_MAP(CTextScroller, CStatic) 
	//{{AFX_MSG_MAP(CTextScroller) 
	ON_WM_PAINT() 
	ON_WM_TIMER() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CTextScroller message handlers 
 
void CTextScroller::AddLine(CStringArray &str) 
{ 
	Line *_line = NULL; 
	for(int ii =0 ;iistrLine  = str.GetAt(ii); 
		_line->pos	    = 0; 
		_line->Initpos  = 0; 
		_line->bDecrease= TRUE; 
		m_Lines.AddTail(_line); 
	} 
	FormatLines(); 
	Invalidate(); 
} 
 
void CTextScroller::PreSubclassWindow()  
{ 
	CStatic::PreSubclassWindow(); 
	ModifyStyle(0,SS_BITMAP, SS_OWNERDRAW); 
	ModifyStyle(0,WS_BORDER,SWP_DRAWFRAME); 
} 
 
void CTextScroller::OnPaint()  
{ 
	KillTimer(0); 
	CPaintDC dc(this); // device context for painting 
	DrawBkGround(&dc); 
	SetTimer(0,50,NULL); 
} 
 
void CTextScroller::DrawBkGround(CDC *pDC,CRect InvalidRect) 
{ 
	CRect rectClient; 
	GetClientRect(rectClient); 
	if(InvalidRect == CRect(0,0,0,0)) 
		InvalidRect = rectClient; 
	if(m_bFirstTime) 
	{ 
		if(m_Lines.GetCount()) 
		{ 
			POSITION pos = m_Lines.GetHeadPosition(); 
			Line *_line = NULL; 
			int offset = rectClient.bottom;  
			CFont *pOldFont = pDC->SelectObject(&m_font); 
			CSize size = pDC->GetTextExtent(_T("TEST")); 
			pDC->SelectObject(pOldFont); 
			while(pos) 
			{ 
				_line  = m_Lines.GetNext(pos); 
				if(_line) 
				{ 
					_line->pos	   = offset; 
					_line->Initpos = offset; 
					offset += size.cy + 1; 
				} 
			} 
			m_bFirstTime = 0; 
		} 
	} 
	pDC->FillSolidRect(&InvalidRect,m_BkColor); 
} 
 
void CTextScroller::OnTimer(UINT nIDEvent)  
{ 
	if(nIDEvent == 0) 
	{ 
		MoveTextToTheTop(); 
	} 
	CStatic::OnTimer(nIDEvent); 
} 
 
void CTextScroller::MoveTextToTheTop() 
{ 
	int count = m_Lines.GetCount(); 
	if(!count) 
		return; 
	CDC *pDC = GetDC(); 
	CRect rectClient; 
	GetClientRect(rectClient); 
	CFont *pOldFont = pDC->SelectObject(&m_font); 
	int iOldMode    = pDC->SetBkMode(TRANSPARENT); 
	COLORREF col    = pDC->SetTextColor(m_TextColor); 
	CSize size = pDC->GetTextExtent(_T("TEST")); 
	Line *_line = NULL; 
	POSITION pos = m_Lines.GetHeadPosition(); 
	int nIndex = -1; 
	while(pos) 
	{ 
		 _line = m_Lines.GetNext(pos); 
		 nIndex++; 
		 if(!_line) 
			 return; 
		 if(_line->bDecrease) 
			(_line->pos)--; 
		if(_line->pos < 0) 
		{ 
			DrawBkGround(pDC,CRect(0,_line->pos - 1,rectClient.right,_line->pos + size.cy - 1)); 
			_line->pos = _line->Initpos; 
			if(nIndex == m_Lines.GetCount()-1) 
			{ 
				pos = m_Lines.GetHeadPosition(); 
				while(pos) 
				{ 
					_line = m_Lines.GetNext(pos); 
					_line->bDecrease = TRUE; 
				} 
				break; 
			} 
			else 
				_line->bDecrease = FALSE; 
			continue; 
		} 
		if(_line->pos > rectClient.bottom - size.cy) 
			continue; 
		DrawBkGround(pDC,CRect(0,_line->pos - 1,rectClient.right,_line->pos + size.cy + 1)); 
		pDC->DrawText(_line->strLine,CRect(0,_line->pos,rectClient.right,_line->pos + size.cy),DT_CENTER); 
	} 
	pDC->SetBkMode(iOldMode); 
	pDC->SelectObject(pOldFont); 
	pDC->SetTextColor(col); 
//Clean the top of the window 
	DrawBkGround(pDC,CRect(0,0,rectClient.right,size.cy)); 
	ReleaseDC(pDC); 
} 
 
void CTextScroller::FormatLines() 
{ 
//Get nbr caractere that can fit the client rectangle 
	CDC *pDC = GetDC(); 
	CFont *pOldFont = pDC->SelectObject(&m_font); 
	CSize size		= pDC->GetTextExtent("T"); 
	pDC->SelectObject(pOldFont); 
	CRect rectClient; 
	GetClientRect(rectClient); 
	int nbrCarPerLine = (rectClient.Width() / size.cx); 
//format text now 
	POSITION pos = m_Lines.GetHeadPosition(); 
	int posEsp   = 0; 
	Line *_line  = NULL; 
	CStringArray tmpArray; 
	CString strLine; 
	CString tmp; 
	while(pos) 
	{ 
		_line = m_Lines.GetNext(pos); 
		strLine = _line->strLine; 
		while(!strLine.IsEmpty()) 
		{ 
			posEsp = 0; 
			strLine.TrimRight(); 
			if(nbrCarPerLine < strLine.GetLength() && strLine.GetAt(nbrCarPerLine) != ' ') 
			{ 
				int Oldpos = 0; 
				while(posEsp <= nbrCarPerLine  && posEsp != -1) 
				{ 
					Oldpos = posEsp; 
					posEsp = strLine.Find(' ',posEsp+1); 
				} 
				posEsp = Oldpos; 
			} 
			else 
			{ 
				if(nbrCarPerLine < strLine.GetLength()) 
					posEsp = nbrCarPerLine; 
				else 
				{ 
					strLine += ' '; 
					posEsp = strLine.GetLength()-1; 
				} 
			} 
			tmp = strLine; 
			if(posEsp) 
				strLine.Delete(posEsp,strLine.GetLength()-posEsp); 
			tmpArray.Add(strLine); 
			tmp.Delete(0,posEsp+1); 
			strLine = tmp; 
		} 
	} 
	FreeList(); 
//fill the list with new strings 
	for(int ii = 0;iistrLine  = tmpArray.GetAt(ii); 
		_line->pos	    = 0; 
		_line->Initpos  = 0; 
		_line->bDecrease= TRUE; 
		m_Lines.AddTail(_line); 
	} 
} 
 
void CTextScroller::FreeList() 
{ 
	POSITION pos = m_Lines.GetHeadPosition(); 
	Line *_line = NULL; 
	while(pos) 
	{ 
		_line = m_Lines.GetNext(pos); 
		delete _line; 
	} 
	m_Lines.RemoveAll(); 
} 
 
COLORREF CTextScroller::SetBkColor(COLORREF color) 
{ 
	COLORREF OldCol = m_BkColor; 
	m_BkColor = color; 
	Invalidate(); 
	return OldCol; 
} 
 
void CTextScroller::SetScrollTimer(int nElapse) 
{ 
	if(nElapse >0) 
	{ 
		KillTimer(0); 
		SetTimer(0,nElapse,NULL); 
	} 
} 
 
COLORREF CTextScroller::SetTextColor(COLORREF color) 
{ 
	COLORREF OldCol = m_TextColor; 
	m_TextColor = color; 
	Invalidate(); 
	return OldCol; 
} 
 
void CTextScroller::SetBorder(BOOL bSet) 
{ 
	if(bSet) 
		ModifyStyle(0,WS_BORDER,SWP_DRAWFRAME); 
	else 
		ModifyStyle(WS_BORDER,0,SWP_DRAWFRAME); 
} 
 
CString CTextScroller::SetFontName(CString strFont) 
{ 
	CString OldFontName = _T(m_lf.lfFaceName); 
	strcpy(m_lf.lfFaceName,strFont); 
	m_font.DeleteObject(); 
	m_font.CreateFontIndirect(&m_lf); 
	Invalidate(); 
	return OldFontName; 
} 
 
void CTextScroller::SetFontBold(BOOL bIsBold) 
{ 
	m_lf.lfWeight = bIsBold ? FW_BOLD : FW_NORMAL; 
	m_font.DeleteObject(); 
	m_font.CreateFontIndirect(&m_lf); 
	Invalidate(); 
} 
 
void CTextScroller::SetFontItalic(BOOL bItalic) 
{ 
	m_lf.lfItalic = bItalic; 
	m_font.DeleteObject(); 
	m_font.CreateFontIndirect(&m_lf); 
	Invalidate(); 
} 
 
void CTextScroller::SetFontSize(int nSize) 
{ 
	nSize*=-1; 
	m_lf.lfHeight = nSize; 
	m_font.DeleteObject(); 
	m_font.CreateFontIndirect(&m_lf); 
	Invalidate(); 
}