📄 cedtview.cpp
字号:
// save point to check context menu is called from mouse or keyboard
m_ptRButtonUpPoint = point;
CView::OnRButtonUp(nFlags, point);
}
void CCedtView::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu context, * pMenu = NULL; context.LoadMenu(IDR_VIEW_CONTEXT);
ScreenToClient( & point );
if( point != m_ptRButtonUpPoint ) { // not called from mouse but from keyboard
INT nCaretWidth = m_nCaretWidthRatio * GetAveCharWidth() / 100;
if( m_bOverwriteMode && ! m_bSelected ) nCaretWidth = GetCharWidth();
point.x = m_nCaretPosX - m_nScrollPosX + GetLeftMargin() + nCaretWidth / 2;
point.y = m_nCaretPosY - m_nScrollPosY + GetLineHeight() / 2;
}
if( point.x < GetLeftMargin() ) pMenu = context.GetSubMenu(0);
else if( ! m_bSelected ) pMenu = context.GetSubMenu(1);
else pMenu = context.GetSubMenu(2);
UINT nFlags = TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
ClientToScreen( & point );
pMenu->TrackPopupMenu(nFlags, point.x, point.y, AfxGetMainWnd());
}
void CCedtView::OnLButtonDown(UINT nFlags, CPoint point)
{
TRACE0("OnLButtonDown\n");
if( m_bEnableDragAndDropEditing && ! (nFlags & MK_SHIFT) && m_bSelected && m_bSaveSelected
&& point.x >= GetLeftMargin() && IsPointInSelection(point) ) {
CMemText Block; INT nBegX, nBegY, nEndX, nEndY;
GetSelectedIndex(nBegX, nBegY, nEndX, nEndY);
if( nBegY == nEndY ) { Block.AddTail(""); CopyToString(Block.GetTail(), nBegX, nBegY, nEndX-nBegX); }
else if( ! m_bColumnMode ) CopyToLineSelection(Block, nBegX, nBegY, nEndX, nEndY);
else { GetSelectedPosition(nBegX, nBegY, nEndX, nEndY); CopyToColumnSelection(Block, nBegX, nBegY, nEndX, nEndY); }
INT size = Block.MemorySize(); HGLOBAL hMemory = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
void * pMemory = ::GlobalLock(hMemory); Block.MemorySave((char *)pMemory, size); ::GlobalUnlock(hMemory);
COleDataSource src; src.CacheGlobalData(CF_TEXT, hMemory);
m_bDragDataSource = TRUE; m_bDragDropOccured = FALSE;
TRACE0("Before DoDragDrop\n");
DROPEFFECT eff = src.DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_SCROLL );
m_bDragDataSource = FALSE;
TRACE0("After DoDragDrop\n");
if( eff == DROPEFFECT_NONE && ! m_bDragDropOccured ) {
SetCaretPosFromMouse(point);
m_bSelected = FALSE;
SetScrollPosToMakeCaretVisible();
Invalidate(); UpdateWindow(); UpdateAllViews();
} else if( eff == DROPEFFECT_MOVE && m_bDragDropOccured ) {
OnDragAndDrop(hMemory);
} else if( eff == DROPEFFECT_MOVE ) {
OnDragDelete();
}
} else {
// shift + click: select text enclosed from prev caret position and current mouse point
if( (nFlags & MK_SHIFT) && ! m_bSelected ) { m_nAnchorPosY = m_nCaretPosY; m_nAnchorPosX = m_nCaretPosX; }
// set caret position from mouse pointer
SetCaretPosFromMouse(point);
// adjust caret position and anchor position relative to saved selection
if( (nFlags & MK_SHIFT) && m_bSaveSelected ) AdjustCaretAndAnchorPosRelativeToSavedSelection();
if( point.x < GetLeftMargin() ) {
if( nFlags & MK_SHIFT ) m_bSelected = (m_nCaretPosY != m_nAnchorPosY || m_nCaretPosX != m_nAnchorPosX);
else if( ! m_bColumnMode ) m_bSelected = ActionSelectLine();
else { m_nAnchorPosY = m_nCaretPosY; m_nAnchorPosX = m_nCaretPosX; m_bSelected = FALSE; }
} else {
if( nFlags & MK_SHIFT ) m_bSelected = (m_nCaretPosY != m_nAnchorPosY || m_nCaretPosX != m_nAnchorPosX);
else if( nFlags & MK_CONTROL ) m_bSelected = ActionSelectWord();
else { m_nAnchorPosY = m_nCaretPosY; m_nAnchorPosX = m_nCaretPosX; m_bSelected = FALSE; }
}
if( m_bSelected ) { // set save selected field
GetSelectedPosition(m_nSaveSelBegX, m_nSaveSelBegY, m_nSaveSelEndX, m_nSaveSelEndY);
m_bSaveSelected = TRUE;
} else m_bSaveSelected = FALSE;
// check if this is line select mouse move
if( point.x < GetLeftMargin() && ! m_bColumnMode ) m_bLineSelect = TRUE;
else m_bLineSelect = FALSE;
SetScrollPosToMakeCaretVisible();
Invalidate(); UpdateWindow();
UpdateAllPanesSharingScrollBar();
// calculate auto non-scroll boundary...
RECT rect; GetClientRect( & rect );
INT nLineHeight = GetLineHeight(), nLinesPerPage = GetLinesPerPage();
INT nLeftMargin = GetLeftMargin(), nMaxCharWidth = GetMaxCharWidth();
m_rectNonScroll.top = rect.top; m_rectNonScroll.bottom = nLinesPerPage * nLineHeight;
m_rectNonScroll.left = rect.left; m_rectNonScroll.right = rect.right - nMaxCharWidth;
// set timer for auto scroll
SetTimer( ID_TIMER_AUTO_SCROLL, 100, NULL );
SetCapture(); m_bAutoScroll = TRUE;
}
CView::OnLButtonDown(nFlags, point);
}
void CCedtView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
TRACE0("OnLButtonDblClk\n");
// set caret position from mouse pointer
SetCaretPosFromMouse(point);
if( point.x < GetLeftMargin() ) {
OnSearchToggleBookmark();
m_bSelected = ActionSelectLine();
} else {
m_bSelected = ActionSelectWord();
}
if( m_bSelected ) { // set save selected field
GetSelectedPosition(m_nSaveSelBegX, m_nSaveSelBegY, m_nSaveSelEndX, m_nSaveSelEndY);
m_bSaveSelected = TRUE;
} else m_bSaveSelected = FALSE;
// check if this is line select mouse move
if( point.x < GetLeftMargin() && ! m_bColumnMode ) m_bLineSelect = TRUE;
else m_bLineSelect = FALSE;
SetScrollPosToMakeCaretVisible();
Invalidate(); UpdateWindow();
UpdateAllPanesSharingScrollBar();
// calculate auto non-scroll boundary...
RECT rect; GetClientRect( & rect );
INT nLineHeight = GetLineHeight(), nLinesPerPage = GetLinesPerPage();
INT nLeftMargin = GetLeftMargin(), nMaxCharWidth = GetMaxCharWidth();
m_rectNonScroll.top = rect.top; m_rectNonScroll.bottom = nLinesPerPage * nLineHeight;
m_rectNonScroll.left = rect.left; m_rectNonScroll.right = rect.right - nMaxCharWidth;
// set timer for auto scroll
SetTimer( ID_TIMER_AUTO_SCROLL, 100, NULL );
SetCapture(); m_bAutoScroll = TRUE;
CView::OnLButtonDblClk(nFlags, point);
}
void CCedtView::OnLButtonUp(UINT nFlags, CPoint point)
{
TRACE0("OnLButtonUp\n");
if( m_bAutoScroll ) {
KillTimer( ID_TIMER_AUTO_SCROLL );
ReleaseCapture(); m_bAutoScroll = FALSE;
if( m_bLineSelect ) {
AdjustCaretPosAfterLineSelectMouseMove();
m_bLineSelect = FALSE;
SetScrollPosToMakeCaretVisible();
Invalidate(); UpdateWindow();
UpdateAllPanesSharingScrollBar();
}
if( m_bSelected ) { // set save selected field
GetSelectedPosition(m_nSaveSelBegX, m_nSaveSelBegY, m_nSaveSelEndX, m_nSaveSelEndY);
m_bSaveSelected = TRUE;
} else m_bSaveSelected = FALSE;
}
CView::OnLButtonUp(nFlags, point);
}
void CCedtView::OnMouseMove(UINT nFlags, CPoint point)
{
if( m_bAutoScroll && (nFlags & MK_LBUTTON) ) {
if( PtInRect( & m_rectNonScroll, point ) ) {
// set caret position from mouse pointer
SetCaretPosFromMouse(point);
// adjust caret position and anchor position relative to saved selection
if( m_bSaveSelected ) AdjustCaretAndAnchorPosRelativeToSavedSelection();
m_bSelected = ( (m_nAnchorPosY != m_nCaretPosY) || (m_nAnchorPosX != m_nCaretPosX) );
// check if this is line select mouse move
if( point.x < GetLeftMargin() && ! m_bColumnMode ) m_bLineSelect = TRUE;
else m_bLineSelect = FALSE;
Invalidate(); UpdateWindow();
}
OnSetCursor(this, HTCLIENT, 0);
}
CView::OnMouseMove(nFlags, point);
}
void CCedtView::OnTimerAutoScroll()
{
if( m_bAutoScroll ) {
CPoint point; GetCursorPos( & point ); ScreenToClient( & point );
if( ! PtInRect( & m_rectNonScroll, point ) ) {
// set caret position from mouse pointer
SetCaretPosFromMouse(point);
// adjust caret position and anchor position relative to saved selection
if( m_bSaveSelected ) AdjustCaretAndAnchorPosRelativeToSavedSelection();
m_bSelected = ( (m_nAnchorPosY != m_nCaretPosY) || (m_nAnchorPosX != m_nCaretPosX) );
// check if this is line select mouse move
if( point.x < GetLeftMargin() && ! m_bColumnMode ) m_bLineSelect = TRUE;
else m_bLineSelect = FALSE;
SetScrollPosToMakeAutoScroll();
Invalidate(); UpdateWindow();
UpdateAllPanesSharingScrollBar();
}
// OnSetCursor(this, HTCLIENT, 0); -- don't need to set cursor
}
}
DROPEFFECT CCedtView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
TRACE0("OnDragEnter\n");
if( pDataObject->IsDataAvailable(CF_TEXT) ) {
CMainFrame * pFrame = (CMainFrame *)AfxGetMainWnd(); ASSERT( pFrame );
CChildFrame * pChild = (CChildFrame *)GetParentFrame(); ASSERT( pChild );
// activate this child frame if it is not active
if( pFrame->MDIGetActive() != pChild ) pFrame->MDIActivate(pChild);
// calculate drag non-scroll boundary...
RECT rect; GetClientRect( & rect );
INT nLineHeight = GetLineHeight(), nLinesPerPage = GetLinesPerPage();
INT nLeftMargin = GetLeftMargin(), nMaxCharWidth = GetMaxCharWidth();
m_rectNonScroll.top = nLineHeight / 2; m_rectNonScroll.bottom = nLinesPerPage * nLineHeight;
m_rectNonScroll.left = nLeftMargin; m_rectNonScroll.right = rect.right - nMaxCharWidth;
if( rect.bottom % nLineHeight < nLineHeight ) m_rectNonScroll.bottom = nLinesPerPage * nLineHeight - nLineHeight / 2;
// set drag position from mouse pointer
SetDragPosFromMouse(point);
// update drag position
UpdateDragPosition();
if( dwKeyState & MK_CONTROL ) return DROPEFFECT_COPY;
else return DROPEFFECT_MOVE;
} else return CView::OnDragEnter(pDataObject, dwKeyState, point);
}
DROPEFFECT CCedtView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
if( pDataObject->IsDataAvailable(CF_TEXT) ) {
// set drag position from mouse pointer
SetDragPosFromMouse(point);
if( ! PtInRect( & m_rectNonScroll, point ) ) {
SetScrollPosToMakeDragScroll();
Invalidate(); UpdateWindow();
UpdateAllPanesSharingScrollBar();
}
// update drag position
UpdateDragPosition();
if( dwKeyState & MK_CONTROL ) return DROPEFFECT_COPY;
else return DROPEFFECT_MOVE;
} else return CView::OnDragOver(pDataObject, dwKeyState, point);
}
void CCedtView::OnDragLeave()
{
TRACE0("OnDragLeave\n");
CView::OnDragLeave();
}
BOOL CCedtView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
{
m_bDragDropOccured = TRUE;
TRACE0("OnDrop\n");
if( pDataObject->IsDataAvailable(CF_TEXT) ) {
// set drag position from mouse pointer
SetDragPosFromMouse(point);
if( m_bDragDataSource && IsPositionInSelection(m_nDragPosX, m_nDragPosY) ) {
OnDropEscape();
return FALSE;
} else if( dropEffect == DROPEFFECT_MOVE && m_bDragDataSource ) {
/* Drag and Drop action will be executed when DoDragDrop() is finished */
return TRUE;
} else if( dropEffect == DROPEFFECT_COPY ) {
OnDropPaste( pDataObject->GetGlobalData(CF_TEXT) );
return TRUE;
} else if( dropEffect == DROPEFFECT_MOVE ) {
OnDropPaste( pDataObject->GetGlobalData(CF_TEXT) );
return TRUE;
} else return FALSE;
} else return CView::OnDrop(pDataObject, dropEffect, point);
}
void CCedtView::OnTimer(UINT nIDEvent)
{
switch( nIDEvent ) {
case ID_TIMER_AUTO_SCROLL:
OnTimerAutoScroll();
break;
case ID_TIMER_CAPTURE_OUTPUT:
OnTimerCaptureOutput();
break;
}
CView::OnTimer(nIDEvent);
}
BOOL CCedtView::PreTranslateMessage(MSG* pMsg)
{
static CString szCompositionString;
static TCHAR szByte[3], cLeadByte = 0x00;
static UINT nChar, nFlags;
// translate message for command hot key
if( TranslateMessageForUserCommand(pMsg) ) return TRUE;
// translate message for macro hot key
if( TranslateMessageForMacroBuffer(pMsg) ) return TRUE;
switch( pMsg->message ) {
case WM_KEYDOWN: case WM_SYSKEYDOWN:
switch( pMsg->wParam ) {
case VK_LEFT: case VK_RIGHT: case VK_UP: case VK_DOWN:
case VK_HOME: case VK_END: case VK_PRIOR: case VK_NEXT:
nChar = pMsg->wParam; nFlags = GetKeyState();
if( (nFlags & KEYSTATE_CONTROL) && m_bSelected &&
(nChar == VK_UP || nChar == VK_DOWN) ) nFlags |= KEYSTATE_SHIFT;
OnMoveKeyDown( nChar, nFlags );
break; // do not return
}
break;
case WM_CHAR:
if( m_bComposition ) { // CHAR during IME composition
TRACE0("END3\n");
m_bComposition = FALSE;
OnImeCompositionEnd();
}
if( CCedtApp::m_bDoubleByteCharacterSet ) {
if( cLeadByte ) {
szByte[0] = cLeadByte; szByte[1] = pMsg->wParam; szByte[2] = '\0';
TRACE1("DBCHAR: [%s]\n", szByte);
OnDBCharKeyDown( cLeadByte, pMsg->wParam );
cLeadByte = 0x00;
} else if( IsDBCSLeadByte( pMsg->wParam ) ) {
cLeadByte = pMsg->wParam;
} else if( pMsg->wParam == 0x0D ) {
OnEditReturn();
} else if( pMsg->wParam == 0x1B ) {
OnEditEscape();
} else OnCharKeyDown( pMsg->wParam );
} else {
if( pMsg->wParam == 0x0D ) {
OnEditReturn();
} else if( pMsg->wParam == 0x1B ) {
OnEditEscape();
} else OnCharKeyDown( pMsg->wParam );
}
break;
case WM_IME_CHAR:
// If the WM_IME_CHAR message includes a double-byte character
// and the application passes this message to DefWindowProc,
// the IME converts this message into two WM_CHAR messages,
// each containing one byte of the double-byte character.
break;
case WM_IME_STARTCOMPOSITION:
TRACE0("BEG1 ");
m_bComposition = TRUE;
OnImeCompositionStart();
return TRUE;
case WM_IME_ENDCOMPOSITION:
TRACE0("END1\n");
m_bComposition = FALSE;
OnImeCompositionEnd();
return TRUE;
case WM_IME_COMPOSITION:
if( ! m_bComposition ) {
TRACE0("BEG2 ");
m_bComposition = TRUE;
OnImeCompositionStart();
}
if( pMsg->lParam & GCS_RESULTSTR ) {
INT nSize = GetCompositionString( GCS_RESULTSTR, szCompositionString );
TRACE1("[%s] ", szCompositionString);
OnImeCompositionResult( szCompositionString );
} else if( pMsg->lParam & GCS_COMPSTR ) {
INT nSize = GetCompositionString( GCS_COMPSTR, szCompositionString );
TRACE1("(%s) ", szCompositionString);
OnImeCompositionCompose( szCompositionString );
}
if( pMsg->lParam & GCS_RESULTSTR ) {
TRACE0("END2\n");
m_bComposition = FALSE;
OnImeCompositionEnd();
}
return TRUE;
}
return CView::PreTranslateMessage(pMsg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -