📄 ccrystaleditview.cpp
字号:
// CrystalEditView.cpp : implementation of the CCrystalEditView class
//
#include "stdafx.h"
#include "MALLOC.H"
#include "CCrystalEditView.h"
#include "ATLCONV.H"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCrystalEditView
IMPLEMENT_DYNCREATE(CCrystalEditView, CRichEditView)
BEGIN_MESSAGE_MAP(CCrystalEditView, CRichEditView)
//{{AFX_MSG_MAP(CCrystalEditView)
ON_WM_CHAR()
ON_WM_DESTROY()
ON_WM_PAINT()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCrystalEditView construction/destruction
CCrystalEditView::CCrystalEditView()
{
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
}
CCrystalEditView::~CCrystalEditView()
{
}
BOOL CCrystalEditView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CRichEditView::PreCreateWindow(cs);
}
void CCrystalEditView::OnInitialUpdate()
{
CRichEditView::OnInitialUpdate();
//------------------格式控制
SIZE size;
GetTextExtentPoint(GetDC()->GetSafeHdc (),"A",1,&size);
m_LineHeight = size.cy;
CRichEditCtrl& theEdit = GetRichEditCtrl();
theEdit.LimitText(100000); //10万行代码
PARAFORMAT pf;
theEdit.GetParaFormat(pf);
pf.cbSize = sizeof(PARAFORMAT2);
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
pf.dxStartIndent =-20;
pf.dxOffset = 10;
theEdit.SetParaFormat(pf);
//------------------
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)
{
CCrystalEditView *pSiblingView = GetSiblingView(0, nCol);
if (pSiblingView != NULL && pSiblingView != this)
{
m_nOffsetChar = pSiblingView->m_nOffsetChar;
ASSERT(m_nOffsetChar >= 0 && m_nOffsetChar <= GetMaxLineLength());
}
}
if (nCol > 0)
{
CCrystalEditView *pSiblingView = GetSiblingView(nRow, 0);
if (pSiblingView != NULL && pSiblingView != this)
{
m_nTopLine = pSiblingView->m_nTopLine;
ASSERT(m_nTopLine >= 0 && m_nTopLine < GetLineCount());
}
}
}
// Set the printing margins (720 twips = 1/2 inch).
// SetMargins(CRect(10, 10, 10, 10));
}
/////////////////////////////////////////////////////////////////////////////
// CCrystalEditView printing
BOOL CCrystalEditView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CCrystalEditView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ((::GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0 ||
(::GetAsyncKeyState(VK_RBUTTON) & 0x8000) != 0)
return;
BOOL bTranslated = FALSE;
if (nChar == VK_RETURN)
{
if (m_bOvrMode)
{
CPoint ptCursorPos = GetCursorPos();
if (ptCursorPos.y < GetLineCount() - 1)
{
ptCursorPos.x = 0;
ptCursorPos.y++;
SetSelection(ptCursorPos, ptCursorPos);
SetAnchor(ptCursorPos);
SetCursorPos(ptCursorPos);
EnsureVisible(ptCursorPos);
return;
}
}
m_pTextBuffer->BeginUndoGroup();
if (QueryEditable() && m_pTextBuffer != NULL)
{
DeleteCurrentSelection();
CPoint ptCursorPos = GetCursorPos();
const static TCHAR pszText[3] = _T("\r\n");
int x, y;
m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); // [JRT]
ptCursorPos.x = x;
ptCursorPos.y = y;
SetSelection(ptCursorPos, ptCursorPos);
SetAnchor(ptCursorPos);
SetCursorPos(ptCursorPos);
EnsureVisible(ptCursorPos);
}
m_pTextBuffer->FlushUndoGroup(this);
return;
}
if (nChar > 31)
{
if (QueryEditable() && m_pTextBuffer != NULL)
{
m_pTextBuffer->BeginUndoGroup(nChar != _T(' '));
CPoint ptSelStart, ptSelEnd;
GetSelection(ptSelStart, ptSelEnd);
CPoint ptCursorPos;
if (ptSelStart != ptSelEnd)
{
ptCursorPos = ptSelStart;
DeleteCurrentSelection();
}
else
{
ptCursorPos = GetCursorPos();
if (m_bOvrMode && ptCursorPos.x < GetLineLength(ptCursorPos.y))
m_pTextBuffer->DeleteText(this, ptCursorPos.y, ptCursorPos.x, ptCursorPos.y, ptCursorPos.x + 1, CE_ACTION_TYPING); // [JRT]
}
char pszText[2];
pszText[0] = (char) nChar;
pszText[1] = 0;
int x, y;
USES_CONVERSION;
m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, A2T(pszText), y, x, CE_ACTION_TYPING); // [JRT]
ptCursorPos.x = x;
ptCursorPos.y = y;
SetSelection(ptCursorPos, ptCursorPos);
SetAnchor(ptCursorPos);
SetCursorPos(ptCursorPos);
EnsureVisible(ptCursorPos);
m_pTextBuffer->FlushUndoGroup(this);
}
}
CRichEditView::OnChar(nChar, nRepCnt, nFlags);
}
CPoint CCrystalEditView::GetCursorPos()
{
return m_ptCursorPos;
}
int CCrystalEditView::GetLineCount()
{
if (m_pTextBuffer == NULL)
return 1; // Single empty line
int nLineCount = m_pTextBuffer->GetLineCount();
ASSERT(nLineCount > 0);
return nLineCount;
}
void CCrystalEditView::UpdateCaret()
{
}
BOOL CCrystalEditView::DeleteCurrentSelection()
{
if (IsSelection())
{
CPoint ptSelStart, ptSelEnd;
GetSelection(ptSelStart, ptSelEnd);
CPoint ptCursorPos = ptSelStart;
SetAnchor(ptCursorPos);
SetSelection(ptCursorPos, ptCursorPos);
SetCursorPos(ptCursorPos);
EnsureVisible(ptCursorPos);
// [JRT]:
m_pTextBuffer->DeleteText(this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELSEL);
return TRUE;
}
return FALSE;
}
void CCrystalEditView::GetSelection(CPoint &ptStart, CPoint &ptEnd)
{
PrepareSelBounds();
ptStart = m_ptDrawSelStart;
ptEnd = m_ptDrawSelEnd;
}
void CCrystalEditView::PrepareSelBounds()
{
if (m_ptSelStart.y < m_ptSelEnd.y ||
(m_ptSelStart.y == m_ptSelEnd.y && m_ptSelStart.x < m_ptSelEnd.x))
{
m_ptDrawSelStart = m_ptSelStart;
m_ptDrawSelEnd = m_ptSelEnd;
}
else
{
m_ptDrawSelStart = m_ptSelEnd;
m_ptDrawSelEnd = m_ptSelStart;
}
}
BOOL CCrystalEditView::QueryEditable()
{
if (m_pTextBuffer == NULL)
return FALSE;
return ! m_pTextBuffer->GetReadOnly();
}
void CCrystalEditView::EnsureVisible(CPoint pt)
{
// Scroll vertically
int nLineCount = GetLineCount();
int nNewTopLine = m_nTopLine;
if (pt.y >= nNewTopLine + GetScreenLines())
{
nNewTopLine = 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);
}
}
int CCrystalEditView::GetScreenLines()
{
if (m_nScreenLines == -1)
{
CRect rect;
GetClientRect(&rect);
m_nScreenLines = rect.Height() / GetLineHeight();
}
return m_nScreenLines;
}
void CCrystalEditView::ScrollToLine(int nNewTopLine, BOOL bNoSmoothScroll /*= FALSE*/, BOOL bTrackScrollBar /*= TRUE*/)
{
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);
}
}
}
}
}
void CCrystalEditView::UpdateSiblingScrollPos(BOOL bHorz)
{
CSplitterWnd *pSplitterWnd = GetParentSplitter(this, FALSE);
if (pSplitterWnd != NULL)
{
// See CSplitterWnd::IdFromRowCol() implementation for details
int nCurrentRow = (GetDlgCtrlID() - AFX_IDW_PANE_FIRST) / 16;
int nCurrentCol = (GetDlgCtrlID() - AFX_IDW_PANE_FIRST) % 16;
ASSERT(nCurrentRow >= 0 && nCurrentRow < pSplitterWnd->GetRowCount());
ASSERT(nCurrentCol >= 0 && nCurrentCol < pSplitterWnd->GetColumnCount());
if (bHorz)
{
int nCols = pSplitterWnd->GetColumnCount();
for (int nCol = 0; nCol < nCols; nCol ++)
{
if (nCol != nCurrentCol) // We don't need to update ourselves
{
CCrystalEditView *pSiblingView = GetSiblingView(nCurrentRow, nCol);
if (pSiblingView != NULL)
pSiblingView->OnUpdateSibling(this, TRUE);
}
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -