📄 crortextview.cpp
字号:
ASSERT(nIndex >= 0 && nIndex <= nLength);
pt.x = nIndex;
return pt;
}
#ifdef _DEBUG
void CRorTextView::AssertValidTextPos(const CPoint &point)
{
if (GetLineCount() > 0)
{
ASSERT(m_nTopLine >= 0 && m_nOffsetChar >= 0);
ASSERT(point.y >= 0 && point.y < GetLineCount());
ASSERT(point.x >= 0 && point.x <= GetLineLength(point.y));
}
}
#endif
CPoint CRorTextView::TextToClient(const CPoint &point)
{
ASSERT_VALIDTEXTPOS(point);
CPoint pt;
pt.y = (point.y - m_nTopLine) * GetLineHeight();
pt.x = (point.x - m_nOffsetChar) * GetCharWidth();
return pt;
}
void CRorTextView::InvalidateLines(int nLine1, int nLine2, BOOL bInvalidateMargin /*= FALSE*/)
{
bInvalidateMargin = TRUE;
if (nLine2 == -1)
{
CRect rcInvalid;
GetClientRect(&rcInvalid);
rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight();
InvalidateRect(&rcInvalid, FALSE);
}
else
{
if (nLine2 < nLine1)
{
int nTemp = nLine1;
nLine1 = nLine2;
nLine2 = nTemp;
}
CRect rcInvalid;
GetClientRect(&rcInvalid);
rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight();
rcInvalid.bottom = (nLine2 - m_nTopLine + 1) * GetLineHeight();
InvalidateRect(&rcInvalid, FALSE);
}
}
void CRorTextView::SetSelection(const CPoint &ptStart, const CPoint &ptEnd)
{
ASSERT_VALIDTEXTPOS(ptStart);
ASSERT_VALIDTEXTPOS(ptEnd);
if (m_ptSelStart == ptStart)
{
if (m_ptSelEnd != ptEnd)
InvalidateLines(ptEnd.y, m_ptSelEnd.y);
}
else
{
InvalidateLines(ptStart.y, ptEnd.y);
InvalidateLines(m_ptSelStart.y, m_ptSelEnd.y);
}
m_ptSelStart = ptStart;
m_ptSelEnd = ptEnd;
}
void CRorTextView::AdjustTextPoint(CPoint &point)
{
point.x += GetCharWidth() / 2; //todo
}
void CRorTextView::OnSetFocus(CWnd* pOldWnd)
{
CView::OnSetFocus(pOldWnd);
m_bFocused = TRUE;
if (m_ptSelStart != m_ptSelEnd)
InvalidateLines(m_ptSelStart.y, m_ptSelEnd.y);
UpdateCaret();
}
int CRorTextView::ApproxActualOffset(int nLineIndex, int nOffset)
{
if (nOffset == 0)
return 0;
nOffset--;
int nLength = GetLineLength(nLineIndex);
return min(nLength, nOffset);
}
void CRorTextView::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 = 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);
}
}
void CRorTextView::OnKillFocus(CWnd* pNewWnd)
{
CView::OnKillFocus(pNewWnd);
m_bFocused = FALSE;
UpdateCaret();
if (m_ptSelStart != m_ptSelEnd)
InvalidateLines(m_ptSelStart.y, m_ptSelEnd.y);
//ReleaseCapture();
}
CString CRorTextView::GetText(const CPoint &ptStart, const CPoint &ptEnd)
{
if (m_pTextBuffer != NULL)
return m_pTextBuffer->GetText(ptStart.y, ptStart.x, ptEnd.y, ptEnd.x);
return _T("");
}
void CRorTextView::UpdateView()
{
//CRorTextView *pSource, CUpdateContext *pContext, DWORD dwFlags, int nLineIndex /*= -1*/
CRorTextView *pSource = NULL;
CUpdateContext *pContext = NULL;
DWORD dwFlags = UPDATE_RESET;
int nLineIndex = -1; /*= -1*/
if (dwFlags & UPDATE_RESET)
{
ResetView();
RecalcVertScrollBar();
RecalcHorzScrollBar();
return;
}
int nLineCount = GetLineCount();
ASSERT(nLineCount > 0);
ASSERT(nLineIndex >= -1 && nLineIndex < nLineCount);
if ((dwFlags & UPDATE_SINGLELINE) != 0)
{
ASSERT(nLineIndex != -1);
// Repaint the lines
InvalidateLines(nLineIndex, -1, TRUE);
}
else
{
if (nLineIndex == -1)
nLineIndex = 0; // Refresh all text
// Repaint the lines
InvalidateLines(nLineIndex, -1, TRUE);
}
// All those points must be recalculated and validated
if (pContext != NULL)
{
pContext->RecalcPoint(m_ptCursorPos);
pContext->RecalcPoint(m_ptSelStart);
pContext->RecalcPoint(m_ptSelEnd);
pContext->RecalcPoint(m_ptAnchor);
ASSERT_VALIDTEXTPOS(m_ptCursorPos);
ASSERT_VALIDTEXTPOS(m_ptSelStart);
ASSERT_VALIDTEXTPOS(m_ptSelEnd);
ASSERT_VALIDTEXTPOS(m_ptAnchor);
CPoint ptTopLine(0, m_nTopLine);
pContext->RecalcPoint(ptTopLine);
ASSERT_VALIDTEXTPOS(ptTopLine);
m_nTopLine = ptTopLine.y;
UpdateCaret();
}
// Recalculate vertical scrollbar, if needed
if ((dwFlags & UPDATE_VERTRANGE) != 0)
{
RecalcVertScrollBar();
}
// Recalculate horizontal scrollbar, if needed
if ((dwFlags & UPDATE_HORZRANGE) != 0)
{
m_nMaxLineLength = -1;
RecalcHorzScrollBar();
}
}
HINSTANCE CRorTextView::GetResourceHandle()
{
#ifdef CRYSEDIT_RES_HANDLE
return CRYSEDIT_RES_HANDLE;
#else
if (s_hResourceInst != NULL)
return s_hResourceInst;
return AfxGetResourceHandle();
#endif
}
int CRorTextView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
ASSERT(m_hAccel == NULL);
m_hAccel = ::LoadAccelerators(GetResourceHandle(), MAKEINTRESOURCE(IDR_DEFAULT_ACCEL));
ASSERT(m_hAccel != NULL);
return 0;
}
BOOL CRorTextView::PreTranslateMessage(MSG *pMsg)
{
if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
{
if (m_hAccel != NULL)
{
if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
return TRUE;
}
}
return CView::PreTranslateMessage(pMsg);
}
void CRorTextView::SetFont()
{
m_nScreenLines = -1;
m_nScreenChars = -1;
m_nCharWidth = -1;
m_nLineHeight = -1;
if (m_pCacheBitmap != NULL)
{
m_pCacheBitmap->DeleteObject();
delete m_pCacheBitmap;
m_pCacheBitmap = NULL;
}
{
if (m_apFont != NULL)
{
m_apFont->DeleteObject();
delete m_apFont;
m_apFont = NULL;
}
}
if (::IsWindow(m_hWnd))
{
RecalcVertScrollBar();
RecalcHorzScrollBar();
UpdateCaret();
Invalidate();
}
}
class CTempDraw
{
public:
~CTempDraw();
CTempDraw(CDC* pdc);
CDC* m_pdc;
CDC* m_pcacheDC;
int m_lineno;
int m_xpos;
CRect rcClient;
int nLineHeight;
CBitmap* pOldBitmap;
};
CTempDraw::CTempDraw(CDC* pdc)
{
m_pdc = pdc;
m_lineno = 0;
m_xpos = 0;
}
CTempDraw::~CTempDraw()
{
m_pcacheDC->SelectObject(pOldBitmap);
m_pcacheDC->DeleteDC();
}
void CRorTextView::OnDraw(CDC *pdc)
{
#if 1
this->m_pdraw = new CTempDraw(pdc);
CRect rcClient;
GetClientRect(rcClient);
int nLineCount = GetLineCount();
int nLineHeight = GetLineHeight();
this->m_pdraw->nLineHeight = nLineHeight;
PrepareSelBounds();
this->m_pdraw->rcClient = rcClient;
CDC cacheDC;
VERIFY(cacheDC.CreateCompatibleDC(pdc));
if (m_pCacheBitmap == NULL)
{
m_pCacheBitmap = new CBitmap;
VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(pdc, rcClient.Width(), nLineHeight));
}
m_pdraw->pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);
m_pdraw->m_pcacheDC = &cacheDC;
//================
this->LocateTextBuffer()->m_xml.Display(this); //will call this->ColorOut
//================
for (int i=0; i<100; i++)
{
this->ColorOut("=\n",2,RGB(255,255,255));
}
delete this->m_pdraw;
this->m_pdraw = NULL;
#else
CRect rcClient;
GetClientRect(rcClient);
int nLineCount = GetLineCount();
int nLineHeight = GetLineHeight();
PrepareSelBounds();
CDC cacheDC;
VERIFY(cacheDC.CreateCompatibleDC(pdc));
if (m_pCacheBitmap == NULL)
{
m_pCacheBitmap = new CBitmap;
VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(pdc, rcClient.Width(), nLineHeight));
}
CBitmap *pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);
CRect rcLine;
rcLine = rcClient;
rcLine.bottom = rcLine.top + nLineHeight;
int nCurrentLine = m_nTopLine;
while (rcLine.top < rcClient.bottom)
{
cacheDC.FillSolidRect(CRect(0, 0, 9999, 99), GetColor(COLORINDEX_WHITESPACE));
if (nCurrentLine < nLineCount)
{
cacheDC.SetBkColor(GetColor(COLORINDEX_BKGND));
cacheDC.SelectObject(GetFont_1());
DrawSingleLine(&cacheDC, nCurrentLine);
}
VERIFY(pdc->BitBlt(rcLine.left, rcLine.top, rcLine.Width(), rcLine.Height(), &cacheDC, 0, 0, SRCCOPY));
nCurrentLine ++;
rcLine.OffsetRect(0, nLineHeight);
}
cacheDC.SelectObject(pOldBitmap);
cacheDC.DeleteDC();
#endif
}
void __stdcall CRorTextView::SetBKColor(COLORREF textcolor)
{
m_pdraw->m_pcacheDC->SetBkColor(textcolor);
}
void __stdcall CRorTextView::ColorOut(PCSTR str, long len, COLORREF textcolor)
{
if (!memcmp(str, "if", 2))
{
memcmp(str, "if", 2);
}
if (textcolor != RGB(255,255,255))
textcolor = textcolor;
if (len > 1)
len = len;
assert(this->m_pdraw != NULL);
if (m_pdraw->m_xpos == 0)
{//这是行首,清本行
m_pdraw->m_pcacheDC->FillSolidRect(CRect(0, 0, 9999, 99), GetColor(COLORINDEX_WHITESPACE));
m_pdraw->m_pcacheDC->SetBkColor(GetColor(COLORINDEX_BKGND));
m_pdraw->m_pcacheDC->SelectObject(GetFont_1());
}
if (m_pdraw->m_lineno >= GetLineCount())
{
int lines = this->m_pdraw->m_lineno - m_nTopLine;
CRect rcLine = m_pdraw->rcClient;
rcLine.bottom = rcLine.top + m_pdraw->nLineHeight;
rcLine.OffsetRect(0, m_pdraw->nLineHeight * lines);
VERIFY(m_pdraw->m_pdc->BitBlt(
rcLine.left, rcLine.top, rcLine.Width(), rcLine.Height(),
m_pdraw->m_pcacheDC, 0, 0, SRCCOPY));
this->m_pdraw->m_lineno++;
return;
}
//---------------------------------
if (len == 0)
return;
for (int i=0; i<len; i++)
{
char c = str[i];
if (c == '\r' || c == '\n')
{
ColorOut(str,i,textcolor); //递归
if (this->m_pdraw->m_lineno >= m_nTopLine)
{
int lines = this->m_pdraw->m_lineno - m_nTopLine;
CRect rcLine = m_pdraw->rcClient;
rcLine.bottom = rcLine.top + m_pdraw->nLineHeight;
rcLine.OffsetRect(0, m_pdraw->nLineHeight * lines);
VERIFY(m_pdraw->m_pdc->BitBlt(
rcLine.left, rcLine.top, rcLine.Width(), rcLine.Height(),
m_pdraw->m_pcacheDC, 0, 0, SRCCOPY));
}
this->m_pdraw->m_lineno++;
m_pdraw->m_xpos = 0;
if (c == '\r' && str[i+1] == '\n')
i++;
i++;
ColorOut(str+i,len-i,textcolor);
return;
}
}
//以上是处理换行问题
//显示
bool f = false;
{
//处理 select 的问题
for (int i=0; i<len; i++)
{
CPoint pos(m_pdraw->m_xpos+i,m_pdraw->m_lineno);
if (IsInsideSelBlock(pos))
{
if (i != 0)
{
ColorOut(str,i,textcolor);
ColorOut(str+i,len-i,textcolor);
return;
}
f=true;
}
else
{
if (f)
{
ColorOut(str,i,textcolor);
ColorOut(str+i,len-i,textcolor);
return;
}
}
}
if (f)
{
m_pdraw->m_pcacheDC->SetBkColor(RGB(33,33,73));
}
}
m_pdraw->m_pcacheDC->SetTextColor(textcolor);
VERIFY(m_pdraw->m_pcacheDC->ExtTextOut(
this->m_pdraw->m_xpos * GetCharWidth(),
0, //ptOrigin.y * GetLineHeight(),
ETO_CLIPPED, NULL, str,
len,
NULL));
if (f)
{
m_pdraw->m_pcacheDC->SetBkColor(RGB(0,0,0));
}
this->m_pdraw->m_xpos += len;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -