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

📄 syneditview.cpp

📁 一个执行SYBASE SQL语言的工具示例源代码 功能特色 1 语法颜色显示 2 执行DDL语句 3 在执行SQL Select 语句时使用异步多线程处理方式
💻 CPP
📖 第 1 页 / 共 3 页
字号:
[功能]:根据当前语言解析一行字符串。
[入口参数]:
	dwCookie		-	传入前一行的解析结果,如果前一行是多行注释的开始
						或者前一行是一软回车时有用
	strLine			-	被解析的一行字符串
	ColorInfo		-	解析后的颜色值,指定是关键字、字符串、注释还是正常的字符颜色
	nActualItems	-	strLine被解析后的块数
[返回值]:
	函数返回解析结果,指示解析后当前行是处于字符串中、注释中、多行注释中还是正常状态
	nActualItems	-	返回当前行分解的字符串块数
/*//////////////////////////////////////////////////////////////////////////////////////
DWORD CSynEditView::ParseLine(	DWORD dwCookie, 
								CString &strLine, 
								COLORINFO *ColorInfo, 
								int &nActualItems)
{
	if(ColorInfo==NULL) 
		return dwCookie;

	//根据当前语言选择对应的解析模块
	switch (m_nLanguage) {
	case _CPP:
		return ParseLineForCpp(dwCookie, strLine, ColorInfo, nActualItems);
	case _BASIC:
		return ParseLineForBasic(dwCookie, strLine, ColorInfo, nActualItems);
	default: //纯文本
		return dwCookie;
	}
}

//选择语言
void CSynEditView::SelectLanguage(int nLanguage)
{
	ASSERT(this);

	m_nLanguage = nLanguage;
	LoadSynWord(m_nLanguage);
	PostMessage(WM_PAINT);
}


//解析C++语法
DWORD CSynEditView::ParseLineForCpp(	DWORD dwCookie, 
										CString &strLine, 
										COLORINFO *ColorInfo, 
										int &nActualItems)
{
	int nLength = strLine.GetLength(); 
	if(nLength == 0)
		return dwCookie;

	int nIdentBegin = -1;
	BOOL bRedefineBlock = TRUE;
	BOOL bDecIndex  = FALSE;
	BOOL bIsInTheControlChar = FALSE;
	//上一行之变量指示是否在\的控制中, 初始化时必须为FALSE
	//控制字符\的含义:参考下列语句:
	//CString strTemp = _T("\"");
	//第二个引号并不表示字符串变量的结束,而是表明这是在定义"这个字符串,
	//这是因为它的前面有控制字符\,第三个引号才表示定义字符串变量的结束。

	for (int I = 0; ; I++)
	{
		if (bRedefineBlock) //如果开始定义颜色块则向下做
		{
			int nPos = I;
			if (bDecIndex)
				nPos--;
			if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
			{
				DEFINE_BLOCK(nPos, COLORINDEX_COMMENT);
			}
			else {
				if (dwCookie & COOKIE_STRING)
				{
					DEFINE_BLOCK(nPos, COLORINDEX_STRING);
				}
				else
				{
					DEFINE_BLOCK(nPos, COLORINDEX_NORMAL);
				}
			}
			bRedefineBlock = FALSE;
			bDecIndex      = FALSE;
		}
		
		if (I == nLength)
			goto Out;
		
		if (dwCookie & COOKIE_COMMENT)
		{
			DEFINE_BLOCK(I, COLORINDEX_COMMENT);
			dwCookie |= COOKIE_COMMENT;
			goto Out;
		}
		
		if (dwCookie & COOKIE_STRING)
		//如果当前正处于字符串变量中,则应检查是否有结束字符串变量的字符串
		{
			if(I > 0) 
			{
				if(strLine[I-1] != '\\')
				{
					if(strLine[I] != '\\') 
						bIsInTheControlChar = FALSE;
					else
						bIsInTheControlChar = TRUE;
				}
				else 
				{
					if(strLine[I] == '\\') 
					{
						if(!bIsInTheControlChar)
							bIsInTheControlChar = TRUE;
						else
							bIsInTheControlChar = FALSE;
					}
				}
			}
			
			if(strLine[I]==_T('\"') && !bIsInTheControlChar) 
			{
				dwCookie &= ~COOKIE_STRING;
				bRedefineBlock = TRUE;
			}
			goto CmpNextChar;
		}
		
		if (dwCookie & COOKIE_CHAR)
		//如果当前正处于字符变量中,则应检查是否有结束字符变量的字符串
		{
			if(I > 0) {
				if(strLine[I-1] != '\\') 
				{
					if(strLine[I] != '\\') 
						bIsInTheControlChar = FALSE;
					else
						bIsInTheControlChar = TRUE;
				}
				else 
				{
					if(strLine[I] == '\\') 
					{
						if(!bIsInTheControlChar)
							bIsInTheControlChar = TRUE;
						else
							bIsInTheControlChar = FALSE;
					}
				}
			}
			
			if(strLine[I]==_T('\'') && !bIsInTheControlChar) 
			{
				dwCookie &= ~COOKIE_CHAR;
				bRedefineBlock = TRUE;
			}
			goto CmpNextChar;
		}

		if (dwCookie & COOKIE_EXT_COMMENT)
		//如果当前正处于多行注释中,则应检查是否有结束多行注释的字符串
		{
			if(I >= 1 && strLine[I-1]==_T('*') && strLine[I]==_T('/'))
			{
				dwCookie &= ~COOKIE_EXT_COMMENT;
				bRedefineBlock = TRUE;
			}
			
			goto CmpNextChar;
		}

	
		if(I >= 1 && strLine[I-1]==_T('/') && strLine[I]==_T('/'))
		//处理单行注释
		{
			DEFINE_BLOCK(I - 1, COLORINDEX_COMMENT);
			dwCookie |= COOKIE_COMMENT;
			goto Out; //只要发现有单行注释的字符串则退出
		}

		if( strLine[I]==_T('\"') )
		//处理字符串变量
		{
			DEFINE_BLOCK(I, COLORINDEX_STRING);
			dwCookie |= COOKIE_STRING;
			goto CmpNextChar;
		}
		
		if( strLine[I]==_T('\'') )
		//处理字符变量
		{
			DEFINE_BLOCK(I, COLORINDEX_CHAR);
			dwCookie |= COOKIE_CHAR;
			goto CmpNextChar;
		}

		if( I>=1 && strLine[I-1]==_T('/') && strLine[I]==_T('*'))
		//处理多行注释
		{
			DEFINE_BLOCK(I - 1, COLORINDEX_COMMENT);
			dwCookie |= COOKIE_EXT_COMMENT;
			if ( ++I >= nLength) // 考虑"/*/"的情况
				goto Out;
			goto CmpNextChar;
		}
		
		//C++中,字符串由字母和下划线_组成,我们扩展来包含#以处理类似#if的关键字
		if (isalnum(strLine[I]) || strLine[I] == '_' || strLine[I] == '#')
		{
			if (nIdentBegin == -1)
				nIdentBegin = I;
		}
		else
		{
			//分解出一个字符串,此时判断是关键字还是数字
			if (nIdentBegin >= 0)
			{
				CString strtmp= strLine.Mid(nIdentBegin, I - nIdentBegin); 
				if (IsSynWord(strtmp))
				{
					DEFINE_BLOCK(nIdentBegin, COLORINDEX_SYNTAX);
				}
				else if (IsNumber(strtmp))
				{
					DEFINE_BLOCK(nIdentBegin, COLORINDEX_NUMBER);
				}
				bRedefineBlock = TRUE;
				bDecIndex = TRUE;
				nIdentBegin = -1;
			}
		}
CmpNextChar:;
	}
	
Out: //当遇到单行注释时会直接跳到这儿
	//处理剩下的字符串
	if (nIdentBegin >= 0)
	{
		CString strtmp = strLine.Mid(nIdentBegin, I - nIdentBegin); 
		if (IsSynWord(strtmp))
		{
			DEFINE_BLOCK(nIdentBegin, COLORINDEX_SYNTAX);
		}
		else if (IsNumber(strtmp))
		{
			DEFINE_BLOCK(nIdentBegin, COLORINDEX_NUMBER);
		}
	}

	return dwCookie;
}

//解析VB语法(注意:VB没有多行注释和控制字符)
DWORD CSynEditView::ParseLineForBasic(	DWORD dwCookie, 
										CString &strLine, 
										COLORINFO *ColorInfo, 
										int &nActualItems)
{	
	int nLength = strLine.GetLength(); 
	if(nLength == 0)
		return dwCookie;

	int nIdentBegin = -1;
	BOOL bRedefineBlock = TRUE;
	BOOL bDecIndex  = FALSE;

	for (int I = 0; ; I++)
	{
		if (bRedefineBlock) //如果开始定义颜色块向下做
		{
			int nPos = I;
			if (bDecIndex)
				nPos--;
			if (dwCookie & COOKIE_COMMENT)
			{
				DEFINE_BLOCK(nPos, COLORINDEX_COMMENT);
			}
			else 
			{
				if (dwCookie & COOKIE_STRING)
				{
					DEFINE_BLOCK(nPos, COLORINDEX_STRING);
				}
				else
				{
					DEFINE_BLOCK(nPos, COLORINDEX_NORMAL);
				}
			}
			bRedefineBlock = FALSE;
			bDecIndex      = FALSE;
		}
		
		if (I == nLength)
			goto Out;
		
		if (dwCookie & COOKIE_COMMENT)
		{
			DEFINE_BLOCK(I, COLORINDEX_COMMENT);
			dwCookie |= COOKIE_COMMENT;
			goto Out;
		}
		
		if (dwCookie & COOKIE_STRING)
		//如果当前正处于字符串变量中,则应检查是否有结束字符串变量的字符串
		{			
			if(strLine[I]==_T('\"')) 
			{
				dwCookie &= ~COOKIE_STRING;
				bRedefineBlock = TRUE;
			}
			goto CmpNextChar;
		}
		
		if (dwCookie & COOKIE_CHAR)
		//如果当前正处于字符变量中,则应检查是否有结束字符变量的字符串
		{			
			if(strLine[I]==_T('\'')) 
			{
				dwCookie &= ~COOKIE_CHAR;
				bRedefineBlock = TRUE;
			}
			goto CmpNextChar;
		}
	
		if(strLine[I]==_T('\''))
		{
		//处理单行注释
			DEFINE_BLOCK(I , COLORINDEX_COMMENT);
			dwCookie |= COOKIE_COMMENT;
			goto Out; //只要发现有单行注释的字符串则退出
		}

		if( strLine[I]==_T('\"') )
		{
		//处理字符串变量
			DEFINE_BLOCK(I, COLORINDEX_STRING);
			dwCookie |= COOKIE_STRING;
			goto CmpNextChar;
		}
		
		if( strLine[I]==_T('\'') )
		//处理字符变量
		{
			DEFINE_BLOCK(I, COLORINDEX_CHAR);
			dwCookie |= COOKIE_CHAR;
			goto CmpNextChar;
		}
		
		if (isalnum(strLine[I]) || strLine[I] == '_' || strLine[I] == '#')
		{
			if (nIdentBegin == -1)
				nIdentBegin = I;
		}
		else
		{
			if (nIdentBegin >= 0)
			{
				CString strtmp= strLine.Mid(nIdentBegin, I - nIdentBegin); 
				if (IsSynWord(strtmp))
				{
					DEFINE_BLOCK(nIdentBegin, COLORINDEX_SYNTAX);
				}
				else if (IsNumber(strtmp))
				{
					DEFINE_BLOCK(nIdentBegin, COLORINDEX_NUMBER);
				}
				bRedefineBlock = TRUE;
				bDecIndex = TRUE;
				nIdentBegin = -1;
			}
		}
CmpNextChar:;
	}
	
Out: //当遇到单行注释时会直接跳到这儿
	if (nIdentBegin >= 0)
	{
		CString strtmp = strLine.Mid(nIdentBegin, I - nIdentBegin); 
		if (IsSynWord(strtmp))
		{
			DEFINE_BLOCK(nIdentBegin, COLORINDEX_SYNTAX);
		}
		else if (IsNumber(strtmp))
		{
			DEFINE_BLOCK(nIdentBegin, COLORINDEX_NUMBER);
		}
	}

	return dwCookie;
}


//语法解析相关函数,判断给定的串是否是当前语言的数字变量
BOOL CSynEditView::IsNumber(CString &strReadyToTest)
{
	int nLength = strReadyToTest.GetLength(); 

	switch (m_nLanguage)
	{
		case _CPP:
			{
				if (nLength > 2 && strReadyToTest[0] == _T('0') && 
					strReadyToTest[1] == _T('x'))
				{
					for (int I = 2; I < nLength; I++)
					{
						if (_istdigit(strReadyToTest[I])  ||(strReadyToTest[I] >= _T('A') && 
							strReadyToTest[I] <= _T('F')) ||(strReadyToTest[I] >= _T('a') && 
							strReadyToTest[I] <= _T('f')))
							continue;
						return FALSE;
					}
					return TRUE;
				}
			}
			break;
		case _BASIC:
			{
				if (nLength > 2 && strReadyToTest[0] == _T('&') && 
					(strReadyToTest[1] == _T('O') || strReadyToTest[1] == _T('H')))
				{
					for (int I = 2; I < nLength; I++)
					{
						if (_istdigit(strReadyToTest[I])  ||(strReadyToTest[I] >= _T('A') && 
							strReadyToTest[I] <= _T('F')) ||(strReadyToTest[I] >= _T('a') && 
							strReadyToTest[I] <= _T('f')))
							continue;
						return FALSE;
					}
					return TRUE;
				}
			}
			break;

		default:
			return FALSE;
	} 
	
	if (!_istdigit(strReadyToTest[0]))
		return FALSE;
	
	for (int I = 1; I < nLength; I++)
	{
		if (!_istdigit(strReadyToTest[I]) && strReadyToTest[I] != _T('+') &&
			strReadyToTest[I] != _T('-')  && strReadyToTest[I] != _T('.') && 
			strReadyToTest[I] != _T('e')  && strReadyToTest[I] != _T('E'))
			return FALSE;
	}

	return TRUE;
}

void CSynEditView::SetSynEditViewMargin(int nLeftMargin, int nTopMargin)
{
	m_nLeftMargin = nLeftMargin;
	m_nTopMargin = nTopMargin;

	GetClientRect(&m_rcClient);
	CRect rect(m_rcClient);
	rect.left = m_nLeftMargin;
	rect.top = m_nTopMargin;
	GetRichEditCtrl().SetRect(&rect); 
}

DWORD CALLBACK CSynEditView::EditStreamCallbackReadFromFile(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	CFile* pFile = (CFile*) dwCookie;
	ASSERT_KINDOF(CFile, pFile);

	*pcb = pFile->Read(pbBuff, cb);

	return 0;
}

int CSynEditView::GetCurLanguage()
{
	return m_nLanguage;
}

⌨️ 快捷键说明

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