📄 cedtview.cpp
字号:
{
// caret position
m_nScrollPosX = m_nScrollPosY = 0;
m_nAnchorPosX = m_nAnchorPosY = 0;
m_nCaretPosX = m_nCaretPosY = 0;
m_nCaretPosXFixed = 0;
// display options
// m_bLocalWordWrap = m_bColumnMode ? FALSE : m_bWordWrap;
// m_bLocalSpellCheck = FALSE;
// active line highlight
m_bActiveLineHighlighted = FALSE;
m_nActiveLineHighlightedPosY = 0;
// pairs highlight
m_bPairMatched = FALSE; m_bBeginningPair = FALSE;
m_nPairPosX[0] = m_nPairPosX[1] = m_nPairPosY[0] = m_nPairPosY[1] = 0;
m_bPairHighlighted[0] = m_bPairHighlighted[1] = FALSE;
// imm composition
m_bComposition = FALSE;
// saved index (save & restore caret and scroll pos)
m_nCaretIdxX = m_nCaretIdxY = 0;
m_nAnchorIdxX = m_nAnchorIdxY = 0;
m_nScrollIdxX = m_nScrollIdxY = 0;
// saved selection
m_nSaveSelBegX = m_nSaveSelBegY = 0;
m_nSaveSelEndX = m_nSaveSelEndY = 0;
m_bSaveSelected = m_bSelected = FALSE;
// update file selection tab
UpdateMDIFileTabOfTheDocument();
// initial formatting
FormatScreenText();
}
void CCedtView::UpdateScrollBars()
{
INT nLineCount = m_clsFormatedScreenText.GetCount();
if( ! nLineCount ) return;
RECT rect; GetClientRect( & rect );
INT nLineHeight = GetLineHeight();
INT nLeftMargin = GetLeftMargin();
INT nAveCharWidth = GetAveCharWidth();
if( m_nScrollPosY < 0 ) m_nScrollPosY = 0;
if( m_nScrollPosY > (nLineCount-1) * nLineHeight ) m_nScrollPosY = (nLineCount-1) * nLineHeight;
UINT nScalingFactor = 32; // maximum scaling factor
if ( nLineCount < 32768 ) nScalingFactor = 1;
else if( nLineCount < 65536 ) nScalingFactor = 2;
else if( nLineCount < 131072 ) nScalingFactor = 4;
else if( nLineCount < 262144 ) nScalingFactor = 8;
else if( nLineCount < 524288 ) nScalingFactor = 16;
UINT nPage = rect.bottom / nLineHeight / nScalingFactor;
INT nMax = (nLineCount - 1) / nScalingFactor + nPage - 1;
INT nPos = m_nScrollPosY / nLineHeight / nScalingFactor;
SCROLLINFO vsi; GetScrollInfo( SB_VERT, & vsi );
vsi.fMask |= SIF_DISABLENOSCROLL;
if( vsi.nMax != nMax || vsi.nPage != nPage ) {
vsi.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
vsi.nMin = 0; vsi.nMax = nMax;
vsi.nPage = nPage; vsi.nPos = nPos;
SetScrollInfo( SB_VERT, & vsi );
} else if( vsi.nPos != nPos ) SetScrollPos( SB_VERT, nPos );
INT nMaxCharCount = 4096;
if( m_nScrollPosX < 0 ) m_nScrollPosX = 0;
nPage = (rect.right - nLeftMargin) / nAveCharWidth;
nMax = nMaxCharCount + nPage - 2;
nPos = m_nScrollPosX / nAveCharWidth;
SCROLLINFO hsi; GetScrollInfo( SB_HORZ, & hsi );
if( hsi.nMax != nMax || hsi.nPage != nPage ) {
hsi.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
hsi.nMin = 0; hsi.nMax = nMax;
hsi.nPage = nPage; hsi.nPos = nPos;
SetScrollInfo( SB_HORZ, & hsi );
} else if( hsi.nPos != nPos ) SetScrollPos( SB_HORZ, nPos );
}
void CCedtView::UpdateCaretPosition()
{
// check if this view is ready
if( ! m_clsFormatedScreenText.GetCount() ) return;
// hide and destroy caret
HideCaret();
DestroyCaret();
if( m_bPairHighlighted[0] || m_bPairHighlighted[1] ) UnhighlightPairs();
if( m_bActiveLineHighlighted ) UnhighlightActiveLine();
if( m_bHighlightActiveLine || m_crBkgrColor[0] != m_crBkgrColor[2] ) HighlightActiveLine();
if( m_bShowColumnMarker1 || m_bShowColumnMarker2 ) HighlightColumnMarker();
if( ! m_bSelected && m_bEnablePairsMatching ) HighlightMatchingPairs();
RECT rect; GetClientRect( & rect );
INT nLeftMargin = GetLeftMargin();
CFormatedString & rLine = GetLineFromPosY(m_nCaretPosY);
INT nIdxY = GetIdxYFromPosY(m_nCaretPosY);
INT nIdxX = GetIdxXFromPosX(rLine, m_nCaretPosX);
INT nMaxY = GetLastIdxY();
// create new caret
INT nCaretHeight = GetCharHeight() - 1;
INT nCaretWidth = m_nCaretWidthRatio * GetAveCharWidth() / 100;
if( m_bOverwriteMode && ! m_bSelected ) nCaretWidth = GetCharWidth();
CreateSolidCaret(nCaretWidth, nCaretHeight);
// set caret position & show caret
INT nPosX = m_nCaretPosX - m_nScrollPosX + nLeftMargin;
INT nPosY = m_nCaretPosY - m_nScrollPosY;
if( nPosX < nLeftMargin || nPosX > rect.right || nPosY < 0 || nPosY > rect.bottom
|| m_bComposition ) ::SetCaretPos(-10000, -10000);
else ::SetCaretPos(nPosX, nPosY+1);
ShowCaret();
// update status bar caret information
CMainFrame * pMainFrame = (CMainFrame *)AfxGetMainWnd();
pMainFrame->SetCaretPositionInfo(nIdxY+1, nIdxX+1, nMaxY+1);
}
void CCedtView::UpdateDragPosition()
{
// check if this view is ready
if( ! m_clsFormatedScreenText.GetCount() ) return;
// hide and destroy caret
HideCaret();
DestroyCaret();
RECT rect; GetClientRect( & rect );
INT nLeftMargin = GetLeftMargin();
CFormatedString & rLine = GetLineFromPosY(m_nCaretPosY);
INT nIdxY = GetIdxYFromPosY(m_nCaretPosY);
INT nIdxX = GetIdxXFromPosX(rLine, m_nCaretPosX);
INT nMaxY = GetLastIdxY();
// create new caret
INT nCaretHeight = GetCharHeight() - 1;
INT nCaretWidth = 25 * GetAveCharWidth() / 100;
CreateGrayCaret(nCaretWidth, nCaretHeight);
// set caret position & show caret
INT nPosX = m_nDragPosX - m_nScrollPosX + nLeftMargin;
INT nPosY = m_nDragPosY - m_nScrollPosY;
if( nPosX < nLeftMargin || nPosX > rect.right || nPosY < 0 || nPosY > rect.bottom
|| m_bComposition ) ::SetCaretPos(-10000, -10000);
else ::SetCaretPos(nPosX, nPosY+1);
ShowCaret();
}
void CCedtView::UpdateFileStatusPane()
{
CMainFrame * pMainFrame = (CMainFrame *)AfxGetMainWnd();
CCedtDoc * pDoc = (CCedtDoc *)GetDocument();
pMainFrame->SetFileStatusInfo( pDoc->m_nEncodingType, pDoc->m_nFileFormat, pDoc->IsReadOnlyFile() );
}
void CCedtView::UpdateMDIFileTabOfTheDocument()
{
// CMainFrame * pMainFrame = (CMainFrame *)AfxGetMainWnd();
// CChildFrame * pChild = (CChildFrame *)GetParentFrame();
// pMainFrame->UpdateFileTab( pChild );
CCedtDoc * pDoc = (CCedtDoc *)GetDocument(); ASSERT( pDoc );
pDoc->UpdateMDIFileTab();
}
INT CCedtView::GetCompositionString(DWORD dwIndex, CString & szString)
{
HIMC hImc = ImmGetContext( m_hWnd ); CHAR buf[1024];
INT nSize = ImmGetCompositionString( hImc, dwIndex, buf, 1024 );
ImmReleaseContext( m_hWnd, hImc );
buf[nSize] = '\0'; szString = buf;
return nSize;
}
INT CCedtView::GetCurrentLineNumber()
{
return GetIdxYFromPosY(m_nCaretPosY) + 1;
}
CString CCedtView::GetCurrentWord()
{
CFormatedString & rLine = GetLineFromPosY( m_nCaretPosY );
INT nIdxX = GetIdxXFromPosX( rLine, m_nCaretPosX );
INT nBegX, nEndX; GetCurrWordRange( rLine, nIdxX, nBegX, nEndX );
if( nEndX - nBegX > 0 ) {
INT nIdxY = GetIdxYFromPosY( m_nCaretPosY );
CAnalyzedString & rString = GetLineFromIdxY( nIdxY );
return rString.Mid( nBegX, nEndX-nBegX );
} else return "";
}
CString CCedtView::GetSelectedString()
{
INT nBegX, nBegY, nEndX, nEndY; GetSelectedIndex(nBegX, nBegY, nEndX, nEndY);
if( nBegY == nEndY ) {
CAnalyzedString & rString = GetLineFromIdxY( nBegY );
return rString.Mid( nBegX, nEndX-nBegX );
} else return "";
}
BOOL CCedtView::TurnOffWordWrapMode()
{
if( m_bLocalWordWrap ) {
SendMessage(WM_COMMAND, ID_VIEW_WORD_WRAP, 0L);
return TRUE;
} else return FALSE;
}
void CCedtView::UpdateAllPanesInTheSameRow()
{
CChildFrame * pChild = (CChildFrame *)GetParentFrame(); ASSERT( pChild );
pChild->UpdateAllPanesInTheSameRow( this );
}
void CCedtView::UpdateAllPanesSharingScrollBar()
{
CChildFrame * pChild = (CChildFrame *)GetParentFrame(); ASSERT( pChild );
pChild->UpdateAllPanesSharingScrollBar( this );
}
void CCedtView::UpdateAllViews()
{
CCedtDoc * pDoc = (CCedtDoc *)GetDocument(); ASSERT( pDoc );
pDoc->UpdateAllViews( this );
}
/////////////////////////////////////////////////////////////////////////////
// CCedtView message handlers
int CCedtView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1) return -1;
// register this view as drop target
m_oleDropTarget.Register(this);
return 0;
}
BOOL CCedtView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if( nHitTest == HTCLIENT ) {
CPoint point; GetCursorPos( & point ); ScreenToClient( & point );
if( m_bEnableDragAndDropEditing && m_bSelected && ! m_bAutoScroll ) {
if( point.x < GetLeftMargin() ) SetCursor( CCedtApp::m_hCursorRightArrow );
else if( IsPointInSelection(point) ) SetCursor( CCedtApp::m_hCursorArrow );
else if( IsMacroRecording() ) SetCursor( CCedtApp::m_hCursorIBeamMacro );
else SetCursor( CCedtApp::m_hCursorIBeam );
} else {
if( point.x < GetLeftMargin() ) SetCursor( CCedtApp::m_hCursorRightArrow );
else if( IsMacroRecording() ) SetCursor( CCedtApp::m_hCursorIBeamMacro );
else SetCursor( CCedtApp::m_hCursorIBeam );
}
return TRUE;
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
void CCedtView::OnSetFocus(CWnd* pOldWnd)
{
CView::OnSetFocus(pOldWnd);
ShowCaret();
m_bHaveFocus = TRUE;
UpdateCaretPosition(); // create new caret and update caret position
UpdateFileStatusPane(); // update file format & read only attribute
}
void CCedtView::OnKillFocus(CWnd* pNewWnd)
{
HideCaret();
m_bHaveFocus = FALSE;
CView::OnKillFocus(pNewWnd);
}
void CCedtView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
CClientDC dc( this );
if( m_dcActiveLine.m_hDC ) {
m_bmActiveLine.DeleteObject();
m_dcActiveLine.DeleteDC();
}
m_dcActiveLine.CreateCompatibleDC( & dc );
m_bmActiveLine.CreateCompatibleBitmap( & dc, cx, 2 * GetCharHeight() + 2 );
m_dcActiveLine.SelectObject( & m_bmActiveLine );
// check if not initialized yet
if( ! m_clsFormatedScreenText.GetCount() ) return;
if( m_szPrevClientSize.cx != cx && m_bLocalWordWrap && ! m_nFixedWrapWidth ) {
SaveCaretAndAnchorPos();
FormatScreenText();
RestoreCaretAndAnchorPos();
}
m_szPrevClientSize.cx = cx;
m_szPrevClientSize.cy = cy;
}
// this function is called when screen font is changed
void CCedtView::OnScreenFontChange()
{
CRect rect; GetClientRect( & rect );
CClientDC dc( this );
if( m_dcActiveLine.m_hDC ) {
m_bmActiveLine.DeleteObject();
m_dcActiveLine.DeleteDC();
}
m_dcActiveLine.CreateCompatibleDC( & dc );
m_bmActiveLine.CreateCompatibleBitmap( & dc, rect.Width(), 2 * (GetLineHeight() + 1) );
m_dcActiveLine.SelectObject( & m_bmActiveLine );
}
void CCedtView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
INT nLineCount = m_clsFormatedScreenText.GetCount();
if( ! nLineCount ) return; // this view is not ready...
RECT rect; GetClientRect( & rect );
INT nLineHeight = GetLineHeight();
INT nPageHeight = (rect.bottom / nLineHeight) * nLineHeight;
UINT nScalingFactor = 32; // maximum scaling factor
if ( nLineCount < 32768 ) nScalingFactor = 1;
else if( nLineCount < 65536 ) nScalingFactor = 2;
else if( nLineCount < 131072 ) nScalingFactor = 4;
else if( nLineCount < 262144 ) nScalingFactor = 8;
else if( nLineCount < 524288 ) nScalingFactor = 16;
switch( nSBCode ) {
case SB_LINEUP: SetScrollPosY(m_nScrollPosY - nLineHeight); break;
case SB_LINEDOWN: SetScrollPosY(m_nScrollPosY + nLineHeight); break;
case SB_PAGEUP: SetScrollPosY(m_nScrollPosY - nPageHeight); break;
case SB_PAGEDOWN: SetScrollPosY(m_nScrollPosY + nPageHeight); break;
case SB_THUMBTRACK: SetScrollPosY(nPos * nScalingFactor * nLineHeight); break;
}
Invalidate(); UpdateWindow();
}
void CCedtView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
INT nLineCount = m_clsFormatedScreenText.GetCount();
if( ! nLineCount ) return; // this view is not ready
RECT rect; GetClientRect( & rect );
INT nLeftMargin = GetLeftMargin();
INT nAveCharWidth = GetAveCharWidth();
INT nPageWidth = ((rect.right - nLeftMargin) / nAveCharWidth) * nAveCharWidth;
switch( nSBCode ) {
case SB_LINELEFT: SetScrollPosX(m_nScrollPosX - nAveCharWidth); break;
case SB_LINERIGHT: SetScrollPosX(m_nScrollPosX + nAveCharWidth); break;
case SB_PAGELEFT: SetScrollPosX(m_nScrollPosX - nPageWidth); break;
case SB_PAGERIGHT: SetScrollPosX(m_nScrollPosX + nPageWidth); break;
case SB_THUMBTRACK: SetScrollPosX(nPos * nAveCharWidth); break;
}
Invalidate(); UpdateWindow();
}
BOOL CCedtView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
INT nLineCount = m_clsFormatedScreenText.GetCount();
if( ! nLineCount ) return TRUE; // this view is not ready
INT nLineHeight = GetLineHeight();
INT nDelta = 3 * abs(zDelta) / WHEEL_DELTA;
if( zDelta > 0 ) SetScrollPosSyncAllPanes(m_nScrollPosX, m_nScrollPosY - nDelta * nLineHeight);
else SetScrollPosSyncAllPanes(m_nScrollPosX, m_nScrollPosY + nDelta * nLineHeight);
Invalidate(); UpdateWindow();
UpdateAllPanesInTheSameRow();
return TRUE;
}
void CCedtView::OnRButtonDown(UINT nFlags, CPoint point)
{
if( m_bSelected && point.x >= GetLeftMargin() && IsPointInSelection(point) ) {
// do not set caret position the cursor is on the selection
} else {
// set caret position from mouse pointer
SetCaretPosFromMouse(point);
if( ! IsCaretVisible() ) {
m_bSelected = FALSE;
SetScrollPosToMakeCaretVisible();
Invalidate(); UpdateWindow();
UpdateAllPanesSharingScrollBar();
} else if( m_bSelected ) {
m_bSelected = FALSE;
Invalidate(); UpdateWindow();
} else {
UpdateCaretPosition();
}
}
CView::OnRButtonDown(nFlags, point);
}
void CCedtView::OnRButtonUp(UINT nFlags, CPoint point)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -