📄 ccrystaleditview.cpp
字号:
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 + -