📄 crortextview.cpp
字号:
return CView::GetFont();
}
}
return m_apFont;
}
void CRorTextView::CalcLineCharDim()
{
CDC *pdc = GetDC();
CFont *pOldFont = pdc->SelectObject(GetFont_1());
CSize szCharExt = pdc->GetTextExtent(_T("X"));
m_nLineHeight = szCharExt.cy;
if (m_nLineHeight < 1)
m_nLineHeight = 1;
m_nCharWidth = szCharExt.cx;
pdc->SelectObject(pOldFont);
ReleaseDC(pdc);
}
int CRorTextView::GetLineHeight()
{
if (m_nLineHeight == -1)
CalcLineCharDim();
return m_nLineHeight;
}
int CRorTextView::GetCharWidth()
{
if (m_nCharWidth == -1)
CalcLineCharDim();
return m_nCharWidth;
}
int CRorTextView::GetMaxLineLength()
{
if (m_nMaxLineLength == -1)
{
m_nMaxLineLength = 0;
int nLineCount = GetLineCount();
for (int I = 0; I < nLineCount; I ++)
{
int nActualLength = GetLineLength(I);
if (m_nMaxLineLength < nActualLength)
m_nMaxLineLength = nActualLength;
}
}
return m_nMaxLineLength;
}
CRorTextView *CRorTextView::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(CRorTextView)))
return NULL;
return (CRorTextView *) pWnd;
}
void CRorTextView::OnInitialUpdate()
{
CView::OnInitialUpdate();
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)
{
CRorTextView *pSiblingView = GetSiblingView(0, nCol);
if (pSiblingView != NULL && pSiblingView != this)
{
m_nOffsetChar = pSiblingView->m_nOffsetChar;
ASSERT(m_nOffsetChar >= 0 && m_nOffsetChar <= GetMaxLineLength());
}
}
if (nCol > 0)
{
CRorTextView *pSiblingView = GetSiblingView(nRow, 0);
if (pSiblingView != NULL && pSiblingView != this)
{
m_nTopLine = pSiblingView->m_nTopLine;
ASSERT(m_nTopLine >= 0 && m_nTopLine < GetLineCount());
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CRorTextView printing
void CRorTextView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
CView::OnPrepareDC(pDC, pInfo);
}
/////////////////////////////////////////////////////////////////////////////
// CRorTextView message handlers
int CRorTextView::GetLineCount()
{
if (m_pTextBuffer == NULL)
return 1; // Single empty line
int nLineCount = m_pTextBuffer->GetLineCount();
ASSERT(nLineCount > 0);
return nLineCount;
}
int CRorTextView::GetLineLength(int nLineIndex)
{
if (m_pTextBuffer == NULL)
return 0;
return m_pTextBuffer->GetLineLength(nLineIndex);
}
LPCTSTR CRorTextView::GetLineChars(int nLineIndex)
{
if (m_pTextBuffer == NULL)
return NULL;
return m_pTextBuffer->GetLineChars(nLineIndex);
}
void CRorTextView::AttachToBuffer(CRorTextBuffer *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();
}
void CRorTextView::DetachFromBuffer()
{
if (m_pTextBuffer != NULL)
{
m_pTextBuffer->RemoveView(this);
m_pTextBuffer = NULL;
ResetView();
}
}
int CRorTextView::GetScreenLines()
{
if (m_nScreenLines == -1)
{
CRect rect;
GetClientRect(&rect);
m_nScreenLines = rect.Height() / GetLineHeight();
}
return m_nScreenLines;
}
int CRorTextView::GetScreenChars()
{
if (m_nScreenChars == -1)
{
CRect rect;
GetClientRect(&rect);
m_nScreenChars = rect.Width() / GetCharWidth();
}
return m_nScreenChars;
}
void MyRefreshView();
void CRorTextView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CScrollView::OnChar(nChar,nRepCnt,nFlags);
if (this->m_pTextBuffer->OnChar(this->m_ptCursorPos.x, this->m_ptCursorPos.y, nChar))
{
//Invalidate();
MyRefreshView();
}
}
void CRorTextView::OnDestroy()
{
DetachFromBuffer();
m_hAccel = NULL;
CView::OnDestroy();
{
if (m_apFont != NULL)
{
m_apFont->DeleteObject();
delete m_apFont;
m_apFont = NULL;
}
}
if (m_pCacheBitmap != NULL)
{
delete m_pCacheBitmap;
m_pCacheBitmap = NULL;
}
}
void CRorTextView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if (m_pCacheBitmap != NULL)
{
m_pCacheBitmap->DeleteObject();
delete m_pCacheBitmap;
m_pCacheBitmap = NULL;
}
m_nScreenLines = -1;
m_nScreenChars = -1;
RecalcVertScrollBar();
RecalcHorzScrollBar();
}
void CRorTextView::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
{
CRorTextView *pSiblingView = GetSiblingView(nCurrentRow, nCol);
if (pSiblingView != NULL)
pSiblingView->OnUpdateSibling(this, TRUE);
}
}
}
else
{
int nRows = pSplitterWnd->GetRowCount();
for (int nRow = 0; nRow < nRows; nRow ++)
{
if (nRow != nCurrentRow) // We don't need to update ourselves
{
CRorTextView *pSiblingView = GetSiblingView(nRow, nCurrentCol);
if (pSiblingView != NULL)
pSiblingView->OnUpdateSibling(this, FALSE);
}
}
}
}
}
void CRorTextView::OnUpdateSibling(CRorTextView *pUpdateSource, BOOL bHorz)
{
if (pUpdateSource != this)
{
ASSERT(pUpdateSource != NULL);
ASSERT_KINDOF(CRorTextView, 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);
UpdateCaret();
}
}
}
}
void CRorTextView::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));
}
void CRorTextView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CView::OnVScroll(nSBCode, nPos, pScrollBar);
// Note we cannot use nPos because of its 16-bit nature
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
VERIFY(GetScrollInfo(SB_VERT, &si));
int nPageLines = GetScreenLines();
int nLineCount = GetLineCount();
int nNewTopLine;
BOOL bDisableSmooth = TRUE;
switch (nSBCode)
{
case SB_TOP:
nNewTopLine = 0;
bDisableSmooth = FALSE;
break;
case SB_BOTTOM:
nNewTopLine = nLineCount - nPageLines + 1;
bDisableSmooth = FALSE;
break;
case SB_LINEUP:
nNewTopLine = m_nTopLine - 1;
break;
case SB_LINEDOWN:
nNewTopLine = m_nTopLine + 1;
break;
case SB_PAGEUP:
nNewTopLine = m_nTopLine - si.nPage + 1;
bDisableSmooth = FALSE;
break;
case SB_PAGEDOWN:
nNewTopLine = m_nTopLine + si.nPage - 1;
bDisableSmooth = FALSE;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
nNewTopLine = si.nTrackPos;
break;
default:
return;
}
if (nNewTopLine < 0)
nNewTopLine = 0;
if (nNewTopLine >= nLineCount)
nNewTopLine = nLineCount - 1;
ScrollToLine(nNewTopLine, bDisableSmooth);
}
void CRorTextView::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 CRorTextView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CView::OnHScroll(nSBCode, nPos, pScrollBar);
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
VERIFY(GetScrollInfo(SB_HORZ, &si));
int nPageChars = GetScreenChars();
int nMaxLineLength = GetMaxLineLength();
int nNewOffset;
switch (nSBCode)
{
case SB_LEFT:
nNewOffset = 0;
break;
case SB_BOTTOM:
nNewOffset = nMaxLineLength - nPageChars + 1;
break;
case SB_LINEUP:
nNewOffset = m_nOffsetChar - 1;
break;
case SB_LINEDOWN:
nNewOffset = m_nOffsetChar + 1;
break;
case SB_PAGEUP:
nNewOffset = m_nOffsetChar - si.nPage + 1;
break;
case SB_PAGEDOWN:
nNewOffset = m_nOffsetChar + si.nPage - 1;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
nNewOffset = si.nTrackPos;
break;
default:
return;
}
if (nNewOffset >= nMaxLineLength)
nNewOffset = nMaxLineLength - 1;
if (nNewOffset < 0)
nNewOffset = 0;
ScrollToChar(nNewOffset);
UpdateCaret();
}
BOOL CRorTextView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (nHitTest == HTCLIENT)
{
CPoint pt;
::GetCursorPos(&pt);
ScreenToClient(&pt);
if (pt.x < 0)
{
::SetCursor(::LoadCursor(GetResourceHandle(), MAKEINTRESOURCE(IDR_MARGIN_CURSOR)));
}
else
{
CPoint ptText = ClientToText(pt);
PrepareSelBounds();
}
return TRUE;
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
CPoint CRorTextView::ClientToText(const CPoint &point)
{
int nLineCount = GetLineCount();
CPoint pt;
pt.y = m_nTopLine + point.y / GetLineHeight();
if (pt.y >= nLineCount)
pt.y = nLineCount - 1;
if (pt.y < 0)
pt.y = 0;
int nLength = 0;
if (pt.y >= 0 && pt.y < nLineCount)
{
nLength = GetLineLength(pt.y);
}
int nPos = m_nOffsetChar + (point.x) / GetCharWidth();
if (nPos < 0)
nPos = 0;
int nIndex = 0, nCurPos = 0;
while (nIndex < nLength)
{
nCurPos ++;
if (nCurPos > nPos)
break;
nIndex ++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -