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

📄 colorstring.cpp

📁 检测语法的Edit类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "ColorString.h"

//  Copyright (c) 1996-1997, Keith Rule
//  You may freely use or modify this code provided this 
//  copyright is included in all derived versions.

UINT AFX_CDECL CColorStringBkgThread(LPVOID object)
{
	CColorString&	text = *((CColorString*) object);
	long			len, count = 0;
	CColorArray		renderColor;	// Hmm - This shouldn't be declared here, 
									// it causes a leak when the thread is terminated.

	// This isn't exactly efficent, but hey it's running in
	// the background
	for (;;) {
		len = text.GetLength();

		if (text.CommentPos() < len || text.KeywordPos() < len || text.QuotePos() < len) {
			renderColor.SetSize(len);
			renderColor.SetColor(text.m_defaultColor, 0, len);

			text.CommentPos(0); text.KeywordPos(0); text.QuotePos(0);
			if (text.m_color.GetSize() != len) {
				text.m_color.SetSize(len);
			}

			if (!text.ParseKeywords(renderColor)) goto restart;
			if (!text.ParseQuotes(renderColor)) goto restart;
			if (!text.ParseComments(renderColor)) goto restart;
		
			if (renderColor != text.m_color && len == text.GetLength())  
			{
				text.m_color = renderColor;
				text.DoUpdate(count > 0);
			}
		}
restart:
		::Sleep(100);
		count++;
	}

	return 0;
}


CColorString::CColorString(BOOL bUseThread) : CStringEx(), 
	m_defaultColor(RGB(0, 0, 0)), m_bkgThread(NULL),
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)), m_updateLevel(0),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::CColorString(const CString& stringSrc, BOOL bUseThread) : CStringEx( stringSrc ), m_bkgThread(NULL),
	m_defaultColor(RGB(0, 0, 0)), 
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)), m_updateLevel(0),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::CColorString(const CStringEx& stringSrc, BOOL bUseThread) : CStringEx( stringSrc ), m_bkgThread(NULL),
	m_defaultColor(RGB(0, 0, 0)), 
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)), m_updateLevel(0),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::CColorString(TCHAR ch, int nRepeat /*= 1*/, BOOL bUseThread) : CStringEx( ch, nRepeat ), m_bkgThread(NULL),
	m_defaultColor(RGB(0, 0, 0)),
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)), m_updateLevel(0),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::CColorString(LPCTSTR lpch, int nLength, BOOL bUseThread) : CStringEx( lpch, nLength ), m_bkgThread(NULL),
	m_defaultColor(RGB(0, 0, 0)), 
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)), m_updateLevel(0),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::CColorString(const unsigned char* psz, BOOL bUseThread) : CStringEx( psz ), m_bkgThread(NULL),
	m_defaultColor(RGB(0, 0, 0)), 
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::CColorString(LPCWSTR lpsz, BOOL bUseThread) : CStringEx( lpsz ), m_bkgThread(NULL),
	m_defaultColor(RGB(0, 0, 0)), 
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)), m_updateLevel(0),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::CColorString(LPCSTR lpsz, BOOL bUseThread) : CStringEx( lpsz ), m_bkgThread(NULL),
	m_defaultColor(RGB(0, 0, 0)),
	m_dQuoteColor(RGB(0, 0, 0)), m_sQuoteColor(RGB(0, 0, 0)), m_updateLevel(0),
	CThreadLock(), m_bUseThread(bUseThread), m_kPos(0), m_cPos(0), m_qPos(0)
{
	//TRACE("ColorString() - %x  File: %s, Line: %d\r\n", this, __FILE__, __LINE__);
}

CColorString::~CColorString()
{
	if (m_bkgThread != NULL) {
		m_bkgThread->SuspendThread();
		delete m_bkgThread;
	}

	for (int i = 0; i < KeywordHashSize; i++) {
		for (int j = 0; j < m_keywordTable[i].GetSize(); j++) {
			if (m_keywordTable[i][j] != NULL) delete m_keywordTable[i][j];
		}
	}

	for (i = 0; i < m_comment.GetSize(); i++) {
		if (m_comment[i] != NULL) delete m_comment[i];
	}

	for (i = 0; i < m_quote.GetSize(); i++) {
		if (m_quote[i] != NULL) delete m_quote[i];
	}
}

void CColorString::AddUpdateTarget(CColorStringUpdate* update)
{
	for (int i = 0; i < m_update.GetSize(); i++) {
		if (m_update[i] == update) return;
	}
	m_update.Add(update);
}

BOOL CColorString::AddKeyword(const CString& keyword, COLORREF color /*= RGB(0, 0, 200)*/) 
{
	CKeywordInfo* pKey = new CKeywordInfo(keyword, color);
	if (pKey != NULL) {
		m_keywordTable[Hash(keyword)].Add(pKey);
	}
	return pKey != NULL;
}

BOOL CColorString::AddComment(const CString& begin /*= _T("//")*/, const CString& end /*= _T("\n")*/, COLORREF color /*= RGB(0, 200, 0)*/)			
{
	CCommentInfo* pComment = new CCommentInfo(begin, end, color);
	if (pComment != NULL) {
		m_comment.Add(pComment);
	}
	return pComment != NULL;
}

BOOL CColorString::AddQuote(const CString & begin, const CString & end, COLORREF color)
{
	CQuoteInfo* pQuote = new CQuoteInfo(begin, end, color);
	if (pQuote != NULL) {
		m_quote.Add(pQuote);
	}
	return pQuote != NULL;
}

void CColorString::SetDefaults(COLORREF color /*= RGB(0, 0, 0)*/, COLORREF sQuoteColor /*= RGB(0, 0,0)*/, COLORREF dQuoteColor /*= RGB(0, 0, 0)*/)					
{
	m_defaultColor = color; 
	m_sQuoteColor = sQuoteColor;
	m_dQuoteColor = dQuoteColor;
}

COLORREF CColorString::GetColor(long index)							
{
	COLORREF retval = m_defaultColor;
	if (index >= 0 && index < m_color.GetSize()) {
		retval = m_color[index];
	}
	return retval;
}

void CColorString::BeginUpdate(long pos, long len)
{
	if (m_updateLevel <= 0) m_updatePos = GetLength();
	m_updateLevel++;
}

void CColorString::EndUpdate(long pos, long len)	{
	m_updateLevel--;
	if (pos < m_updatePos) m_updatePos = pos;
	if (m_updateLevel == 0) Process(m_updatePos);
	return;
}

BOOL IsToken(TCHAR c, BOOL bCharOnly)
{
	return !((!bCharOnly && IsWhite(c)) || (bCharOnly && !(IsAlphaNum(c) || c == '#')));
}

long CColorString::GetToken(CString& token, long pos, BOOL bCharOnly)
{
	long	retval = -1;
	TCHAR	c;

	// Skip whitespace
	while (pos < GetLength() && !IsToken(GetAt(pos), bCharOnly)) {
		pos++;
	}

	// Save start position
	retval = pos;

	// Fill in token
	token = _T("");
	if (pos < GetLength()) {
		for (c = GetAt(pos); IsToken(c, bCharOnly); c = GetAt(++pos)) {
			token += c;
			if (pos+1 >= GetLength()) break;
		}
	}
	
	// return start position
	return retval;
}

long CColorString::GetComment(const CString& beginToken, const CString& endToken, long& commentLen, long pos)
{
	long len = GetLength();
	long beginTokenLen = beginToken.GetLength();
	long endTokenLen = endToken.GetLength();

	commentLen = 0;
	if (!beginToken.IsEmpty() && !endToken.IsEmpty()) {
		// Skip Whitespace
		for (int i = pos; i < len && IsWhite(GetAt(i)); i++) 
			;

		// Find Comment
		if (i/*+beginTokenLen*/ < len && Mid(i, beginTokenLen) == beginToken) {
			// Find close of comment
			for (int j = i+beginTokenLen; j+endTokenLen < len; j++) {
				if (Mid(j, endTokenLen) == endToken) {
					commentLen = (j+endTokenLen)-i; 
					return i;
				}
			}

			// Handle case where single line comments goes to EOF
			if (j+endTokenLen >= len && endToken == _T("\n")) {
				commentLen = len - i;
				return i;
			}
		}
	}

	return -1;
}

long CColorString::GetQuote(const CString & beginToken, const CString & endToken, long & commentLen, long pos)
{
	long len = GetLength();
	long beginTokenLen = beginToken.GetLength();
	long endTokenLen = endToken.GetLength();
	long i = pos;

	commentLen = 0;
	if (!beginToken.IsEmpty() && !endToken.IsEmpty()) {
		// Find Quote
start:
		// Skip Whitespace
		for (; i < len && IsWhite(GetAt(i)); i++) 
			;

		if (i < len && Mid(i, beginTokenLen) == beginToken) {
			// Find close of comment
			for (int j = i+beginTokenLen; j+endTokenLen < len; j++) {
				if (GetAt(j) == '\n') {
					i++;
					goto start;
				}
				if (Mid(j, endTokenLen) == endToken) {
					commentLen = (j+endTokenLen)-i; 
					return i;
				}
			}

			// Handle case where single line comments goes to EOF
			if (j+endTokenLen >= len && endToken == _T("\n")) {
				commentLen = len - i;
				return i;
			}
		}
	}

	return -1;
}

CKeywordInfo* CColorString::KeywordLookup(const CString& token)
{
	CArray<CKeywordInfo*, CKeywordInfo*>& keywordTable = m_keywordTable[Hash(token)];
	long size = keywordTable.GetSize();

	for (int i = 0; i < size; i++) {
		if (token == keywordTable[i]->Keyword()) {
			return keywordTable[i];
		}
	}
	return NULL;
}

long CColorString::Offset2Line(long pos)
{
	long prev, cur, i = 1, len = m_lineOffset.GetSize();

	if (pos <= 0) return 0;

	if (m_lineOffset.GetSize() > 0) {
		prev = m_lineOffset[0];
		for (i = 1; i < len; i++) {
			cur = m_lineOffset[i];
			if (pos >= prev && pos < cur) {
				return i-1;
			}
			prev = cur;
		}
	}

	return len-1;
}

void CColorString::Reset(long pos /*= 0*/)
{
	ThreadLock();
	m_lineOffset.SetSize(0);
	m_lineOffset.Add(0);
	for (int i = 0; i < GetLength(); i++) {
		if (GetAt(i) == '\n') m_lineOffset.Add(i+1);
	}
	ThreadUnlock();

	KeywordPos(0); CommentPos(0); QuotePos(0);

	m_color.SetColor(m_defaultColor, pos, GetLength()-pos);

	if (!m_bUseThread) 
	{
		ParseKeywords(m_color);
		ParseQuotes(m_color);
		ParseComments(m_color);
	}
}

⌨️ 快捷键说明

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