📄 ccrystaltextview.cpp
字号:
}
}
void CCrystalTextView::
SaveSettings ()
{
TextDefinition *def = m_SourceDefs;
CReg reg;
if (reg.Create (HKEY_CURRENT_USER, REG_EDITPAD, KEY_WRITE))
{
VERIFY (reg.SaveNumber (_T ("DefaultEncoding"), (DWORD) CCrystalTextBuffer::m_nDefaultEncoding));
for (int i = 0; i < countof (m_SourceDefs); i++, def++)
{
CReg reg1;
if (reg1.Create (reg.hKey, def->name, KEY_WRITE))
{
VERIFY (reg1.SaveString (_T ("Extensions"), def->exts));
VERIFY (reg1.SaveNumber (_T ("Flags"), def->flags));
VERIFY (reg1.SaveNumber (_T ("TabSize"), def->tabsize));
VERIFY (reg1.SaveString (_T ("OpenComment"), def->opencomment));
VERIFY (reg1.SaveString (_T ("CloseComment"), def->closecomment));
VERIFY (reg1.SaveString (_T ("CommentLine"), def->commentline));
VERIFY (reg1.SaveNumber (_T ("DefaultEncoding"), def->encoding));
}
}
VERIFY (reg.SaveBinary (_T ("LogFont"), (LPBYTE) &m_LogFont, sizeof (m_LogFont)));
}
}
CCrystalTextView::CCrystalTextView ()
{
AFX_ZERO_INIT_OBJECT (CView);
m_rxnode = NULL;
m_pszMatched = NULL;
m_bSelMargin = TRUE;
m_bWordWrap = FALSE;
//BEGIN SW
m_panSubLines = new CArray<int, int>();
ASSERT( m_panSubLines );
m_panSubLines->SetSize( 0, 4096 );
m_pstrIncrementalSearchString = new CString;
ASSERT( m_pstrIncrementalSearchString );
m_pstrIncrementalSearchStringOld = new CString;
ASSERT( m_pstrIncrementalSearchStringOld );
//END SW
ResetView ();
SetTextType (SRC_PLAIN);
m_bSingle = false; // needed to be set in descendat classes
m_bRememberLastPos = false;
}
CCrystalTextView::~CCrystalTextView ()
{
ASSERT (m_hAccel == NULL);
ASSERT (m_pCacheBitmap == NULL);
ASSERT (m_pTextBuffer == NULL); // Must be correctly detached
if (m_pszLastFindWhat != NULL)
free (m_pszLastFindWhat);
if (m_pdwParseCookies != NULL)
delete m_pdwParseCookies;
if (m_pnActualLineLength != NULL)
delete m_pnActualLineLength;
if (m_rxnode)
RxFree (m_rxnode);
if (m_pszMatched)
delete m_pszMatched;
//BEGIN SW
if( m_panSubLines )
delete m_panSubLines;
if( m_pstrIncrementalSearchString )
delete m_pstrIncrementalSearchString;
if( m_pstrIncrementalSearchStringOld )
delete m_pstrIncrementalSearchStringOld;
//END SW
}
BOOL CCrystalTextView::
PreCreateWindow (CREATESTRUCT & cs)
{
CWnd *pParentWnd = CWnd::FromHandlePermanent (cs.hwndParent);
if (pParentWnd == NULL || !pParentWnd->IsKindOf (RUNTIME_CLASS (CSplitterWnd)))
{
// View must always create its own scrollbars,
// if only it's not used within splitter
//BEGIN SW
if( m_bWordWrap )
// we do not need a horizontal scroll bar, if we wrap the lines
cs.style|= WS_VSCROLL;
else
cs.style |= (WS_HSCROLL | WS_VSCROLL);
/*ORIGINAL
cs.style |= (WS_HSCROLL | WS_VSCROLL);
*/
//END SW
}
cs.lpszClass = AfxRegisterWndClass (CS_DBLCLKS);
return CView::PreCreateWindow (cs);
}
/////////////////////////////////////////////////////////////////////////////
// CCrystalTextView drawing
void CCrystalTextView::
GetSelection (CPoint & ptStart, CPoint & ptEnd)
{
PrepareSelBounds ();
ptStart = m_ptDrawSelStart;
ptEnd = m_ptDrawSelEnd;
}
CCrystalTextBuffer *CCrystalTextView::
LocateTextBuffer ()
{
return NULL;
}
int CCrystalTextView::
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 (;;)
{
LPTSTR psz = _tcschr (pszCurrent, _T('\t'));
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 CCrystalTextView::
ScrollToChar (int nNewOffsetChar, BOOL bNoSmoothScroll /*= FALSE*/ , BOOL bTrackScrollBar /*= TRUE*/ )
{
//BEGIN SW
// no horizontal scrolling, when word wrapping is enabled
if( m_bWordWrap )
return;
//END SW
// 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);
}
}
//BEGIN SW
void CCrystalTextView::ScrollToSubLine( int nNewTopSubLine,
BOOL bNoSmoothScroll /*= FALSE*/, BOOL bTrackScrollBar /*= TRUE*/ )
{
if (m_nTopSubLine != nNewTopSubLine)
{
if (bNoSmoothScroll || ! m_bSmoothScroll)
{
int nScrollLines = m_nTopSubLine - nNewTopSubLine;
m_nTopSubLine = nNewTopSubLine;
ScrollWindow(0, nScrollLines * GetLineHeight());
UpdateWindow();
if (bTrackScrollBar)
RecalcVertScrollBar(TRUE);
}
else
{
// Do smooth scrolling
int nLineHeight = GetLineHeight();
if (m_nTopSubLine > nNewTopSubLine)
{
int nIncrement = (m_nTopSubLine - nNewTopSubLine) / SMOOTH_SCROLL_FACTOR + 1;
while (m_nTopSubLine != nNewTopSubLine)
{
int nTopSubLine = m_nTopSubLine - nIncrement;
if (nTopSubLine < nNewTopSubLine)
nTopSubLine = nNewTopSubLine;
int nScrollLines = nTopSubLine - m_nTopSubLine;
m_nTopSubLine = nTopSubLine;
ScrollWindow(0, - nLineHeight * nScrollLines);
UpdateWindow();
if (bTrackScrollBar)
RecalcVertScrollBar(TRUE);
}
}
else
{
int nIncrement = (nNewTopSubLine - m_nTopSubLine) / SMOOTH_SCROLL_FACTOR + 1;
while (m_nTopSubLine != nNewTopSubLine)
{
int nTopSubLine = m_nTopSubLine + nIncrement;
if (nTopSubLine > nNewTopSubLine)
nTopSubLine = nNewTopSubLine;
int nScrollLines = nTopSubLine - m_nTopSubLine;
m_nTopSubLine = nTopSubLine;
ScrollWindow(0, - nLineHeight * nScrollLines);
UpdateWindow();
if (bTrackScrollBar)
RecalcVertScrollBar(TRUE);
}
}
}
int nDummy;
GetLineBySubLine( m_nTopSubLine, m_nTopLine, nDummy );
InvalidateRect( NULL ); // repaint whole window
}
}
/*void CCrystalTextView::GoToLine( int nLine )
{
SetCursorPos( CPoint( 0, (nLine > 0)? nLine - 1 : 0 ) );
EnsureVisible( GetCursorPos() );
}*/
//END SW
void CCrystalTextView::
ScrollToLine (int nNewTopLine, BOOL bNoSmoothScroll /*= FALSE*/ , BOOL bTrackScrollBar /*= TRUE*/ )
{
//BEGIN SW
if( m_nTopLine != nNewTopLine )
ScrollToSubLine( GetSubLineIndex( nNewTopLine ), bNoSmoothScroll, bTrackScrollBar );
/*ORIGINAL
if (m_nTopLine != nNewTopLine)
{
if (bNoSmoothScroll || ! m_bSmoothScroll)
{
int nScrollLines = m_nTopLine - nNewTopLine;
m_nTopLine = nNewTopLine;
ScrollWindow(0, nScrollLines * GetLineHeight());
UpdateWindow();
if (bTrackScrollBar)
RecalcVertScrollBar(TRUE);
}
else
{
// Do smooth scrolling
int nLineHeight = GetLineHeight();
if (m_nTopLine > nNewTopLine)
{
int nIncrement = (m_nTopLine - nNewTopLine) / SMOOTH_SCROLL_FACTOR + 1;
while (m_nTopLine != nNewTopLine)
{
int nTopLine = m_nTopLine - nIncrement;
if (nTopLine < nNewTopLine)
nTopLine = nNewTopLine;
int nScrollLines = nTopLine - m_nTopLine;
m_nTopLine = nTopLine;
ScrollWindow(0, - nLineHeight * nScrollLines);
UpdateWindow();
if (bTrackScrollBar)
RecalcVertScrollBar(TRUE);
}
}
else
{
int nIncrement = (nNewTopLine - m_nTopLine) / SMOOTH_SCROLL_FACTOR + 1;
while (m_nTopLine != nNewTopLine)
{
int nTopLine = m_nTopLine + nIncrement;
if (nTopLine > nNewTopLine)
nTopLine = nNewTopLine;
int nScrollLines = nTopLine - m_nTopLine;
m_nTopLine = nTopLine;
ScrollWindow(0, - nLineHeight * nScrollLines);
UpdateWindow();
if (bTrackScrollBar)
RecalcVertScrollBar(TRUE);
}
}
}
}
*///END SW
}
void CCrystalTextView::
ExpandChars (LPCTSTR pszChars, int nOffset, int nCount, CString & line)
{
if (nCount <= 0)
{
line = _T ("");
return;
}
int nTabSize = GetTabSize ();
int nActualOffset = 0;
for (int I = 0; I < nOffset; I++)
{
if (pszChars[I] == _T ('\t'))
nActualOffset += (nTabSize - nActualOffset % nTabSize);
else
nActualOffset++;
}
pszChars += nOffset;
int nLength = nCount;
int nTabCount = 0;
for (I = 0; I < nLength; I++)
{
if (pszChars[I] == _T ('\t'))
nTabCount++;
}
LPTSTR pszBuf = line.GetBuffer (nLength + nTabCount * (nTabSize - 1) + 1);
int nCurPos = 0;
if (nTabCount > 0 || m_bViewTabs)
{
for (I = 0; I < nLength; I++)
{
if (pszChars[I] == _T ('\t'))
{
int nSpaces = nTabSize - (nActualOffset + nCurPos) % nTabSize;
if (m_bViewTabs)
{
pszBuf[nCurPos++] = TAB_CHARACTER;
nSpaces--;
}
while (nSpaces > 0)
{
pszBuf[nCurPos++] = _T (' ');
nSpaces--;
}
}
else
{
if (pszChars[I] == _T (' ') && m_bViewTabs)
pszBuf[nCurPos] = SPACE_CHARACTER;
else
pszBuf[nCurPos] = pszChars[I];
nCurPos++;
}
}
}
else
{
memcpy (pszBuf, pszChars, sizeof (TCHAR) * nLength);
nCurPos = nLength;
}
pszBuf[nCurPos] = 0;
line.ReleaseBuffer ();
}
void CCrystalTextView::
DrawLineHelperImpl (CDC * pdc, CPoint & ptOrigin, const CRect & rcClip,
LPCTSTR pszChars, int nOffset, int nCount)
{
ASSERT (nCount >= 0);
if (nCount > 0)
{
CString line;
ExpandChars (pszChars, nOffset, nCount, line);
int nWidth = rcClip.right - ptOrigin.x;
if (nWidth > 0)
{
int nCharWidth = GetCharWidth ();
int nCount = line.GetLength ();
int nCountFit = nWidth / nCharWidth + 1;
if (nCount > nCountFit)
nCount = nCountFit;
#ifdef _DEBUG
//CSize sz = pdc->GetTextExtent(line, nCount);
//ASSERT(sz.cx == m_nCharWidth * nCount);
#endif
/*
CRect rcBounds = rcClip;
rcBounds.left = ptOrigin.x;
rcBounds.right = rcBounds.left + GetCharWidth() * nCount;
pdc->ExtTextOut(rcBounds.left, rcBounds.top, ETO_OPAQUE, &rcBounds, NULL, 0, NULL);
*/
VERIFY (pdc->ExtTextOut (ptOrigin.x, ptOrigin.y, ETO_CLIPPED, &rcClip, line, nCount, NULL));
}
ptOrigin.x += GetCharWidth () * line.GetLength ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -