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

📄 syneditview.cpp

📁 C 语言编辑器(具有编辑器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		DWORD dwCookie = 0;
		if (L > 0) {
			dwCookie = m_pdwParseCookies[L - 1];
			if(bRealReturn )
				dwCookie &= COOKIE_EXT_COMMENT;
		}
		ASSERT(dwCookie != (DWORD) -1);
		bRealReturn = GetLineString(L, strLine);
		m_pdwParseCookies[L] = ParseLine(dwCookie, strLine, NULL, nBlocks);
		ASSERT(m_pdwParseCookies[L] != (DWORD) -1);
		L ++;
	}

	return m_pdwParseCookies[nLineIndex];
}

//取指定行文本,返回指定该行在WrapToWindow模式下是否为硬回车
//[注]在WrapToWindow模式下如果一行过长则会被分割成多行,此时只有最后一行才是硬回车
BOOL CSynEditView::GetLineString(int nLine, CString &strLine)
{
	strLine = _T("");
	CRichEditCtrl &SynCtrl=GetRichEditCtrl();
	if(nLine > m_nLineCount - 1 || nLine < 0) 
		return TRUE;
		
	int nTemp = SynCtrl.LineIndex(nLine);
	nTemp = SynCtrl.LineLength(nTemp) * sizeof(WCHAR);
	if(nTemp<=1) {
		strLine=_T(" ");
		return TRUE;
	}
	nTemp += 4 * sizeof(WCHAR); //尽量多留点空
	int nLen = SynCtrl.GetLine(nLine, strLine.GetBuffer(nTemp), nTemp);  		
	strLine.ReleaseBuffer(); 
	BOOL bRealReturn;
	
	if(nLen > strLine.GetLength())
		nLen = strLine.GetLength();
	if(nLen>=1 && strLine[nLen-1]==0xd ) {
		strLine = strLine.Left(--nLen);  
		bRealReturn=TRUE;
	}
	else  {
		strLine = strLine.Left(nLen);  
		bRealReturn=FALSE;
	}
	strLine += _T(" ");

	return bRealReturn;
}

//重置语法解析缓冲区
void CSynEditView::ResetParseCookie()
{
	m_nParseArraySize = 0;
	m_nHorzPos = 0;

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

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


int CSynEditView::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
	if (CRichEditView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	GetRichEditCtrl().HideSelection(TRUE, FALSE); 

	return 0;
}


void CSynEditView::CalcSelection()
{
	CRichEditCtrl &SynCtrl = GetRichEditCtrl();	
	CHARRANGE cr;
	SynCtrl.GetSel( cr ); 
	m_ptSelStart = SynCtrl.GetCharPos( cr.cpMin ); 
	m_ptSelEnd = SynCtrl.GetCharPos( cr.cpMax );
}


//根据给定点的x,y坐标判断该点是否在选定区域内


BOOL CSynEditView::IsStrInSelection(int ptLeft, int ptTop)
{
	if( m_ptSelStart == m_ptSelEnd ) //如果没有选定直接返回FALSE
		return FALSE;

	CPoint ptSelStart = m_ptSelStart;
	CPoint ptSelEnd = m_ptSelEnd;

	//考虑边界的情况,将选定区域左右延伸半个字符宽度
	ptSelStart.x -= m_nCharNumberWidth/2;
	ptSelEnd.x += m_nCharNumberWidth/2;

	if( ptSelStart.y == ptSelEnd.y ) { //如果选定行为单行
		if( ptTop != ptSelStart.y ) //如果光标不在该行
			return FALSE;
		else {
			if( ptLeft >= ptSelStart.x && ptLeft <= ptSelEnd.x)
				return TRUE;
			else
				return FALSE;
		}
	}
	else {
		if( ptTop == ptSelStart.y ) { //如果当前位置在选取定行的第一行
			if( ptLeft <  ptSelStart.x )
				return FALSE;
			else
				return TRUE;
		}
		if( ptTop == ptSelEnd.y ) { //如果当前位置在选定行的最后一行
			if( ptLeft < ptSelEnd.x )
				return TRUE;
			else
				return FALSE;
		}
		else if( ptTop > ptSelStart.y && ptTop < ptSelEnd.y ) //如果当前位置在选定行的中间
			return TRUE;
		else
			return FALSE;
	}
}

//判断给定的字符是否在选择区域内,并画出该字符串
void CSynEditView::JudgeInSeletioAndDrawText(CDC *cacheDC, CRect &rcLine, CString &str, COLORREF clrBkColor, COLORREF clrText)
{
	COLORREF clrSelText;

	int nFormat = DT_LEFT|DT_NOPREFIX|DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE|DT_RTLREADING;

	CSize size = cacheDC->GetTextExtent(str); 
	if( !IsSelectionInStr(rcLine.left, size.cx, rcLine.top) ) {
		BOOL bStrLeft = IsStrInSelection( rcLine.left, rcLine.top );
		BOOL bStrRight = IsStrInSelection( rcLine.left + size.cx, rcLine.top );
		
		if( !bStrLeft && !bStrRight ) { //如果str的左右都不在选定区域内			
			cacheDC->SetBkColor( clrBkColor ); 
			cacheDC->SetTextColor( clrText );
			cacheDC->TextOut( rcLine.left, rcLine.top, str);
			rcLine.OffsetRect( size.cx, 0 );
			return;
		}
		else if( bStrLeft && bStrRight ) { //如果str的左右都在选定区域内
			CRect rect(rcLine);
			rect.right = rect.left + size.cx;
			cacheDC->FillSolidRect( &rect, m_clrBKSelText ); 
			clrSelText = RGB( 255-GetRValue(clrText), 255-GetGValue(clrText), 255-GetBValue(clrText) );
			cacheDC->SetTextColor( clrSelText );
			cacheDC->TextOut( rcLine.left, rcLine.top, str);
			rcLine.OffsetRect( size.cx, 0 );
			return;
		}
	}
	//如果str部分在选定区域内, 或者选定区域在str内执行以下代码
	CString strChar;
	for( int nChar = 0; nChar < str.GetLength(); nChar++ ) {
		strChar = str.Mid( nChar, 1 );
		size = cacheDC->GetTextExtent( strChar ); 
		BOOL bStrLeft = IsStrInSelection( rcLine.left, rcLine.top );
		BOOL bStrRight = IsStrInSelection( rcLine.left + size.cx, rcLine.top );
		if( bStrLeft && bStrRight ) { 
			CRect rect(rcLine);
			rect.right = rect.left + size.cx;
			cacheDC->FillSolidRect( &rect, m_clrBKSelText ); 
			clrSelText = RGB( 255-GetRValue(clrText), 255-GetGValue(clrText), 255-GetBValue(clrText) );
			cacheDC->SetTextColor( clrSelText );
		}
		else {
			cacheDC->SetBkColor( clrBkColor ); 
			cacheDC->SetTextColor( clrText );
		}
		cacheDC->TextOut( rcLine.left, rcLine.top, strChar);
		rcLine.OffsetRect( size.cx, 0 );
	}
}

//计算水平滚动位置,以便在水平滚动时可以正确显示
void CSynEditView::CalcHorzScrollPos()
{
	if(m_nWordWrap == WrapToWindow)
	{
		m_nHorzPos = 0;
		return;
	}

	SCROLLINFO si;
	si.cbSize = sizeof(si);
	GetScrollInfo(SB_HORZ, &si);
	
	if( m_bTracking ) 
		m_nHorzPos = si.nTrackPos;
	else
		m_nHorzPos = si.nPos;
}

//在RichEditView上画出内容
void CSynEditView::DrawSynEditView()
{
	if(!m_bAllowDraw)
 		return;

  	CRichEditCtrl &SynCtrl = GetRichEditCtrl();
	m_nLineCount = SynCtrl.GetLineCount(); 
 	m_nCurrentLine = GetCurrentLine();

 	if (m_pdwParseCookies != NULL)
 	{
 		if (m_nParseArraySize != m_nLineCount)
 		{
			int nCurrentLine = m_nCurrentLine;
			if(m_nParseArraySize < m_nLineCount) 
			{
				nCurrentLine = m_nParseArraySize + m_nCurrentLine - m_nLineCount; 
				if(nCurrentLine<0)
					nCurrentLine = m_nCurrentLine;
			}
			if(m_nCurrentLine>m_nLineCount)
				nCurrentLine=0;
 			//	重新分配缓冲区大小
 			DWORD *pdwNewArray = new DWORD[m_nLineCount];
 			if (m_nCurrentLine > 0)
 				memcpy(pdwNewArray, m_pdwParseCookies, sizeof(DWORD) * nCurrentLine);
 			
			delete m_pdwParseCookies;
 			m_nParseArraySize = m_nLineCount;
 			m_pdwParseCookies = pdwNewArray;
			memset(m_pdwParseCookies + nCurrentLine, 0xff, sizeof(DWORD) * (m_nParseArraySize - nCurrentLine));
 		}
 	}
 	
 	CDC *pdc=GetDC();
 	CDC cacheDC;
 	VERIFY(cacheDC.CreateCompatibleDC(pdc));
 	if (m_pCacheBitmap == NULL)
 	{
 		m_pCacheBitmap = new CBitmap;
 		m_pCacheBitmap->CreateCompatibleBitmap(pdc, m_rcClient.Width(), m_rcClient.Height());  //nLineHeight);
 	}
 	CBitmap *pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);
 
	CalcSelection();
	CalcHorzScrollPos();

	CString str;
	int nLine = SynCtrl.GetFirstVisibleLine();
 	if(nLine==0)
		m_bRealReturn = TRUE;
	else
		m_bRealReturn = GetLineString(nLine-1, str);

	CRect rcEditor(m_rcClient);
	//将显示区域背景色画好
	cacheDC.FillSolidRect(&rcEditor, m_clrBkColor); 	

	rcEditor.left = m_nLeftMargin - m_nHorzPos - 1;
	int nLinesTop = GetLinesTop(nLine); //第一行要计算好偏移值,因为第一行可能只显示部分
	rcEditor.top = nLinesTop + m_nTopMargin;
	rcEditor.bottom = rcEditor.top + m_nLineHeight;	

	int nNumberToDraw = 0;
	while(rcEditor.top <= m_rcClient.bottom ) 
	{
		if(nLine > m_nLineCount-1)
			break;
		//画出一行文本
		DrawSingleLineColorText(&cacheDC, nLine++, rcEditor);
		//重新定位下一行的位置
		rcEditor.OffsetRect(0, m_nLineHeight );
	}

	//将缓冲画布cacheDC上的内容复制到RichEditView视上
	pdc->BitBlt(m_rcClient.left, m_rcClient.top, m_rcClient.Width(), m_rcClient.Height(), &cacheDC, 0, 0, SRCCOPY);
 	
 	cacheDC.SelectObject(pOldBitmap);
 	cacheDC.DeleteDC();	
}



/*	判断选择选区域是否在字符串所处位置的内部
[入口参数]:
	nFromHere	-	待测试的字符串的起始位置
	nStrWidth	-	待测试的字符串的宽度
	nTop		-	待测试的字符串的顶部位置
[返回值]:
	TRUE	-	选定区域在字符串所处位置的内部
	FLASE	-	选定区域不在字符串所处位置的内部
*/
BOOL CSynEditView::IsSelectionInStr(int nFromHere, int nStrWidth, int nTop)
{
	if( m_ptSelStart == m_ptSelEnd )
		return FALSE;

	if( m_ptSelStart.y != m_ptSelEnd.y )  //如果选定行不为单行,返回,因为字符不可能跨行
		return FALSE;

	if( m_ptSelStart.y != nTop )  //如果待测试行的顶部不等于选定行的顶部则返回
		return FALSE;

	if( (m_ptSelStart.x > nFromHere) && (m_ptSelEnd.x < nFromHere + nStrWidth) )
		return TRUE;
	else
		return FALSE;
}


COLORREF CSynEditView::GetColor(int nColorIndex)
{
	switch(nColorIndex) 
	{
	case COLORINDEX_NUMBER:
		return m_clrNumberColor;
	case COLORINDEX_BK:
		return m_clrBkColor;
	case COLORINDEX_COMMENT:
		return m_clrCommentColor;
	case COLORINDEX_SYNTAX:
		return m_clrSyntaxColor;
	case COLORINDEX_NORMAL:
		return m_clrNormalColor;
	case COLORINDEX_STRING:
		return m_clrStringColor;
	case COLORINDEX_CHAR:
		return m_clrCharColor;
	default:
		return m_clrNormalColor;
	}
}

//这个函数的作用是在粘贴时重置nParseArraySize的语法解析缓冲区
void CSynEditView::SetParseCookieZeroFromGivenLine(int nParseArraySize)
{
	memset(m_pdwParseCookies + nParseArraySize, 0xff, sizeof(DWORD) * (m_nParseArraySize - nParseArraySize));
}


//判断给定的串是否是语法关键字
BOOL CSynEditView::IsSynWord(CString &strReadyToTest)
{
	BOOL bMatch;

	for(int i=0; i<m_strArrayKeyWords.GetSize(); i++) 
	{

			bMatch = (strReadyToTest.CompareNoCase(m_strArrayKeyWords[i])==0);

		if(bMatch)
			return TRUE;
	}
	return FALSE;
}

//装入指定语言的语法关键字
void CSynEditView::LoadSynWord() 
{
	CString strAllSynWord;
	m_strArrayKeyWords.RemoveAll();
	

	strAllSynWord = _T(" #define,#else,#elif,#elseif,#endif,#error,#if,#ifdef,#ifndef,#include,#pragma,#undef,__asm,__based,__cdecl,__declspec,__except,__fastcall,__finally,__inline,__int16,__int32,__int64,__int8,__leave,__multiple_inheritance,__pascal,__single_inheritance,__stdcall,__try,__uuidof,__virtual_inheritance,_asm,_cdecl,_fastcall,_pascal,_stdcall,afx_msg,auto,bool,break,case,catch,char,class,code_seg,const,const_cast,continue,default,defined,delete,dllexport,dllimport,do,double,dynamic_cast,else,enum,explicit,extern,false,float,for,friend,goto,if,inline,int,interface,long,main,mutable,naked,namespace,new,off,on,once,operator,pack,pascal,pop,private,protected,public,push,register,reinterpret_cast,return,short,signed,sizeof,static,static_cast,struct,switch,template,this,thread,throw,true,try,typedef,typeid,typename,union,unsigned,using,uuid,virtual,void,volatile,while,wmain,xalloc,");

	CString strTemp;
	int nPosPrior = 0;
	int nPos;	

	nPos = strAllSynWord.Find(_T(","), nPosPrior);
	while(nPos!=-1)
	{
		strTemp = strAllSynWord.Mid(nPosPrior+1 , nPos - nPosPrior - 1);
		m_strArrayKeyWords.Add(strTemp);
		
		nPosPrior = nPos;
		nPos = strAllSynWord.Find(_T(","),  nPosPrior + 1);			
	}
}


void CSynEditView::CalcEditorInfo()
{
	ShowWindow(FALSE);

⌨️ 快捷键说明

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