📄 syneditview.cpp
字号:
[功能]:根据当前语言解析一行字符串。
[入口参数]:
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 + -