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

📄 ccrystaltextview.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 CPP
📖 第 1 页 / 共 5 页
字号:
          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 + -