SynEditView.cpp
资源名称:ceditor.rar [点击查看]
上传用户:hgtech
上传日期:2022-06-07
资源大小:4455k
文件大小:30k
源码类别:
词法分析
开发平台:
Visual C++
- #include "stdafx.h"
- #include <winver.h>
- #include <malloc.h>
- #include "SynEditView.h"
- bool flag=false;
- const COOKIE_COMMENT = 0x0002;
- const COOKIE_EXT_COMMENT = 0x0004;
- const COOKIE_STRING = 0x0008;
- const COOKIE_CHAR = 0x0010;
- const COOKIE_DKH = 0x0100;
- const COOKIE_XKH = 0x0200;
- //定义颜色块宏
- #define DEFINE_BLOCK(pos, color)
- ASSERT((pos) >= 0 && (pos) <= nLength);
- if (ColorInfo != NULL)
- {
- if (nActualItems == 0 || ColorInfo[nActualItems - 1].Pos <= (pos)) {
- ColorInfo[nActualItems].Pos = (pos);
- ColorInfo[nActualItems].Color = (color);
- nActualItems ++;
- }
- }
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CSynEditView
- IMPLEMENT_DYNCREATE(CSynEditView, CRichEditView)
- BEGIN_MESSAGE_MAP(CSynEditView, CRichEditView)
- //{{AFX_MSG_MAP(CSynEditView)
- ON_WM_CREATE()
- ON_WM_HSCROLL()
- ON_WM_VSCROLL()
- //}}AFX_MSG_MAP
- // Standard printing commands
- ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CSynEditView construction/destruction
- CSynEditView::CSynEditView()
- {
- m_clrBkColor = RGB(255, 255, 255);
- m_clrCommentColor = RGB(0, 128, 0);
- m_clrSyntaxColor = RGB(0, 0, 255);
- m_clrNormalColor = RGB(0, 0, 0);
- m_clrStringColor = RGB(200, 0, 0);
- m_clrCharColor = RGB(200, 0, 0);
- m_clrNumberColor = RGB(255, 0, 0);
- m_clrBKSelText = RGB(0, 0, 128);
- m_nTabSize = 4;
- m_nParseArraySize = 0;
- m_nLeftMargin = 1;
- m_nTopMargin = 1;
- m_bAllowDraw = TRUE;
- m_bRealReturn = TRUE;
- m_bTracking = FALSE;
- m_pdwParseCookies = NULL;
- m_rcClient = NULL;
- m_pCacheBitmap = NULL;
- }
- CSynEditView::~CSynEditView()
- {
- if (m_pCacheBitmap != NULL)
- delete m_pCacheBitmap;
- if (m_pdwParseCookies != NULL)
- delete m_pdwParseCookies;
- }
- BOOL CSynEditView::PreCreateWindow(CREATESTRUCT& cs)
- {
- //装入rich edit version 2.0
- if (LoadLibraryA("RICHED20.DLL") == NULL)
- {
- AfxMessageBox(_T("Fail to load "riched20.dll"."),
- MB_OK | MB_ICONERROR);
- PostMessage(WM_QUIT,0,0);
- return FALSE;
- }
- m_strClass = RICHEDIT_CLASSA; //for 2.0 class
- return CRichEditView::PreCreateWindow(cs);
- }
- void CSynEditView::OnInitialUpdate()
- {
- CRichEditView::OnInitialUpdate();
- SetMargins(CRect(720, 720, 720, 720));
- ResetParseCookie(); //Version 1.0.0.1加入
- LoadSynWord();
- ::GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &m_lf);
- m_lf.lfWeight = FW_NORMAL;
- m_lf.lfHeight = 0xfffffff2;
- m_lf.lfCharSet = GB2312_CHARSET;
- strcpy(m_lf.lfFaceName, _T("Fixedsys"));
- SetSynEditViewFont(m_lf); //设定编辑器字体
- SendMessage(EM_SETUNDOLIMIT, 1000, 0);
- // GetDocument()->m_bRTF = FALSE; //只处理文本
- SetWrapMode(WrapNone);
- SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT|TM_MULTILEVELUNDO|TM_SINGLECODEPAGE, 0);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CSynEditView printing
- BOOL CSynEditView::OnPreparePrinting(CPrintInfo* pInfo)
- {
- // default preparation
- return DoPreparePrinting(pInfo);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CSynEditView diagnostics
- #ifdef _DEBUG
- void CSynEditView::AssertValid() const
- {
- CRichEditView::AssertValid();
- }
- void CSynEditView::Dump(CDumpContext& dc) const
- {
- CRichEditView::Dump(dc);
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CSynEditView message handlers
- void CSynEditView::LoadFile(CString strFile)
- {
- ASSERT(this);
- CFile* pInputFile = NULL;
- try
- {
- pInputFile = new CFile(strFile, CFile::modeRead | CFile::shareDenyNone);
- EDITSTREAM strm;
- strm.dwCookie = (DWORD) pInputFile;
- strm.pfnCallback = EditStreamCallbackReadFromFile;
- long lResult = GetRichEditCtrl().StreamIn(SF_TEXT, strm);
- pInputFile->Close();
- delete pInputFile;
- }
- catch (CFileException* pEx)
- {
- pEx->Delete();
- }
- GetRichEditCtrl().SetModify( FALSE );
- }
- //设定编辑器字体
- void CSynEditView::SetSynEditViewFont(LOGFONT lf)
- {
- m_lf = lf;
- SetSynCtrlFont();
- SetSynEditViewTabSize(m_nTabSize);
- }
- void CSynEditView::SetSynCtrlFont()
- {
- CString str;
- GetWindowText(str);
- BOOL bModify = GetRichEditCtrl().GetModify();
- m_font.DeleteObject();
- m_font.CreateFontIndirect(&m_lf);
- SetFont(&m_font);
- CalcEditorInfo();
- SetSynEditViewMargin(m_nCharNumberWidth, 0);
- SetWindowText(str);
- GetRichEditCtrl().SetModify(bModify);
- }
- //设定编辑器的Tab宽度,以空格为标准进行计算 //TAB也是一种形式的空格
- void CSynEditView::SetSynEditViewTabSize(int nSize)
- {
- ResetParseCookie();
- CString str;
- GetWindowText(str);
- CRichEditCtrl &SynCtrl = GetRichEditCtrl();
- BOOL bModify = SynCtrl.GetModify();
- SetSynCtrlTabSize(nSize);
- SetWindowText(str);
- SynCtrl.SetModify(bModify);
- }
- //改变RichEditCtrl的默认Tab宽度
- void CSynEditView::SetSynCtrlTabSize(int nSize)
- {
- CRichEditCtrl &SynCtrl = GetRichEditCtrl();
- //设置TAB间隔
- CDC *pdc = GetDC();
- PARAFORMAT pf ;
- pf.cbSize = sizeof(PARAFORMAT);
- pf.dwMask = PFM_TABSTOPS ;
- pf.cTabCount = MAX_TAB_STOPS;
- SynCtrl.GetParaFormat( pf );
- int nSynCtrlTabSize = pf.rgxTabs[0];
- if(nSynCtrlTabSize == 0)
- nSynCtrlTabSize = 720;
- int nNewTab;
- nNewTab = int(nSynCtrlTabSize * 1.0 * nSize * m_nCharSpaceWidth / m_nCharTabWidth);
- pf.cTabCount = MAX_TAB_STOPS;
- pf.dwMask = PFM_TABSTOPS;
- for( int itab = 0; itab < pf.cTabCount; itab++ )
- pf.rgxTabs[itab] = (itab+1) * nNewTab ;
- SetParaFormat( pf );
- m_nTabSize = nSize;
- }
- //根据指定行在指定的矩形区域画出语法加亮的文本
- void CSynEditView::DrawSingleLineColorText( CDC *cacheDC, int nLine, CRect rcLine)
- {
- CRect rectforspace(rcLine);
- CRect rect(rcLine);
- CFont cf;
- cf.CreateFontIndirect(&m_lf);
- CFont *pOldFont = cacheDC->SelectObject(&cf);
- CString strnewline=_T(""), strtmp=_T(""), strLine;
- BOOL bRealReturn = GetLineString(nLine, strLine); //取指定行文本,并返回是否为硬回车标志
- int nTabNumber = 0;
- int npos = strLine.Find(_T("t"));
- //将所有的Tab转化为相应数量的空格
- while(npos!=-1) {
- strtmp = strLine.Left(npos);
- int nlen = strtmp.GetLength();
- nlen %= m_nTabSize;
- nlen = m_nTabSize - nlen;
- CString strNewTab(0x20, nlen);
- strtmp+=strNewTab;
- strnewline+=strtmp;
- strLine=strLine.Right(strLine.GetLength()-npos-1);
- npos = strLine.Find(_T("t"));
- }
- strnewline+=strLine;
- strLine=strnewline;
- int nLength = strLine.GetLength();
- CSize size;
- int nActualItems = 0;
- COLORINFO *ColorInfo = (COLORINFO *)_alloca( sizeof(COLORINFO) * (nLength + 1) );
- DWORD dwCookie = GetParseCookie(nLine-1);
- CString str;
- if( m_bRealReturn )
- dwCookie &= COOKIE_EXT_COMMENT;
- m_bRealReturn = bRealReturn;
- dwCookie = ParseLine(dwCookie, strLine, ColorInfo, nActualItems);
- m_pdwParseCookies[nLine] = dwCookie;
- COLORREF clr;
- int nlen;
- if (nActualItems > 0)
- {
- ASSERT(ColorInfo[0].Pos >= 0 && ColorInfo[0].Pos <= nLength);
- for (int I = 0; I < nActualItems; I ++)
- {
- nlen = ColorInfo[I + 1].Pos - ColorInfo[I].Pos;
- if( I == nActualItems - 1 )
- str = strLine.Mid(ColorInfo[I].Pos, strLine.GetLength() - ColorInfo[I].Pos);
- else
- str = strLine.Mid(ColorInfo[I].Pos, nlen);
- if(str.IsEmpty())
- continue;
- clr = GetColor(ColorInfo[I].Color);
- JudgeInSeletioAndDrawText( cacheDC, rcLine, str, m_clrBkColor, clr );
- }
- }
- cacheDC->SelectObject(pOldFont);
- }
- //设置窗口内是否自动换行
- void CSynEditView::SetWrapMode(int nWrapMode)
- {
- ASSERT(this);
- m_nWordWrap = nWrapMode;
- CSynEditView::WrapChanged();
- ResetParseCookie();
- if(m_nWordWrap == WrapNone)
- {
- GetRichEditCtrl().ShowScrollBar(SB_BOTH, TRUE);
- }
- else
- {
- GetRichEditCtrl().ShowScrollBar(SB_HORZ, FALSE);
- }
- }
- int CSynEditView::GetLinesTop(int nline) //得到第一行
- {
- CRichEditCtrl &SynCtrl = GetRichEditCtrl();
- if( nline > SynCtrl.GetLineCount()-1 ) {
- int nOffset = SynCtrl.LineIndex( nline-1 );
- CPoint p = SynCtrl.GetCharPos( nOffset );
- return p.y+m_nLineHeight;
- }
- int nOffset = SynCtrl.LineIndex( nline );
- CPoint p = SynCtrl.GetCharPos( nOffset );
- return p.y;
- }
- int CSynEditView::GetCurrentLine() //得到当前行
- {
- CRichEditCtrl &SynCtrl=GetRichEditCtrl();
- CHARRANGE cr;
- SynCtrl.GetSel(cr);
- if( cr.cpMin == cr.cpMax )
- return SynCtrl.LineFromChar( cr.cpMax );
- else
- return m_nCurrentLine;
- }
- DWORD CSynEditView::GetParseCookie(int nLineIndex)
- {
- CRichEditCtrl &SynCtrl=GetRichEditCtrl();
- if (m_pdwParseCookies == NULL)
- {
- m_nParseArraySize = m_nLineCount;
- m_pdwParseCookies = new DWORD[m_nLineCount];
- memset(m_pdwParseCookies, 0xff, m_nLineCount * sizeof(DWORD));
- }
- if (nLineIndex < 0)
- return 0;
- if (m_pdwParseCookies[nLineIndex] != (DWORD) -1)
- return m_pdwParseCookies[nLineIndex];
- register int L = nLineIndex;
- while (L >= 0 && m_pdwParseCookies[L] == (DWORD) -1)
- L --;
- L ++;
- int nBlocks = 0;
- CString strLine;
- BOOL bRealReturn = m_bRealReturn;
- while (L <= nLineIndex)
- {
- 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);
- 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(strLine[I]=='}'||strLine[I]=='{')
- {
- DEFINE_BLOCK(I , COLORINDEX_COMMENT);
- bRedefineBlock = true;
- goto CmpNextChar;
- } //判断是否为'}'或'{'
- if(strLine[I]=='('||strLine[I]==')')
- {
- DEFINE_BLOCK(I , COLORINDEX_NUMBER);
- bRedefineBlock = true;
- 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(strtmp=='}'||strtmp=='}')
- {
- DEFINE_BLOCK(nIdentBegin, COLORINDEX_SYNTAX);
- } */
- 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;
- }