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

📄 syneditview.cpp

📁 C 语言编辑器(具有编辑器
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	CPoint p1, p2;
	CRichEditCtrl &SynCtrl = GetRichEditCtrl();

	SynCtrl.SetWindowText(_T("8"));  
	p1 = SynCtrl.GetCharPos(0);
	p2 = SynCtrl.GetCharPos(1);
	m_nCharNumberWidth = p2.x - p1.x;	//数字宽度

	SynCtrl.SetWindowText(_T(" "));  
	p1 = SynCtrl.GetCharPos(0);
	p2 = SynCtrl.GetCharPos(1);
	m_nCharSpaceWidth = p2.x - p1.x;	//空格宽度
	
	SynCtrl.SetWindowText(_T("\t"));  
	p1 = SynCtrl.GetCharPos(0);	
	p2 = SynCtrl.GetCharPos(1);
	m_nCharTabWidth = p2.x - p1.x;	//TAB宽度

	SynCtrl.SetWindowText(_T("\n     "));
	CPoint ps, pe;
	p1 = SynCtrl.GetCharPos(0);
	p2 = SynCtrl.GetCharPos(3);
	//m_nLineHeight = p2.y - p1.y; //行高
	m_nLineHeight = 16;

	ShowWindow(TRUE);
}


LRESULT CSynEditView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	switch (message) 
	{
	case WM_PAINT:
		{
			CPaintDC dc(this); // device context for painting
			DrawSynEditView();
			return FALSE;
		}
	case WM_PASTE:
		{
			//处理粘贴的情况,当用户粘入rtf格式时,只取出其中的文本,否则直接粘可能会引起文本错位
			char * buffer;
			if(!OpenClipboard())
				return FALSE;	
			buffer = (char*)::GetClipboardData(CF_TEXT);
			CloseClipboard(); 
			CString str = buffer;
			
			CRichEditCtrl &edit = GetRichEditCtrl();
			CHARRANGE cr;
			edit.GetSel(cr); 	

			SetParseCookieZeroFromGivenLine(edit.LineFromChar(cr.cpMin)); //粘贴时需重置解析缓冲区
			edit.ReplaceSel(str, TRUE); 
			return FALSE;
		}
	case WM_SIZE:
		{			
			CRichEditView::WindowProc(message, wParam, lParam);			
			
			GetParent()->GetClientRect(&m_rcClient); 
			MoveWindow(&m_rcClient);

			if (m_pCacheBitmap != NULL)
			{
				delete m_pCacheBitmap;
				m_pCacheBitmap = NULL;
			}

			return FALSE;
		}
	default:
		return CRichEditView::WindowProc(message, wParam, lParam);
	}
}

void CSynEditView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{	
	InvalidateRect(m_rcClient, FALSE);
	m_bAllowDraw = FALSE;
	CRichEditView::OnHScroll(nSBCode, nPos, pScrollBar);
	m_bAllowDraw = TRUE;
	ValidateRect(m_rcClient);
	
	//判断用户是否正在拖动水平滚动条
	SCROLLINFO si;
	si.cbSize = sizeof(si);
	GetScrollInfo(SB_HORZ, &si);
	if(nSBCode==SB_THUMBPOSITION || nSBCode==SB_THUMBTRACK)
		m_bTracking = TRUE;
	else
		m_bTracking = FALSE;
	
	SendMessage(WM_PAINT, 0, 0);	
}

void CSynEditView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	InvalidateRect(m_rcClient, FALSE);
	m_bAllowDraw = FALSE;
	CRichEditView::OnVScroll(nSBCode, nPos, pScrollBar);
	m_bAllowDraw = TRUE;
	ValidateRect(m_rcClient);
	SendMessage(WM_PAINT, 0, 0);
}



/*	dwCookie		-	传入前一行的解析结果,如果前一行是多行注释的开始
						或者前一行是一软回车时有用
	strLine			-	被解析的一行字符串
	ColorInfo		-	解析后的颜色值,指定是关键字、字符串、注释还是正常的字符颜色
	nActualItems	-	strLine被解析后的块数

	函数返回解析结果,指示解析后当前行是处于字符串中、注释中、多行注释中还是正常状态
	nActualItems	-	返回当前行分解的字符串块数
*/
DWORD CSynEditView::ParseLine(	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;
}



//判断给定的串是否是数字变量
BOOL CSynEditView::IsNumber(CString &strReadyToTest)
{
		
	int nLength = strReadyToTest.GetLength(); 
	{
		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;
				}
			}

	
	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;
}

⌨️ 快捷键说明

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