📄 ccrystaltextview.cpp
字号:
return CView::GetFont ();
}
}
return m_apFonts[nIndex];
}
void CCrystalTextView::
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);
}
int CCrystalTextView::
GetLineHeight ()
{
if (m_nLineHeight == -1)
CalcLineCharDim ();
return m_nLineHeight;
}
//BEGIN SW
int CCrystalTextView::GetSubLines( int nLineIndex )
{
/*
if( GetLineLength( nLineIndex ) <= GetScreenChars() )
return 1;
*/
// get number of wrapped lines, this line contains of
int nBreaks = 0;
WrapLineCached( nLineIndex, GetScreenChars(), NULL, nBreaks );
return nBreaks + 1;
}
int CCrystalTextView::CharPosToPoint( int nLineIndex, int nCharPos, CPoint &charPoint )
{
// if we do not wrap lines, y is allways 0 and x is equl to nCharPos
if( !m_bWordWrap )
{
charPoint.x = nCharPos;
charPoint.y = 0;
}
// calculate point out of char pos
/*
if( GetLineLength( nLineIndex ) <= GetScreenChars() )
{
// line is not wrapped
charPoint.x = nCharPos;
charPoint.y = 0;
return 0;
}
*/
// line is wrapped
int *anBreaks = (int*)_alloca( sizeof( int ) * GetLineLength( nLineIndex ) );
int nBreaks = 0;
WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks );
for( int i = nBreaks - 1; i >= 0 && nCharPos < anBreaks[i]; i-- );
charPoint.x = (i >= 0)? nCharPos - anBreaks[i] : nCharPos;
charPoint.y = i + 1;
return (i >= 0)? anBreaks[i] : 0;
}
int CCrystalTextView::CursorPointToCharPos( int nLineIndex, const CPoint &curPoint )
{
// calculate char pos out of point
int nLength = GetLineLength( nLineIndex );
int nScreenChars = GetScreenChars();
LPCTSTR szLine = GetLineChars( nLineIndex );
// wrap line
int *anBreaks = (int*)_alloca( sizeof( int ) * nLength );
int nBreaks = 0;
WrapLineCached( nLineIndex, nScreenChars, anBreaks, nBreaks );
// find char pos that matches cursor position
int nXPos = 0;
int nYPos = 0;
int nCurPos = 0;
int nTabSize = GetTabSize();
for( int nIndex = 0; nIndex < nLength; nIndex++ )
{
if( nBreaks && nIndex == anBreaks[nYPos] )
{
nXPos = 0;
nYPos++;
}
if (szLine[nIndex] == _T('\t'))
{
nXPos+= (nTabSize - nCurPos % nTabSize);
nCurPos+= (nTabSize - nCurPos % nTabSize);
}
else
{
nXPos++;
nCurPos++;
}
if( nXPos > curPoint.x && nYPos == curPoint.y )
break;
else if( nYPos > curPoint.y )
{
nIndex--;
break;
}
}
return nIndex;
}
void CCrystalTextView::SubLineCursorPosToTextPos( const CPoint &subLineCurPos, CPoint &textPos )
{
// Get line breaks
int nSubLineOffset, nLine;
GetLineBySubLine( subLineCurPos.y, nLine, nSubLineOffset );
// compute cursor-position
textPos.x = CursorPointToCharPos( nLine, CPoint( subLineCurPos.x, nSubLineOffset ) );
textPos.y = nLine;
}
int CCrystalTextView::SubLineEndToCharPos( int nLineIndex, int nSubLineOffset )
{
int nLength = GetLineLength( nLineIndex );
// if word wrapping is disabled, the end is equal to the length of the line -1
if( !m_bWordWrap /*|| nLength <= GetScreenChars()*/ )
return nLength;
// wrap line
int *anBreaks = (int*)_alloca( sizeof( int ) * nLength );
int nBreaks = 0;
WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks );
// if there is no break inside the line or the given subline is the last
// one in this line...
if( !nBreaks || nSubLineOffset == nBreaks )
return nLength;
// compute character position for end of subline
ASSERT( nSubLineOffset >= 0 && nSubLineOffset <= nBreaks );
return anBreaks[nSubLineOffset] - 1;
}
int CCrystalTextView::SubLineHomeToCharPos( int nLineIndex, int nSubLineOffset )
{
int nLength = GetLineLength( nLineIndex );
// if word wrapping is disabled, the start is 0
if( !m_bWordWrap /*|| nLength <= GetScreenChars() */|| nSubLineOffset == 0 )
return 0;
// wrap line
int *anBreaks = (int*)_alloca( sizeof( int ) * nLength );
int nBreaks = 0;
WrapLineCached( nLineIndex, GetScreenChars(), anBreaks, nBreaks );
// if there is no break inside the line...
if( !nBreaks )
return 0;
// compute character position for end of subline
ASSERT( nSubLineOffset > 0 && nSubLineOffset <= nBreaks );
return anBreaks[nSubLineOffset - 1];
}
//END SW
int CCrystalTextView::
GetCharWidth ()
{
if (m_nCharWidth == -1)
CalcLineCharDim ();
return m_nCharWidth;
}
int CCrystalTextView::
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;
}
CCrystalTextView *CCrystalTextView::
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 (CCrystalTextView)))
return NULL;
return (CCrystalTextView *) pWnd;
}
void CCrystalTextView::
GoToLine (int nLine, bool bRelative)
{
int nLines = m_pTextBuffer->GetLineCount () - 1;
CPoint ptCursorPos = GetCursorPos ();
if (bRelative)
{
nLine += ptCursorPos.y;
}
if (nLine)
{
nLine--;
}
if (nLine > nLines)
{
nLine = nLines;
}
if (nLine >= 0)
{
int nChars = m_pTextBuffer->GetLineLength (nLine);
if (nChars)
{
nChars--;
}
if (ptCursorPos.x > nChars)
{
ptCursorPos.x = nChars;
}
if (ptCursorPos.x >= 0)
{
ptCursorPos.y = nLine;
ASSERT_VALIDTEXTPOS (ptCursorPos);
SetAnchor (ptCursorPos);
SetSelection (ptCursorPos, ptCursorPos);
SetCursorPos (ptCursorPos);
EnsureVisible (ptCursorPos);
}
}
}
void CCrystalTextView::
OnInitialUpdate ()
{
CView::OnInitialUpdate ();
CString sDoc = GetDocument ()->GetPathName (), sExt = GetExt (sDoc);
SetTextType (sExt);
AttachToBuffer (NULL);
CSplitterWnd *pSplitter = GetParentSplitter (this, FALSE);
if (pSplitter != NULL)
{
// See CSplitterWnd::IdFromRowCol() implementation
int nRow = (GetDlgCtrlID () - AFX_IDW_PANE_FIRST) / 16;
int nCol = (GetDlgCtrlID () - AFX_IDW_PANE_FIRST) % 16;
ASSERT (nRow >= 0 && nRow < pSplitter->GetRowCount ());
ASSERT (nCol >= 0 && nCol < pSplitter->GetColumnCount ());
if (nRow > 0)
{
CCrystalTextView *pSiblingView = GetSiblingView (0, nCol);
if (pSiblingView != NULL && pSiblingView != this)
{
m_nOffsetChar = pSiblingView->m_nOffsetChar;
ASSERT (m_nOffsetChar >= 0 && m_nOffsetChar <= GetMaxLineLength ());
}
}
if (nCol > 0)
{
CCrystalTextView *pSiblingView = GetSiblingView (nRow, 0);
if (pSiblingView != NULL && pSiblingView != this)
{
m_nTopLine = pSiblingView->m_nTopLine;
ASSERT (m_nTopLine >= 0 && m_nTopLine < GetLineCount ());
}
}
}
SetTextType (sExt);
SetFont (m_LogFont);
if (m_bRememberLastPos && !sDoc.IsEmpty ())
{
DWORD dwLastPos[3];
CString sKey = REG_EDITPAD;
sKey += _T ("\\Remembered");
CReg reg;
if (reg.Open (HKEY_CURRENT_USER, sKey, KEY_READ) &&
reg.LoadBinary (sDoc, (LPBYTE) dwLastPos, sizeof (dwLastPos)))
{
CPoint ptCursorPos;
ptCursorPos.x = dwLastPos[1];
ptCursorPos.y = dwLastPos[2];
if (IsValidTextPosY (ptCursorPos))
{
if (!IsValidTextPosX (ptCursorPos))
ptCursorPos.x = 0;
ASSERT_VALIDTEXTPOS (ptCursorPos);
SetCursorPos (ptCursorPos);
SetSelection (ptCursorPos, ptCursorPos);
SetAnchor (ptCursorPos);
EnsureVisible (ptCursorPos);
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CCrystalTextView printing
void CCrystalTextView::
OnPrepareDC (CDC * pDC, CPrintInfo * pInfo)
{
CView::OnPrepareDC (pDC, pInfo);
if (pInfo != NULL)
{
pInfo->m_bContinuePrinting = TRUE;
if (m_pnPages != NULL && (int) pInfo->m_nCurPage > m_nPrintPages)
pInfo->m_bContinuePrinting = FALSE;
}
}
BOOL CCrystalTextView::
OnPreparePrinting (CPrintInfo * pInfo)
{
return DoPreparePrinting (pInfo);
}
int CCrystalTextView::
PrintLineHeight (CDC * pdc, int nLine)
{
ASSERT (nLine >= 0 && nLine < GetLineCount ());
ASSERT (m_nPrintLineHeight > 0);
int nLength = GetLineLength (nLine);
if (nLength == 0)
return m_nPrintLineHeight;
CString line;
LPCTSTR pszChars = GetLineChars (nLine);
ExpandChars (pszChars, 0, nLength, line);
CRect rcPrintArea = m_rcPrintArea;
pdc->DrawText (line, &rcPrintArea, DT_LEFT | DT_NOPREFIX | DT_TOP | DT_WORDBREAK | DT_CALCRECT);
return rcPrintArea.Height ();
}
void CCrystalTextView::
GetPrintHeaderText (int nPageNum, CString & text)
{
ASSERT (m_bPrintHeader);
text = _T ("");
}
void CCrystalTextView::
GetPrintFooterText (int nPageNum, CString & text)
{
ASSERT (m_bPrintFooter);
text.Format (_T ("Page %d/%d"), nPageNum, m_nPrintPages);
}
void CCrystalTextView::
PrintHeader (CDC * pdc, int nPageNum)
{
CRect rcHeader = m_rcPrintArea;
rcHeader.bottom = rcHeader.top;
rcHeader.top -= (m_nPrintLineHeight + m_nPrintLineHeight / 2);
CString text;
GetPrintHeaderText (nPageNum, text);
if (!text.IsEmpty ())
pdc->DrawText (text, &rcHeader, DT_CENTER | DT_NOPREFIX | DT_TOP | DT_SINGLELINE);
}
void CCrystalTextView::
PrintFooter (CDC * pdc, int nPageNum)
{
CRect rcFooter = m_rcPrintArea;
rcFooter.top = rcFooter.bottom;
rcFooter.bottom += (m_nPrintLineHeight + m_nPrintLineHeight / 2);
CString text;
GetPrintFooterText (nPageNum, text);
if (!text.IsEmpty ())
pdc->DrawText (text, &rcFooter, DT_CENTER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -