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

📄 ccrystaltextview.cpp

📁 专门为65XX系列芯片设计的变异调试环境的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if (nLine2 == -1)
	{
		CRect rcInvalid;
		GetClientRect(&rcInvalid);
		if (! bInvalidateMargin)
			rcInvalid.left += GetMarginWidth();
//		rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight();
		rcInvalid.top = CalcVisibleLines(m_nTopLine, nLine1) * 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 = CalcVisibleLines(m_nTopLine, nLine1) * GetLineHeight();
		rcInvalid.bottom = (CalcVisibleLines(m_nTopLine, nLine2) + 1) * GetLineHeight();
		InvalidateRect(&rcInvalid, FALSE);
	}
}

void CCrystalTextView::SetSelection(const CPoint &ptStart, const CPoint &ptEnd)
{
	ASSERT_VALIDTEXTPOS(ptStart);
	ASSERT_VALIDTEXTPOS(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 CCrystalTextView::AdjustTextPoint(CPoint &point)
{
	point.x += GetCharWidth() / 2;	//todo
}

void CCrystalTextView::OnSetFocus(CWnd* pOldWnd) 
{
	CView::OnSetFocus(pOldWnd);

	m_bFocused = TRUE;
	if (m_ptSelStart != m_ptSelEnd)
		InvalidateLines(m_ptSelStart.y, m_ptSelEnd.y);
	UpdateCaret();
}

DWORD CCrystalTextView::ParseLine(DWORD dwCookie, int nLineIndex, TEXTBLOCK *pBuf, int &nActualItems)
{
	return 0;
}

int CCrystalTextView::CalculateActualOffset(int nLineIndex, int nCharIndex)
{
//	ASSERT(!IsLineHidden(nLineIndex));
	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 CCrystalTextView::ApproxActualOffset(int nLineIndex, int nOffset)
{
	if (nOffset == 0)
		return 0;

	int nLength = GetLineLength(nLineIndex);
	LPCTSTR pszChars = GetLineChars(nLineIndex);
	int nCurrentOffset = 0;
	int nTabSize = GetTabSize();
	for (int I = 0; I < nLength; I ++)
	{
		if (pszChars[I] == _T('\t'))
			nCurrentOffset += (nTabSize - nCurrentOffset % nTabSize);
		else
			nCurrentOffset ++;
		if (nCurrentOffset >= nOffset)
		{
			if (nOffset <= nCurrentOffset - nTabSize / 2)
				return I;
			return I + 1;
		}
	}
	return nLength;
}

void CCrystalTextView::EnsureVisible(CPoint pt)
{
	ASSERT(!IsLineHidden(pt.y));

	//	Scroll vertically
	int nLineCount = GetLineCount();
	int nNewTopLine = m_nTopLine;
	// MiK: bottom line (last visible)
	int nBottomLine= FindVisibleLine(nNewTopLine, GetScreenLines() - 1);
	if (pt.y > nBottomLine) // MiK (pt.y >= nNewTopLine + GetScreenLines())
	{
		nNewTopLine = FindVisibleLine(pt.y, -GetScreenLines() + 1); //MiK pt.y - GetScreenLines() + 1;
	}
	if (pt.y < nNewTopLine)
	{
		nNewTopLine = pt.y;
	}

	if (nNewTopLine < 0)
		nNewTopLine = 0;
	if (nNewTopLine >= nLineCount)
		nNewTopLine = nLineCount - 1;

	if (m_nTopLine != nNewTopLine)
	{
		ScrollToLine(nNewTopLine);
		UpdateSiblingScrollPos(TRUE);
	}

	//	Scroll horizontally
	int nActualPos = CalculateActualOffset(pt.y, pt.x);
	int nNewOffset = m_nOffsetChar;
	if (nActualPos > nNewOffset + GetScreenChars())
	{
		nNewOffset = nActualPos - GetScreenChars();
	}
	if (nActualPos < nNewOffset)
	{
		nNewOffset = nActualPos;
	}

	if (nNewOffset >= GetMaxLineLength())
		nNewOffset = GetMaxLineLength() - 1;
	if (nNewOffset < 0)
		nNewOffset = 0;

	if (m_nOffsetChar != nNewOffset)
	{
		ScrollToChar(nNewOffset);
		UpdateCaret();
		UpdateSiblingScrollPos(FALSE);
	}
}

void CCrystalTextView::OnKillFocus(CWnd* pNewWnd) 
{
	CView::OnKillFocus(pNewWnd);

	m_bFocused = FALSE;
	UpdateCaret();
	if (m_ptSelStart != m_ptSelEnd)
		InvalidateLines(m_ptSelStart.y, m_ptSelEnd.y);
	if (m_bDragSelection)
	{
		ReleaseCapture();
		KillTimer(m_nDragSelTimer);
		m_bDragSelection = FALSE;
	}
}

void CCrystalTextView::OnSysColorChange() 
{
	CView::OnSysColorChange();
	Invalidate();
}

void CCrystalTextView::GetText(const CPoint &ptStart, const CPoint &ptEnd, CString &text)
{
	if (m_pTextBuffer != NULL)
		m_pTextBuffer->GetText(ptStart.y, ptStart.x, ptEnd.y, ptEnd.x, text);
	else
		text = _T("");
}

CString CCrystalTextView::GetCurLine()
{
	int nLine= m_ptCursorPos.y;

	if (m_pTextBuffer == 0 || nLine >= GetLineCount())
		return _T("");

	int nLength= GetLineLength(nLine);
	if (nLength == 0)
		return _T("");

	CString str;
	m_pTextBuffer->GetText(nLine, 0, nLine, nLength, str);
	return str;
}


void CCrystalTextView::UpdateView(CCrystalTextView *pSource, CUpdateContext *pContext,
								  DWORD dwFlags, int nLineIndex /*= -1*/)
{
	if (dwFlags & UPDATE_RESET)
	{
		ResetView();
		RecalcVertScrollBar();
		RecalcHorzScrollBar();
		// MiK: parse all to update collapsible blocks
		GetParseCookie(GetLineCount() - 1);
		NotifyTextChanged();
		return;
	}

	int nLineCount = GetLineCount();
	ASSERT(nLineCount > 0);
	ASSERT(nLineIndex >= -1 && nLineIndex < nLineCount);
	if ((dwFlags & UPDATE_SINGLELINE) != 0)
	{
		ASSERT(nLineIndex != -1);
		//	All text below this line should be reparsed
		if (m_pdwParseCookies != NULL)
		{
			ASSERT(m_nParseArraySize == nLineCount);
			memset(m_pdwParseCookies + nLineIndex, 0xff, sizeof(DWORD) * (m_nParseArraySize - nLineIndex));
		}
		//	This line'th actual length must be recalculated
		if (m_pnActualLineLength != NULL)
		{
			ASSERT(m_nActualLengthArraySize == nLineCount);
			m_pnActualLineLength[nLineIndex] = -1;
		}
		//	Repaint the lines
		InvalidateLines(nLineIndex, -1, TRUE);
	}
	else
	{
		if (nLineIndex == -1)
			nLineIndex = 0;		//	Refresh all text
		//	All text below this line should be reparsed
		if (m_pdwParseCookies != NULL)
		{
			if (m_nParseArraySize != nLineCount)
			{
				//	Reallocate cookies array
				DWORD *pdwNewArray = new DWORD[nLineCount];
				if (nLineIndex > 0)
					memcpy(pdwNewArray, m_pdwParseCookies, sizeof(DWORD) * nLineIndex);
				delete m_pdwParseCookies;
				m_nParseArraySize = nLineCount;
				m_pdwParseCookies = pdwNewArray;
			}
			memset(m_pdwParseCookies + nLineIndex, 0xff, sizeof(DWORD) * (m_nParseArraySize - nLineIndex));
		}
		//	Recalculate actual length for all lines below this
		if (m_pnActualLineLength != NULL)
		{
			if (m_nActualLengthArraySize != nLineCount)
			{
				//	Reallocate actual length array
				int *pnNewArray = new int[nLineCount];
				if (nLineIndex > 0)
					memcpy(pnNewArray, m_pnActualLineLength, sizeof(int) * nLineIndex);
				delete m_pnActualLineLength;
				m_nActualLengthArraySize = nLineCount;
				m_pnActualLineLength = pnNewArray;
			}
			memset(m_pnActualLineLength + nLineIndex, 0xff, sizeof(DWORD) * (m_nActualLengthArraySize - nLineIndex));
		}
		//	Repaint the lines
		InvalidateLines(nLineIndex, -1, TRUE);
	}

	//	All those points must be recalculated and validated
	if (pContext != NULL)
	{
		pContext->RecalcPoint(m_ptCursorPos);
		pContext->RecalcPoint(m_ptSelStart);
		pContext->RecalcPoint(m_ptSelEnd);
		pContext->RecalcPoint(m_ptAnchor);
		ASSERT_VALIDTEXTPOS(m_ptCursorPos);
		ASSERT_VALIDTEXTPOS(m_ptSelStart);
		ASSERT_VALIDTEXTPOS(m_ptSelEnd);
		ASSERT_VALIDTEXTPOS(m_ptAnchor);
		if (m_bDraggingText)
		{
			pContext->RecalcPoint(m_ptDraggedTextBegin);
			pContext->RecalcPoint(m_ptDraggedTextEnd);
			ASSERT_VALIDTEXTPOS(m_ptDraggedTextBegin);
			ASSERT_VALIDTEXTPOS(m_ptDraggedTextEnd);
		}
		CPoint ptTopLine(0, m_nTopLine);
		pContext->RecalcPoint(ptTopLine);
		ASSERT_VALIDTEXTPOS(ptTopLine);
		m_nTopLine = ptTopLine.y;
		UpdateCaret();
	}

	//	Recalculate vertical scrollbar, if needed
	if ((dwFlags & UPDATE_VERTRANGE) != 0)
	{
		if (! m_bVertScrollBarLocked)
			RecalcVertScrollBar();
	}

	//	Recalculate horizontal scrollbar, if needed
	if ((dwFlags & UPDATE_HORZRANGE) != 0)
	{
		m_nMaxLineLength = -1;
		if (! m_bHorzScrollBarLocked)
			RecalcHorzScrollBar();
	}

	if (dwFlags & (UPDATE_SINGLELINE | UPDATE_VERTRANGE))
		NotifyTextChanged();
}

HINSTANCE CCrystalTextView::GetResourceHandle()
{
#ifdef CRYSEDIT_RES_HANDLE
	return CRYSEDIT_RES_HANDLE;
#else
	if (s_hResourceInst != NULL)
		return s_hResourceInst;
	return AfxGetResourceHandle();
#endif
}

int CCrystalTextView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	// Note: CSampleDoc overwrites this logfont
	memset(&m_lfBaseFont, 0, sizeof(m_lfBaseFont));
	lstrcpy(m_lfBaseFont.lfFaceName, _T("Atari Mono"));
	m_lfBaseFont.lfHeight = 0;
	m_lfBaseFont.lfWeight = FW_NORMAL;
	m_lfBaseFont.lfItalic = FALSE;
	m_lfBaseFont.lfCharSet = DEFAULT_CHARSET;
	m_lfBaseFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
	m_lfBaseFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	m_lfBaseFont.lfQuality = DEFAULT_QUALITY;
	m_lfBaseFont.lfPitchAndFamily = DEFAULT_PITCH;

	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	ASSERT(m_hAccel == NULL);
	m_hAccel = ::LoadAccelerators(GetResourceHandle(), MAKEINTRESOURCE(IDR_DEFAULT_ACCEL));
	ASSERT(m_hAccel != NULL);
	return 0;
}

void CCrystalTextView::SetAnchor(const CPoint &ptNewAnchor)
{
	ASSERT_VALIDTEXTPOS(ptNewAnchor);
	m_ptAnchor = ptNewAnchor;
}

void CCrystalTextView::OnEditOperation(int nAction, LPCTSTR pszText)
{
}

BOOL CCrystalTextView::PreTranslateMessage(MSG *pMsg) 
{
	if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
	{
		if (m_hAccel != NULL)
		{
			if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
				return TRUE;
		}
	}

	return CView::PreTranslateMessage(pMsg);
}

CPoint CCrystalTextView::GetCursorPos()
{
	return m_ptCursorPos;
}

void CCrystalTextView::SetCursorPos(const CPoint &ptCursorPos)
{
	ASSERT_VALIDTEXTPOS(ptCursorPos);
	m_ptCursorPos = ptCursorPos;
	m_nIdealCharPos = CalculateActualOffset(m_ptCursorPos.y, m_ptCursorPos.x);
	UpdateCaret();
}

void CCrystalTextView::SetSelectionMargin(BOOL bSelMargin)
{
	if (m_bSelMargin != bSelMargin)
	{
		m_bSelMargin = bSelMargin;
		if (::IsWindow(m_hWnd))
		{
			m_nScreenChars = -1;
			Invalidate();
			RecalcHorzScrollBar();
		}
	}
}

void CCrystalTextView::GetFont(LOGFONT &lf)
{
	lf = m_lfBaseFont;
}

void CCrystalTextView::SetFont(const LOGFONT &lf)
{
	m_lfBaseFont = lf;
	m_nScreenLines = -1;
	m_nScreenChars = -1;
	m_nCharWidth = -1;
	m_nLineHeight = -1;
	if (m_pCacheBitmap != NULL)
	{
		m_pCacheBitmap->DeleteObject();
		delete m_pCacheBitmap;
		m_pCacheBitmap = NULL;
	}
	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 (::IsWindow(m_hWnd))
	{
		RecalcVertScrollBar();
		RecalcHorzScrollBar();
		UpdateCaret();
		Invalidate();
	}
}

void CCrystalTextView::OnUpdateIndicatorPosition(CCmdUI* pCmdUI)
{
	ASSERT_VALIDTEXTPOS(m_ptCursorPos);
	CString stat;
	int nXPos= CalculateActualOffset(m_ptCursorPos.y, m_ptCursorPos.x);
	stat.Format(_T("Ln %d, Col %d"), m_ptCursorPos.y + 1, nXPos + 1);
	pCmdUI->SetText(stat);
}

void CCrystalTextView::OnUpdateIndicatorCRLF(CCmdUI* pCmdUI)
{
	if (m_pTextBuffer != NULL)
	{
		int crlfMode = m_pTextBuffer->GetCRLFMode();
		switch (crlfMode)
		{
		case CRLF_STYLE_DOS:
			pCmdUI->SetText(_T("DOS"));
			pCmdUI->Enable(TRUE);
			break;
		case CRLF_STYLE_UNIX:
			pCmdUI->SetText(_T("UNIX"));
			pCmdUI->Enable(TRUE);
			break;
		case CRLF_STYLE_MAC:
			pCmdUI->SetText(_T("MAC"));
			pCmdUI->Enable(TRUE);
			break;
		default:
			pCmdUI->SetText(NULL);
			pCmdUI->Enable(FALSE);
		}
	}
	else
	{
		pCmdUI->SetText(NULL);
		pCmdUI->Enable(FALSE);
	}
}

void CCrystalTextView::OnToggleBookmark(UINT nCmdID)
{
	int nBookmarkID = nCmdID - ID_EDIT_TOGGLE

⌨️ 快捷键说明

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