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

📄 ctrltext.cpp

📁 p2p软件
💻 CPP
字号:
//
// CtrlText.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "CtrlText.h"

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

BEGIN_MESSAGE_MAP(CTextCtrl, CWnd)
	//{{AFX_MSG_MAP(CTextCtrl)
	ON_WM_VSCROLL()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

#define LINE_BUFFER_LIMIT		1024
#define LINE_BUFFER_BLOCK		64


/////////////////////////////////////////////////////////////////////////////
// CTextCtrl construction

CTextCtrl::CTextCtrl()
{
	m_crBackground	= GetSysColor( COLOR_WINDOW );
	m_crText[0]		= RGB( 0, 0, 0 );
	m_crText[1]		= RGB( 0, 0, 127 );
	m_crText[2]		= RGB( 255, 0, 0 );
	m_crText[3]		= RGB( 192, 192, 192 );
	m_crText[4]		= RGB( 0, 0, 255 );

	m_pFont.CreateFont( -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
		DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
		DEFAULT_PITCH|FF_DONTCARE, _T("Courier New") );
	m_cCharacter = CSize( 0, 0 );
}

CTextCtrl::~CTextCtrl()
{
	Clear( FALSE );
}

/////////////////////////////////////////////////////////////////////////////
// CTextCtrl operations

BOOL CTextCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) 
{
	dwStyle |= WS_CHILD|WS_VSCROLL;
	return CWnd::Create( NULL, NULL, dwStyle, rect, pParentWnd, nID, NULL );
}

void CTextCtrl::Add(int nType, LPCTSTR pszText)
{
	CSingleLock pLock( &m_pSection, TRUE );
	CString strLine;

	for ( ; *pszText ; pszText++ )
	{
		if ( *pszText == 13 )
		{
			if ( strLine.GetLength() ) AddLine( nType, strLine );
			strLine.Empty();
		}
		else if ( *pszText != 10 )
		{
			strLine += *pszText;
		}
	}

	if ( strLine.GetLength() ) AddLine( nType, strLine );
}

void CTextCtrl::AddLine(int nType, LPCTSTR pszLine)
{
	CSingleLock pLock( &m_pSection, TRUE );

	if ( m_pLines.GetSize() >= LINE_BUFFER_LIMIT )
	{
		for ( int nCount = 0 ; nCount < LINE_BUFFER_BLOCK ; nCount++ )
		{
			delete (CTextLine*)m_pLines.GetAt( 0 );
			m_pLines.RemoveAt( 0 );
		}
		m_bProcess = TRUE;
	}

	m_pLines.Add( new CTextLine( nType, pszLine ) );
	Invalidate();
}

void CTextCtrl::Clear(BOOL bInvalidate)
{
	CSingleLock pLock( &m_pSection, TRUE );

	for ( int nLine = 0 ; nLine < m_pLines.GetSize() ; nLine++ )
	{
		delete (CTextLine*)m_pLines.GetAt( nLine );
	}
	m_pLines.RemoveAll();
	
	m_nPosition = m_nTotal = 0;

	if ( bInvalidate )
	{
		UpdateScroll( TRUE );
		Invalidate();
	}
}

void CTextCtrl::UpdateScroll(BOOL bFull)
{
	SCROLLINFO si;

	ZeroMemory( &si, sizeof(si) );
	si.cbSize = sizeof(si);

	if ( bFull )
	{
		CRect rc;
		GetClientRect( &rc );

		si.fMask	= SIF_POS|SIF_PAGE|SIF_RANGE|SIF_DISABLENOSCROLL;
		si.nPos		= m_nPosition;
		si.nPage	= rc.Height() / m_cCharacter.cy;
		si.nMin		= 0;
		si.nMax		= m_nTotal + si.nPage - 1;
	}
	else
	{
		si.fMask	= SIF_POS;
		si.nPos		= m_nPosition;
	}
	
	SetScrollInfo( SB_VERT, &si );
}

CFont* CTextCtrl::GetFont()
{
	return &m_pFont;
}

/////////////////////////////////////////////////////////////////////////////
// CTextCtrl message handlers

int CTextCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
	
	m_nPosition = m_nTotal = 0;
	m_bProcess = TRUE;
	
	return 0;
}

void CTextCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	CSingleLock pLock( &m_pSection, TRUE );
	SCROLLINFO si;

	ZeroMemory( &si, sizeof(si) );
	si.cbSize	= sizeof(si);
	si.fMask	= SIF_ALL;

	GetScrollInfo( SB_VERT, &si );

	switch ( nSBCode )
	{
	case SB_TOP:
		m_nPosition = 0;
		break;
	case SB_BOTTOM:
		m_nPosition = m_nTotal - 1;
		break;
	case SB_LINEUP:
		m_nPosition--;
		break;
	case SB_LINEDOWN:
		m_nPosition++;
		break;
	case SB_PAGEUP:
		m_nPosition -= ( si.nPage - 1 );
		break;
	case SB_PAGEDOWN:
		m_nPosition += ( si.nPage - 1 );
		break;
	case SB_THUMBPOSITION:
	case SB_THUMBTRACK:
		m_nPosition = si.nTrackPos;
		break;
	}

	m_nPosition = max( 0, min( m_nTotal, m_nPosition ) );

	UpdateScroll();
	Invalidate();
}

BOOL CTextCtrl::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

void CTextCtrl::OnPaint() 
{
	CSingleLock pLock( &m_pSection, TRUE );
	CRect rcClient, rcLine;
	CPaintDC dc( this );
	
	GetClientRect( &rcClient );

	CFont* pOldFont = (CFont*)dc.SelectObject( &m_pFont );
	
	if ( m_cCharacter.cx == 0 ) m_cCharacter = dc.GetTextExtent( _T("X") );

	BOOL bBottom	= ( m_nPosition >= m_nTotal );
	BOOL bModified	= m_bProcess;

	if ( m_bProcess ) m_nTotal = 0;
	
	int nWidth = ( rcClient.right - 4 ) / m_cCharacter.cx;

	for ( int nLine = 0 ; nLine < m_pLines.GetSize() ; nLine++ )
	{
		CTextLine* pLine = (CTextLine*)m_pLines.GetAt( nLine );

		if ( m_bProcess || ! pLine->m_nLine )
		{
			m_nTotal += pLine->Process( nWidth );
			bModified = TRUE;
		}
	}

	if ( bBottom ) m_nPosition = m_nTotal;
	if ( bModified ) UpdateScroll( TRUE );
	m_bProcess = FALSE;

	dc.SetTextColor( m_crText[0] );
	dc.SetBkColor( m_crBackground );
	dc.SetBkMode( OPAQUE );

	rcLine.CopyRect( &rcClient );
	rcLine.bottom += ( m_nTotal - m_nPosition ) * m_cCharacter.cy;
	rcLine.top = rcLine.bottom - m_cCharacter.cy;

	for ( nLine = m_pLines.GetSize() - 1 ; nLine >= 0 && rcLine.bottom > 0 ; nLine-- )
	{
		CTextLine* pLine = (CTextLine*)m_pLines.GetAt( nLine );

		dc.SetTextColor( m_crText[ pLine->m_nType ] );
		pLine->Paint( &dc, &rcLine );
	}

	if ( rcLine.bottom > 0 )
	{
		rcLine.top = 0;
		dc.FillSolidRect( &rcLine, m_crBackground );
	}

	dc.SelectObject( pOldFont );
}

void CTextCtrl::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize( nType, cx, cy );
	m_bProcess = TRUE;
}

void CTextCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
	SetFocus();
}

/////////////////////////////////////////////////////////////////////////////
// CTextLine construction

CTextLine::CTextLine(int nType, LPCTSTR pszText)
{
	m_sText	= pszText;
	m_pLine	= NULL;
	m_nLine	= 0;
	m_nType = nType;
}

CTextLine::~CTextLine()
{
	if ( m_pLine ) delete [] m_pLine;
}

/////////////////////////////////////////////////////////////////////////////
// CTextLine process

int CTextLine::Process(int nWidth)
{
	if ( m_pLine ) delete [] m_pLine;
	m_pLine = NULL;
	m_nLine = 0;
	
	int nLength = 0;
	int nLast = 0;

	for ( LPCTSTR pszText = m_sText ; ; pszText++, nLength++ )
	{
		if ( *pszText == 32 || *pszText == 0 )
		{
			if ( nLength <= nWidth )
			{
				nLast = nLength;
			}
			else if ( nLast )
			{
				AddLine( nLast );
				nLength = nLast = nLength - nLast;
			}
			else
			{
				break;
			}
		}

		if ( *pszText == 0 ) break;
	}

	if ( nLength || !m_nLine ) AddLine( nLength );

	return m_nLine;
}

void CTextLine::AddLine(int nLength)
{
	int* pLine = new int[ m_nLine + 1 ];
	CopyMemory( pLine, m_pLine, m_nLine * sizeof(int) );
	if ( m_pLine ) delete [] m_pLine;
	m_pLine = pLine;
	m_pLine[ m_nLine++ ] = nLength;
}

/////////////////////////////////////////////////////////////////////////////
// CTextLine paint

void CTextLine::Paint(CDC* pDC, CRect* pRect)
{
	int nHeight = pRect->bottom - pRect->top;

	pRect->top		-= ( m_nLine - 1 ) * nHeight;
	pRect->bottom	-= ( m_nLine - 1 ) * nHeight;

	LPCTSTR pszLine	= m_sText;
	int* pLength	= m_pLine;

	for ( int nLine = 0 ; nLine < m_nLine ; nLine++, pLength++ )
	{
		if ( pDC->RectVisible( pRect ) )
		{
			pDC->ExtTextOut( pRect->left + 2, pRect->top, ETO_CLIPPED|ETO_OPAQUE,
				pRect, pszLine, *pLength, NULL );
		}
		pszLine += *pLength;

		pRect->top += nHeight;
		pRect->bottom += nHeight;
	}

	pRect->top		-= ( m_nLine + 1 ) * nHeight;
	pRect->bottom	-= ( m_nLine + 1 ) * nHeight;
}

⌨️ 快捷键说明

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