📄 ccrystaltextview.cpp
字号:
m_ptCursorPos = ptCursorPos;
m_nIdealCharPos = CalculateActualOffset(m_ptCursorPos.y, m_ptCursorPos.x);
UpdateCaret();
}
void CCrystalTextView::SetSelectionMargin(BOOL bSelMargin)
{
if (m_bSelMargin != bSelMargin)
{
m_bSelMargin = bSelMargin;
if (::IsWindow(m_hWnd))
{
m_nScreenChars = -1;
Invalidate();
RecalcHorzScrollBar();
}
}
}
void CCrystalTextView::GetFont(LOGFONT &lf)
{
lf = m_lfBaseFont;
}
void CCrystalTextView::SetFont(const LOGFONT &lf)
{
m_lfBaseFont = lf;
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;
}
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 (::IsWindow(m_hWnd))
{
RecalcVertScrollBar();
RecalcHorzScrollBar();
UpdateCaret();
Invalidate();
}
}
void CCrystalTextView::OnUpdateIndicatorPosition(CCmdUI* pCmdUI)
{
ASSERT_VALIDTEXTPOS(m_ptCursorPos);
CString stat;
stat.Format(_T("Ln %d, Col %d"), m_ptCursorPos.y + 1, m_ptCursorPos.x + 1);
pCmdUI->SetText(stat);
}
void CCrystalTextView::OnUpdateIndicatorCRLF(CCmdUI* pCmdUI)
{
if (m_pTextBuffer != NULL)
{
int crlfMode = m_pTextBuffer->GetCRLFMode();
switch (crlfMode)
{
case CRLF_STYLE_DOS:
pCmdUI->SetText(_T("DOS"));
pCmdUI->Enable(TRUE);
break;
case CRLF_STYLE_UNIX:
pCmdUI->SetText(_T("UNIX"));
pCmdUI->Enable(TRUE);
break;
case CRLF_STYLE_MAC:
pCmdUI->SetText(_T("MAC"));
pCmdUI->Enable(TRUE);
break;
default:
pCmdUI->SetText(NULL);
pCmdUI->Enable(FALSE);
}
}
else
{
pCmdUI->SetText(NULL);
pCmdUI->Enable(FALSE);
}
}
void CCrystalTextView::OnToggleBookmark(UINT nCmdID)
{
int nBookmarkID = nCmdID - ID_EDIT_TOGGLE_BOOKMARK0;
ASSERT(nBookmarkID >= 0 && nBookmarkID <= 9);
if (m_pTextBuffer != NULL)
{
DWORD dwFlags = GetLineFlags(m_ptCursorPos.y);
DWORD dwMask = LF_BOOKMARK(nBookmarkID);
m_pTextBuffer->SetLineFlag(m_ptCursorPos.y, dwMask, (dwFlags & dwMask) == 0);
}
}
void CCrystalTextView::OnGoBookmark(UINT nCmdID)
{
int nBookmarkID = nCmdID - ID_EDIT_GO_BOOKMARK0;
ASSERT(nBookmarkID >= 0 && nBookmarkID <= 9);
if (m_pTextBuffer != NULL)
{
int nLine = m_pTextBuffer->GetLineWithFlag(LF_BOOKMARK(nBookmarkID));
if (nLine >= 0)
{
CPoint pt(0, nLine);
ASSERT_VALIDTEXTPOS(pt);
SetCursorPos(pt);
SetSelection(pt, pt);
SetAnchor(pt);
EnsureVisible(pt);
}
}
}
void CCrystalTextView::OnClearBookmarks()
{
if (m_pTextBuffer != NULL)
{
for (int nBookmarkID = 0; nBookmarkID <= 9; nBookmarkID++)
{
int nLine = m_pTextBuffer->GetLineWithFlag(LF_BOOKMARK(nBookmarkID));
if (nLine >= 0)
{
m_pTextBuffer->SetLineFlag(nLine, LF_BOOKMARK(nBookmarkID), FALSE);
}
}
}
}
void CCrystalTextView::ShowCursor()
{
m_bCursorHidden = FALSE;
UpdateCaret();
}
void CCrystalTextView::HideCursor()
{
m_bCursorHidden = TRUE;
UpdateCaret();
}
DROPEFFECT CCrystalTextView::GetDropEffect()
{
return DROPEFFECT_COPY;
}
void CCrystalTextView::OnDropSource(DROPEFFECT de)
{
ASSERT(de == DROPEFFECT_COPY);
}
HGLOBAL CCrystalTextView::PrepareDragData()
{
PrepareSelBounds();
if (m_ptDrawSelStart == m_ptDrawSelEnd)
return NULL;
CString text;
GetText(m_ptDrawSelStart, m_ptDrawSelEnd, text);
HGLOBAL hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, lstrlen(text) + 1);
if (hData == NULL)
return NULL;
LPSTR pszData = (LPSTR) ::GlobalLock(hData);
USES_CONVERSION;
strcpy(pszData, T2A(text.GetBuffer(0)));
text.ReleaseBuffer();
::GlobalUnlock(hData);
m_ptDraggedTextBegin = m_ptDrawSelStart;
m_ptDraggedTextEnd = m_ptDrawSelEnd;
return hData;
}
static int FindStringHelper(LPCTSTR pszFindWhere, LPCTSTR pszFindWhat, BOOL bWholeWord)
{
ASSERT(pszFindWhere != NULL);
ASSERT(pszFindWhat != NULL);
int nCur = 0;
int nLength = lstrlen(pszFindWhat);
for (;;)
{
#ifdef _UNICODE
LPCTSTR pszPos = wcsstr(pszFindWhere, pszFindWhat);
#else
LPCTSTR pszPos = strstr(pszFindWhere, pszFindWhat);
#endif
if (pszPos == NULL)
return -1;
if (! bWholeWord)
return nCur + (pszPos - pszFindWhere);
if (pszPos > pszFindWhere && (isalnum(pszPos[-1]) || pszPos[-1] == _T('_')))
{
nCur += (pszPos - pszFindWhere);
pszFindWhere = pszPos + 1;
continue;
}
if (isalnum(pszPos[nLength]) || pszPos[nLength] == _T('_'))
{
nCur += (pszPos - pszFindWhere + 1);
pszFindWhere = pszPos + 1;
continue;
}
return nCur + (pszPos - pszFindWhere);
}
ASSERT(FALSE);
return -1;
}
BOOL CCrystalTextView::HighlightText(const CPoint &ptStartPos, int nLength)
{
ASSERT_VALIDTEXTPOS(ptStartPos);
m_ptCursorPos = ptStartPos;
m_ptCursorPos.x += nLength;
ASSERT_VALIDTEXTPOS(m_ptCursorPos);
m_ptAnchor = m_ptCursorPos;
SetSelection(ptStartPos, m_ptCursorPos);
UpdateCaret();
EnsureVisible(m_ptCursorPos);
return TRUE;
}
BOOL CCrystalTextView::FindText(LPCTSTR pszText, const CPoint &ptStartPos, DWORD dwFlags,
BOOL bWrapSearch, CPoint *pptFoundPos)
{
int nLineCount = GetLineCount();
return FindTextInBlock(pszText, ptStartPos, CPoint(0, 0),
CPoint(GetLineLength(nLineCount - 1), nLineCount - 1),
dwFlags, bWrapSearch, pptFoundPos);
}
BOOL CCrystalTextView::FindTextInBlock(LPCTSTR pszText, const CPoint &ptStartPosition,
const CPoint &ptBlockBegin, const CPoint &ptBlockEnd,
DWORD dwFlags, BOOL bWrapSearch, CPoint *pptFoundPos)
{
CPoint ptCurrentPos = ptStartPosition;
ASSERT(pszText != NULL && lstrlen(pszText) > 0);
ASSERT_VALIDTEXTPOS(ptCurrentPos);
ASSERT_VALIDTEXTPOS(ptBlockBegin);
ASSERT_VALIDTEXTPOS(ptBlockEnd);
ASSERT(ptBlockBegin.y < ptBlockEnd.y || ptBlockBegin.y == ptBlockEnd.y &&
ptBlockBegin.x <= ptBlockEnd.x);
if (ptBlockBegin == ptBlockEnd)
return FALSE;
if (ptCurrentPos.y < ptBlockBegin.y || ptCurrentPos.y == ptBlockBegin.y &&
ptCurrentPos.x < ptBlockBegin.x)
ptCurrentPos = ptBlockBegin;
CString what = pszText;
if ((dwFlags & FIND_MATCH_CASE) == 0)
what.MakeUpper();
if (dwFlags & FIND_DIRECTION_UP)
{
ASSERT(ptBlockBegin.x == 0 && ptBlockBegin.y == 0);
ASSERT(ptBlockEnd.x == GetLineLength(GetLineCount() - 1) &&
ptBlockEnd.y == GetLineCount() - 1);
for (;;)
{
while (ptCurrentPos.y >= 0)
{
int nLineLength = GetLineLength(ptCurrentPos.y);
nLineLength -= ptCurrentPos.x;
if (nLineLength <= 0)
{
ptCurrentPos.x = 0;
ptCurrentPos.y --;
continue;
}
LPCTSTR pszChars = GetLineChars(ptCurrentPos.y);
pszChars += ptCurrentPos.x;
CString line;
lstrcpyn(line.GetBuffer(nLineLength + 1), pszChars, nLineLength + 1);
line.ReleaseBuffer();
if ((dwFlags & FIND_MATCH_CASE) == 0)
line.MakeUpper();
int nPos = ::FindStringHelper(line, what, (dwFlags & FIND_WHOLE_WORD) != 0);
if (nPos >= 0)
{
ptCurrentPos.x += nPos;
*pptFoundPos = ptCurrentPos;
return TRUE;
}
ptCurrentPos.x = 0;
ptCurrentPos.y --;
}
if (! bWrapSearch)
return FALSE;
bWrapSearch = FALSE;
ptCurrentPos = CPoint(0, GetLineCount() - 1);
}
}
else
{
for (;;)
{
while (ptCurrentPos.y <= ptBlockEnd.y)
{
int nLineLength = GetLineLength(ptCurrentPos.y);
nLineLength -= ptCurrentPos.x;
if (nLineLength <= 0)
{
ptCurrentPos.x = 0;
ptCurrentPos.y ++;
continue;
}
LPCTSTR pszChars = GetLineChars(ptCurrentPos.y);
pszChars += ptCurrentPos.x;
CString line;
lstrcpyn(line.GetBuffer(nLineLength + 1), pszChars, nLineLength + 1);
line.ReleaseBuffer();
if ((dwFlags & FIND_MATCH_CASE) == 0)
line.MakeUpper();
int nPos = ::FindStringHelper(line, what, (dwFlags & FIND_WHOLE_WORD) != 0);
if (nPos >= 0)
{
ptCurrentPos.x += nPos;
if (ptCurrentPos.y == ptBlockEnd.y && ptCurrentPos.x >= ptBlockEnd.x)
break;
*pptFoundPos = ptCurrentPos;
return TRUE;
}
ptCurrentPos.x = 0;
ptCurrentPos.y ++;
}
if (! bWrapSearch)
return FALSE;
bWrapSearch = FALSE;
ptCurrentPos = ptBlockBegin;
}
}
ASSERT(FALSE);
return FALSE;
}
void CCrystalTextView::OnEditFind()
{
CWinApp *pApp = AfxGetApp();
ASSERT(pApp != NULL);
CFindTextDlg dlg(this);
if (m_bLastSearch)
{
dlg.m_bMatchCase = (m_dwLastSearchFlags & FIND_MATCH_CASE) != 0;
dlg.m_bWholeWord = (m_dwLastSearchFlags & FIND_WHOLE_WORD) != 0;
dlg.m_nDirection = (m_dwLastSearchFlags & FIND_DIRECTION_UP) != 0 ? 0 : 1;
if (m_pszLastFindWhat != NULL)
dlg.m_sText = m_pszLastFindWhat;
}
else
{
dlg.m_bMatchCase = pApp->GetProfileInt(REG_FIND_SUBKEY, REG_MATCH_CASE, FALSE);
dlg.m_bWholeWord = pApp->GetProfileInt(REG_FIND_SUBKEY, REG_WHOLE_WORD, FALSE);
dlg.m_nDirection = 1;
dlg.m_sText = pApp->GetProfileString(REG_FIND_SUBKEY, REG_FIND_WHAT, _T(""));
}
if (IsSelection())
{
CPoint ptSelStart, ptSelEnd;
GetSelection(ptSelStart, ptSelEnd); if (ptSelStart.y == ptSelEnd.y)
{
LPCTSTR pszChars = GetLineChars(ptSelStart.y);
int nChars = ptSelEnd.x - ptSelStart.x;
lstrcpyn(dlg.m_sText.GetBuffer(nChars + 1), pszChars + ptSelStart.x, nChars + 1);
dlg.m_sText.ReleaseBuffer();
}
}
dlg.m_ptCurrentPos = m_ptCursorPos;
m_bShowInactiveSelection = TRUE;
dlg.DoModal();
m_bShowInactiveSelection = FALSE;
m_bLastSearch = TRUE;
if (m_pszLastFindWhat != NULL)
free(m_pszLastFindWhat);
#ifdef _UNICODE
m_pszLastFindWhat = _wcsdup(dlg.m_sText);
#else
m_pszLastFindWhat = strdup(dlg.m_sText);
#endif
m_dwLastSearchFlags = 0;
if (dlg.m_bMatchCase)
m_dwLastSearchFlags |= FIND_MATCH_CASE;
if (dlg.m_bWholeWord)
m_dwLastSearchFlags |= FIND_WHOLE_WORD;
if (dlg.m_nDirection == 0)
m_dwLastSearchFlags |= FIND_DIRECTION_UP;
pApp->WriteProfileInt(REG_FIND_SUBKEY, REG_MATCH_CASE, dlg.m_bMatchCase);
pApp->WriteProfileInt(REG_FIND_SUBKEY, REG_WHOLE_WORD, dlg.m_bWholeWord);
pApp->WriteProfileString(REG_FIND_SUBKEY, REG_FIND_WHAT, dlg.m_sText);
}
void CCrystalTextView::OnEditRepeat()
{
if (m_bLastSearch)
{
CPoint ptFoundPos;
if (! FindText(m_pszLastFindWhat, m_ptCursorPos, m_dwLastSearchFlags, TRUE, &ptFoundPos))
{
CString prompt;
prompt.Format(IDS_EDIT_TEXT_NOT_FOUND, m_pszLastFindWhat);
AfxMessageBox(prompt);
return;
}
HighlightText(ptFoundPos, lstrlen(m_pszLastFindWhat));
m_bMultipleSearch = TRUE;
}
}
void CCrystalTextView::OnUpdateEditRepeat(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bLastSearch);
}
void CCrystalTextView::OnEditFindPrevious()
{
DWORD dwSaveSearchFlags = m_dwLastSearchFlags;
if ((m_dwLastSearchFlags & FIND_DIRECTION_UP) != 0)
m_dwLastSearchFlags &= ~FIND_DIRECTION_UP;
else
m_dwLastSearchFlags |= FIND_DIRECTION_UP;
OnEditRepeat();
m_dwLastSearchFlags = dwSaveSearchFlags;
}
void CCrystalTextView::OnUpdateEditFindPrevious(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bLastSearch);
}
void CCrystalTextView::OnFilePageSetup()
{
CWinApp *pApp = AfxGetApp();
ASSERT(pApp != NULL);
CPageSetupDialog dlg;
dlg.m_psd.Flags &= ~PSD_INTHOUSANDTHSOFINCHES;
dlg.m_psd.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS | PSD_DISABLEORIENTATION | PSD_DISABLEPAPER;
dlg.m_psd.rtMargin.left = pApp->GetProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_LEFT, DEFAULT_PRINT_MARGIN);
dlg.m_psd.rtMargin.right = pApp->GetProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_RIGHT, DEFAULT_PRINT_MARGIN);
dlg.m_psd.rtMargin.top = pApp->GetProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_TOP, DEFAULT_PRINT_MARGIN);
dlg.m_psd.rtMargin.bottom = pApp->GetProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_BOTTOM, DEFAULT_PRINT_MARGIN);
if (dlg.DoModal() == IDOK)
{
pApp->WriteProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_LEFT, dlg.m_psd.rtMargin.left);
pApp->WriteProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_RIGHT, dlg.m_psd.rtMargin.right);
pApp->WriteProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_TOP, dlg.m_psd.rtMargin.top);
pApp->WriteProfileInt(REG_PAGE_SUBKEY, REG_MARGIN_BOTTOM, dlg.m_psd.rtMargin.bottom);
}
}
void CCrystalTextView::OnToggleBookmark()
{
if (m_pTextBuffer != NULL)
{
DWORD dwFlags = GetLineFlags(m_ptCursorPos.y);
DWORD dwMask = LF_BOOKMARKS;
m_pTextBuffer->SetLineFlag(m_ptCursorPos.y, dwMask, (dwFlags & dwMask) == 0, FALSE);
}
int nLine = m_pTextBuffer->GetLineWithFlag(LF_BOOKMARKS);
if (nLine >= 0)
m_bBookmarkExist = TRUE;
else
m_bBookmarkExist = FALSE;
}
void CCrystalTextView::OnNextBookmark()
{
if (m_pTextBuffer != NULL)
{
int nLine = m_pTextBuffer->FindNextBookmarkLine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -