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

📄 ccrystaleditview.cpp

📁 一个类似VB代码编辑器.通过一个多文档模板导出
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			int nRows = pSplitterWnd->GetRowCount();
			for (int nRow = 0; nRow < nRows; nRow ++)
			{
				if (nRow != nCurrentRow)	//	We don't need to update ourselves
				{
					CCrystalEditView *pSiblingView = GetSiblingView(nRow, nCurrentCol);
					if (pSiblingView != NULL)
						pSiblingView->OnUpdateSibling(this, FALSE);
				}
			}
		}
	}
}
int CCrystalEditView::CalculateActualOffset(int nLineIndex, int nCharIndex)
{
	int nLength = GetLineLength(nLineIndex);
	ASSERT(nCharIndex >= 0 && nCharIndex <= nLength);
	LPCTSTR pszChars = GetLineChars(nLineIndex);
	int nOffset = 0;
	int nTabSize = GetTabSize();
	for (int I = 0; I < nCharIndex; I ++)
	{
		if (pszChars[I] == _T('\t'))
			nOffset += (nTabSize - nOffset % nTabSize);
		else
			nOffset ++;
	}
	return nOffset;
}
int CCrystalEditView::GetScreenChars()
{
	if (m_nScreenChars == -1)
	{
		CRect rect;
		GetClientRect(&rect);
		m_nScreenChars = (rect.Width() - GetMarginWidth()) / GetCharWidth();
	}
	return m_nScreenChars;
}
int CCrystalEditView::GetMaxLineLength()
{
	if (m_nMaxLineLength == -1)
	{
		m_nMaxLineLength = 0;
		int nLineCount = GetLineCount();
		for (int I = 0; I < nLineCount; I ++)
		{
			int nActualLength = GetLineActualLength(I);
			if (m_nMaxLineLength < nActualLength)
				m_nMaxLineLength = nActualLength;
		}
	}
	return m_nMaxLineLength;
}
void CCrystalEditView::ScrollToChar(int nNewOffsetChar, BOOL bNoSmoothScroll /*= FALSE*/, BOOL bTrackScrollBar /*= TRUE*/)
{
	//	For now, ignoring bNoSmoothScroll and m_bSmoothScroll
	if (m_nOffsetChar != nNewOffsetChar)
	{
		int nScrollChars = m_nOffsetChar - nNewOffsetChar;
		m_nOffsetChar = nNewOffsetChar;
		CRect rcScroll;
		GetClientRect(&rcScroll);
		rcScroll.left += GetMarginWidth();
		ScrollWindow(nScrollChars * GetCharWidth(), 0, &rcScroll, &rcScroll);
		UpdateWindow();
		if (bTrackScrollBar)
			RecalcHorzScrollBar(TRUE);
	}
}
int CCrystalEditView::GetLineHeight()
{
	if (m_nLineHeight == -1)
		CalcLineCharDim();
	return m_nLineHeight;
}
void CCrystalEditView::RecalcVertScrollBar(BOOL bPositionOnly /*= FALSE*/)
{
	SCROLLINFO si;
	si.cbSize = sizeof(si);
	if (bPositionOnly)
	{
		si.fMask = SIF_POS;
		si.nPos = m_nTopLine;
	}
	else
	{
		if (GetScreenLines() >= GetLineCount() && m_nTopLine > 0)
		{
			m_nTopLine = 0;
			Invalidate();
			UpdateCaret();
		}
		si.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_POS | SIF_RANGE;
		si.nMin = 0;
		si.nMax = GetLineCount() - 1;
		si.nPage = GetScreenLines();
		si.nPos = m_nTopLine;
	}
	VERIFY(SetScrollInfo(SB_VERT, &si));
}
CCrystalEditView *CCrystalEditView::GetSiblingView(int nRow, int nCol)
{
	CSplitterWnd *pSplitter = GetParentSplitter(this, FALSE);
	if (pSplitter == NULL)
		return NULL;
	CWnd *pWnd = CWnd::FromHandlePermanent(
		::GetDlgItem(pSplitter->m_hWnd, pSplitter->IdFromRowCol(nRow, nCol)));
	if (pWnd == NULL || ! pWnd->IsKindOf(RUNTIME_CLASS(CCrystalEditView)))
		return NULL;
	return (CCrystalEditView *) pWnd;
}
void CCrystalEditView::OnUpdateSibling(CCrystalEditView *pUpdateSource, BOOL bHorz)
{
	if (pUpdateSource != this)
	{
		ASSERT(pUpdateSource != NULL);
		ASSERT_KINDOF(CCrystalEditView, pUpdateSource);
		if (bHorz)
		{
			ASSERT(pUpdateSource->m_nTopLine >= 0);
			ASSERT(pUpdateSource->m_nTopLine < GetLineCount());
			if (pUpdateSource->m_nTopLine != m_nTopLine)
			{
				ScrollToLine(pUpdateSource->m_nTopLine, TRUE, FALSE);
				UpdateCaret();
			}
		}
		else
		{
			ASSERT(pUpdateSource->m_nOffsetChar >= 0);
			ASSERT(pUpdateSource->m_nOffsetChar < GetMaxLineLength());
			if (pUpdateSource->m_nOffsetChar != m_nOffsetChar)
			{
				ScrollToChar(pUpdateSource->m_nOffsetChar, TRUE, FALSE);
				UpdateCaret();
			}
		}
	}
}
int CCrystalEditView::GetLineLength(int nLineIndex)
{
	if (m_pTextBuffer == NULL)
		return 0;
	return m_pTextBuffer->GetLineLength(nLineIndex);
}
LPCTSTR CCrystalEditView::GetLineChars(int nLineIndex)
{
	if (m_pTextBuffer == NULL)
		return NULL;
	return m_pTextBuffer->GetLineChars(nLineIndex);
}
int CCrystalEditView::GetTabSize()
{
	ASSERT(m_nTabSize >= 0 && m_nTabSize <= 64);
	return m_nTabSize;
}
int CCrystalEditView::GetMarginWidth()
{
	return m_bSelMargin ? 20 : 1;
}
int CCrystalEditView::GetCharWidth()
{
	if (m_nCharWidth == -1)
		CalcLineCharDim();
	return m_nCharWidth;
}
int CCrystalEditView::GetLineActualLength(int nLineIndex)
{
	int nLineCount = GetLineCount();
	ASSERT(nLineCount > 0);
	ASSERT(nLineIndex >= 0 && nLineIndex < nLineCount);
	if (m_pnActualLineLength == NULL)
	{
		m_pnActualLineLength = new int[nLineCount];
		memset(m_pnActualLineLength, 0xff, sizeof(int) * nLineCount);
		m_nActualLengthArraySize = nLineCount;
	}

	if (m_pnActualLineLength[nLineIndex] >= 0)
		return m_pnActualLineLength[nLineIndex];

	//	Actual line length is not determined yet, let's calculate a little
	int nActualLength = 0;
	int nLength = GetLineLength(nLineIndex);
	if (nLength > 0)
	{
		LPCTSTR pszLine = GetLineChars(nLineIndex);
		LPTSTR pszChars = (LPTSTR) _alloca(sizeof(TCHAR) * (nLength + 1));
		memcpy(pszChars, pszLine, sizeof(TCHAR) * nLength);
		pszChars[nLength] = 0;
		LPTSTR pszCurrent = pszChars;

		int nTabSize = GetTabSize();
		for (;;)
		{
#ifdef _UNICODE
			LPTSTR psz = wcschr(pszCurrent, L'\t');
#else
			LPTSTR psz = strchr(pszCurrent, '\t');
#endif
			if (psz == NULL)
			{
				nActualLength += (pszChars + nLength - pszCurrent);
				break;
			}

			nActualLength += (psz - pszCurrent);
			nActualLength += (nTabSize - nActualLength % nTabSize);
			pszCurrent = psz + 1;
		}
	}

	m_pnActualLineLength[nLineIndex] = nActualLength;
	return nActualLength;
}
void CCrystalEditView::SetCursorPos(const CPoint &ptCursorPos)
{

	m_ptCursorPos = ptCursorPos;
	m_nIdealCharPos = CalculateActualOffset(m_ptCursorPos.y, m_ptCursorPos.x);
	UpdateCaret();
}
void CCrystalEditView::SetAnchor(const CPoint &ptNewAnchor)
{

	m_ptAnchor = ptNewAnchor;
}
void CCrystalEditView::SetSelection(const CPoint &ptStart, const CPoint &ptEnd)
{

	if (m_ptSelStart == ptStart)
	{
		if (m_ptSelEnd != ptEnd)
			InvalidateLines(ptEnd.y, m_ptSelEnd.y);
	}
	else
	{
		InvalidateLines(ptStart.y, ptEnd.y);
		InvalidateLines(m_ptSelStart.y, m_ptSelEnd.y);
	}
	m_ptSelStart = ptStart;
	m_ptSelEnd = ptEnd;
}
void CCrystalEditView::InvalidateLines(int nLine1, int nLine2, BOOL bInvalidateMargin /*= FALSE*/)
{
	bInvalidateMargin = TRUE;
	if (nLine2 == -1)
	{
		CRect rcInvalid;
		GetClientRect(&rcInvalid);
		if (! bInvalidateMargin)
			rcInvalid.left += GetMarginWidth();
		rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight();
		InvalidateRect(&rcInvalid, FALSE);
	}
	else
	{
		if (nLine2 < nLine1)
		{
			int nTemp = nLine1;
			nLine1 = nLine2;
			nLine2 = nTemp;
		}
		CRect rcInvalid;
		GetClientRect(&rcInvalid);
		if (! bInvalidateMargin)
			rcInvalid.left += GetMarginWidth();
		rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight();
		rcInvalid.bottom = (nLine2 - m_nTopLine + 1) * GetLineHeight();
		InvalidateRect(&rcInvalid, FALSE);
	}
}
void CCrystalEditView::RecalcHorzScrollBar(BOOL bPositionOnly /*= FALSE*/)
{
	//	Again, we cannot use nPos because it's 16-bit
	SCROLLINFO si;
	si.cbSize = sizeof(si);
	if (bPositionOnly)
	{
		si.fMask = SIF_POS;
		si.nPos = m_nOffsetChar;
	}
	else
	{
		if (GetScreenChars() >= GetMaxLineLength() && m_nOffsetChar > 0)
		{
			m_nOffsetChar = 0;
			Invalidate();
			UpdateCaret();
		}
		si.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_POS | SIF_RANGE;
		si.nMin = 0;
		si.nMax = GetMaxLineLength() - 1;
		si.nPage = GetScreenChars();
		si.nPos = m_nOffsetChar;
	}
	VERIFY(SetScrollInfo(SB_HORZ, &si));
}
void CCrystalEditView::CalcLineCharDim()
{
	CDC *pdc = GetDC();
	CFont *pOldFont = pdc->SelectObject(GetFont());
	CSize szCharExt = pdc->GetTextExtent(_T("X"));
	m_nLineHeight = szCharExt.cy;
	if (m_nLineHeight < 1)
		m_nLineHeight = 1;
	m_nCharWidth = szCharExt.cx;
	/*
	TEXTMETRIC tm;
	if (pdc->GetTextMetrics(&tm))
		m_nCharWidth -= tm.tmOverhang;
	*/
	pdc->SelectObject(pOldFont);
	ReleaseDC(pdc);
}
BOOL CCrystalEditView::IsSelection()
{
	return m_ptSelStart != m_ptSelEnd;
}
void CCrystalEditView::AttachToBuffer(CCrystalTextBuffer *pBuf /*= NULL*/)
{
//	if (m_pTextBuffer != NULL)
//		m_pTextBuffer->RemoveView(this);
//	if (pBuf == NULL)
//	{
		pBuf = LocateTextBuffer();
		//	...
//	}
	m_pTextBuffer = pBuf;
	if (m_pTextBuffer != NULL)
		m_pTextBuffer->AddView(this);
	ResetView();

	//	Init scrollbars
	CScrollBar *pVertScrollBarCtrl = GetScrollBarCtrl(SB_VERT);
	if (pVertScrollBarCtrl != NULL)
		pVertScrollBarCtrl->EnableScrollBar(GetScreenLines() >= GetLineCount() ?
											ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
	CScrollBar *pHorzScrollBarCtrl = GetScrollBarCtrl(SB_HORZ);
	if (pHorzScrollBarCtrl != NULL)
		pHorzScrollBarCtrl->EnableScrollBar(GetScreenChars() >= GetMaxLineLength() ?
											ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);

	//	Update scrollbars
	RecalcVertScrollBar();
	RecalcHorzScrollBar();
}
CCrystalTextBuffer *CCrystalEditView::LocateTextBuffer()
{
	return NULL;
}
void CCrystalEditView::ResetView()
{
	m_nTopLine = 0;
	m_nOffsetChar = 0;
	m_nLineHeight = -1;
	m_nCharWidth = -1;
	m_nTabSize = 4;
	m_nMaxLineLength = -1;
	m_nScreenLines = -1;
	m_nScreenChars = -1;
	m_nIdealCharPos = -1;
	m_ptAnchor.x = 0;
	m_ptAnchor.y = 0;
//	for (int I = 0; I < 4; I ++)
//	{
//		if (m_apFonts[I] != NULL)
//		{
//			m_apFonts[I]->DeleteObject();
//			delete m_apFonts[I];
//			m_apFonts[I] = NULL;
//		}
//	}
	if (m_pdwParseCookies != NULL)
	{
		delete m_pdwParseCookies;
		m_pdwParseCookies = NULL;
	}
	if (m_pnActualLineLength != NULL)
	{
		delete m_pnActualLineLength;
		m_pnActualLineLength = NULL;
	}
	m_nParseArraySize = 0;
	m_nActualLengthArraySize = 0;
	m_ptCursorPos.x = 0;
	m_ptCursorPos.y = 0;
	m_ptSelStart = m_ptSelEnd = m_ptCursorPos;
	m_bDragSelection = FALSE;
	m_bVertScrollBarLocked = FALSE;
	m_bHorzScrollBarLocked = FALSE;
	if (::IsWindow(m_hWnd))
		UpdateCaret();
	m_bLastSearch = FALSE;
	m_bShowInactiveSelection = FALSE;
	m_bPrintHeader = FALSE;
	m_bPrintFooter = TRUE;

	m_bBookmarkExist  = FALSE;	// More bookmarks
	m_bMultipleSearch = FALSE;	// More search
}

void CCrystalEditView::OnPaint() 
{
	CRichEditView::OnPaint();
	PaintLeft();
	// TODO: Add your message handler code here
	
	// Do not call CRichEditView::OnPaint() for painting messages
}
//画左边的显示条
void CCrystalEditView::PaintLeft()
{
/*	CBrush brushb(RGB(245,245,230));
	int m_breakpoint;
	CDC* hdc;
	hdc = GetWindowDC();
	CRect rect;
	GetClientRect(&rect);
	hdc->FillRect (CRect(rect.left+2 ,rect.top+2 ,rect.left + m_LineHeight + 7,rect.Height ()+2),&brushb);//画底色
	brushb.DeleteObject ();

	CRichEditCtrl& theEdit = GetRichEditCtrl();
	int nFirstVisible = theEdit.GetFirstVisibleLine();							//得到当前显示的最上端的行号

	CBrush OrigBrush,brushf(RGB(255,0,0));
	CBrush *oldBrush = (CBrush*)hdc->SelectObject (brushf);
	OrigBrush.FromHandle((HBRUSH)oldBrush);

	IntList::iterator it;
	for(it = lBreakPoint.begin(); it != lBreakPoint.end(); it++)
	{
		m_breakpoint = *it;
		if(m_breakpoint > nFirstVisible)
		{
			int point = (m_breakpoint-1 - nFirstVisible)*m_LineHeight +3;				//计算断点位置
			
			if(point < (rect.bottom - m_LineHeight+1))
			{
				hdc->Ellipse(rect.left + 5, point, rect.left+ m_LineHeight + 4,point+m_LineHeight);//画断点
			}
		}
	}
	hdc->SelectObject (&OrigBrush);
	OrigBrush.DeleteObject();
	brushf.DeleteObject ();*/
}

⌨️ 快捷键说明

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