📄 edit.cpp
字号:
}
}
else if(Hit == HT_Nothing)
goto cancel_modes;
else if(!fShift)
psel->CancelModes();
// let the client have a chance to handle this message if we are
// over a link
if(Hit == HT_Link && HandleLinkNotification(WM_LBUTTONDOWN, (WPARAM)dwFlags,
MAKELPARAM(x, y)) )
{
goto cancel_modes;
}
_fMouseDown = TRUE; // Flag mouse down
if( !fShift && _pobjmgr )
{
ClickStatus status;
// de-activate anybody active, etc.
status = _pobjmgr->HandleClick(this, pt);
if( status == CLICK_OBJSELECTED )
{
// the object subsystem will handle resizing.
// if not a resize we will signal start of drag
pobj = _pobjmgr->GetSingleSelect();
// Because HandleClick returned true, pobj better be non-null.
Assert(pobj!=NULL);
if (!pobj->HandleResize(pt))
{
_fWantDrag = !_fDisableDrag;
}
goto cancel_modes;
}
else if( status == CLICK_OBJDEACTIVATED )
goto cancel_modes;
}
_fCapture = TRUE; // Capture the mouse
TxSetCapture(TRUE);
// Check for start of drag and drop
if(!fTripleClick && !fShift && psel->PointInSel(pt, NULL, Hit)
&& !_fDisableDrag)
{
const INT vkey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON
: VK_LBUTTON;
// Assume we want a drag. If we don't CmdLeftUp() needs
// this to be set anyway to change the selection
_fWantDrag = TRUE;
goto cancel_modes;
}
if(fShift) // Extend selection from current
{ // active end to click
psel->InitClickForAutWordSel(pt);
psel->ExtendSelection(pt);
}
else if(fEnterLineSelMode) // Line selection mode: select line
{
// GuyBark JupiterJ: Don't select a line when undetermined text exists.
if(!IsIMEComposition())
{
psel->SelectUnit(pt, tomLine);
}
}
else if(fTripleClick || Hit == HT_OutlineSymbol) // paragraph selection mode
{
// GuyBark JupiterJ: Don't select a paragraph when undetermined text exists.
if(!IsIMEComposition())
{
psel->SelectUnit(pt, tomParagraph);
}
}
else
psel->SetCaret(pt);
if( fMustThaw )
{
_pdp->Thaw();
}
return S_OK;
cancel_modes:
psel->CancelModes();
if (_fWantDrag)
{
TxSetTimer(RETID_DRAGDROP, sysparam.GetDragDelay());
_mousePt = pt;
_dwFkeys = dwFlags;
_fDragged = FALSE;
}
if( fMustThaw )
{
_pdp->Thaw();
}
return S_OK;
}
HRESULT CTxtEdit::OnTxLButtonUp(
INT x,
INT y,
DWORD dwFlags,
BOOL fReleaseCapture)
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxLButtonUp");
CheckRemoveContinuousScroll();
// Remove capture before test for mouse down since we wait till
// we get the mouse button up message to release capture since Forms
// wants it that way.
if(_fCapture && fReleaseCapture)
{
TxSetCapture(FALSE);
_fCapture = FALSE;
}
if (!_fMouseDown)
{
// We noticed the mouse was no longer down earlier so we don't
// need to do anything.
return S_OK;
}
const BOOL fSetSel = !!_fWantDrag;
const POINT pt = {x, y};
// Cancel Auto Word Sel if on
CTxtSelection * const psel = GetSel();
AssertSz(psel,"CTxtEdit::OnLeftUp() - No selection object !");
psel->CancelModes(TRUE);
// Reset flags
_fMouseDown = FALSE;
_fWantDrag = FALSE;
_fDragged = FALSE;
TxKillTimer(RETID_DRAGDROP);
if(IsInOutlineView())
psel->Update(FALSE);
// let the client handle this message if we are over a
// link area
if( HandleLinkNotification(WM_LBUTTONUP, (WPARAM)dwFlags,
MAKELPARAM(x, y)) )
{
return NOERROR;
}
// If we were in drag & drop, put caret under mouse
if(fSetSel)
{
CObjectMgr* pobjmgr = GetObjectMgr();
//If we were on an object, don't deselect it
//by setting the caret.
if (pobjmgr && !pobjmgr->GetSingleSelect())
{
psel->SetCaret(pt, TRUE);
if(!_fFocus)
TxSetFocus(); // create and display caret
}
}
return S_OK;
}
HRESULT CTxtEdit::OnTxRButtonUp(INT x, INT y, DWORD dwFlags)
{
const POINT pt = {x, y};
CTxtSelection * psel;
SELCHANGE selchg;
HMENU hmenu = NULL;
IOleObject * poo = NULL;
COleObject * pobj = NULL;
IUnknown * pUnk = NULL;
IRichEditOleCallback * precall = NULL;
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxRButtonUp");
// make sure we have the focus
if( !_fFocus )
{
TxSetFocus();
}
if( _fWantDrag )
{
_fDragged = FALSE;
_fWantDrag = FALSE;
TxKillTimer(RETID_DRAGDROP);
}
// Grab selection object
psel = GetSel();
psel->SetSelectionInfo( &selchg );
//We need a pointer to the first object, if any, in the selection.
if( _pobjmgr )
{
//If the point is in the selection we need to find out if there
//are any objects in the selection. If the point is not in a
//selection but it is on an object, we need to select the object.
if( psel->PointInSel( pt, NULL ) )
{
pobj = _pobjmgr->GetFirstObjectInRange( selchg.chrg.cpMin,
selchg.chrg.cpMost );
}
else
{
//Select the object
if( _pobjmgr->HandleClick( this, pt ) == CLICK_OBJSELECTED )
{
pobj = _pobjmgr->GetSingleSelect();
// Because HandleClick returned true, pobj better be non-null.
Assert(pobj!=NULL);
//Refresh our information about the selection
psel = GetSel();
psel->SetSelectionInfo( &selchg );
}
}
precall = _pobjmgr->GetRECallback();
}
if( pobj )
{
pUnk = pobj->GetIUnknown();
}
if( pUnk )
{
pUnk->QueryInterface( IID_IOleObject, (void **)&poo );
}
if( precall )
{
precall->GetContextMenu( selchg.seltyp, poo, &selchg.chrg, &hmenu );
}
if( hmenu )
{
HWND hwnd, hwndParent;
POINT ptscr;
if( TxGetWindow( &hwnd ) == NOERROR )
{
ptscr.x = pt.x;
ptscr.y = pt.y;
ClientToScreen( hwnd, &ptscr );
hwndParent = GetParent(hwnd);
if( !hwndParent )
{
hwndParent = hwnd;
}
TrackPopupMenu( hmenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
ptscr.x, ptscr.y, 0, hwndParent, NULL );
}
DestroyMenu( hmenu );
}
if( poo )
{
poo->Release();
}
return precall ? S_OK : S_FALSE;
}
HRESULT CTxtEdit::OnTxRButtonDown(INT x, INT y, DWORD dwFlags)
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxRButtonDown");
CTxtSelection *psel = GetSel();
const POINT pt = {x, y};
psel->CancelModes();
if(psel->PointInSel(pt, NULL) && !_fDisableDrag)
{
_fWantDrag = TRUE;
TxSetTimer(RETID_DRAGDROP, sysparam.GetDragDelay());
_mousePt = pt;
_dwFkeys = dwFlags;
_fDragged = FALSE;
return S_OK;
}
return S_FALSE;
}
HRESULT CTxtEdit::OnTxMouseMove(INT x, INT y, DWORD dwFlags,
IUndoBuilder *publdr)
{
int dx, dy;
WORD wDragMinDist;
DWORD vkLButton, vkRButton;
BOOL fLButtonDown = FALSE, fRButtonDown = FALSE;
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxMouseMove");
CTxtSelection * const psel = GetSel();
if(!_fFocus)
return S_OK;
if (_fWantDrag)
{
wDragMinDist = sysparam.GetDragMinDist() + 3;
dx = _mousePt.x > x ? _mousePt.x - x : x - _mousePt.x;
dy = _mousePt.y > y ? _mousePt.y - y : y - _mousePt.y;
if (dx < wDragMinDist && dy < wDragMinDist)
{
_dwFkeys = dwFlags;
return S_OK;
}
_fDragged = TRUE;
}
_mousePt.x = x; // Remember for scrolling
_mousePt.y = y; // speed, and dir calc.
// RichEdit1.0 allows the client to process mouse moves itself if
// we are over a link (but _not_ doing drag drop).
if( HandleLinkNotification(WM_MOUSEMOVE, 0, MAKELPARAM(x, y)) )
{
return NOERROR;
}
// If we think the mouse is down and it really is then do special
// processing.
if( GetSystemMetrics(SM_SWAPBUTTON) )
{
vkLButton = VK_RBUTTON;
vkRButton = VK_LBUTTON;
}
else
{
vkLButton = VK_LBUTTON;
vkRButton = VK_RBUTTON;
}
fLButtonDown = (GetAsyncKeyState(vkLButton) < 0);
if( !fLButtonDown )
{
fRButtonDown = (GetAsyncKeyState(vkRButton) < 0);
}
if( fLButtonDown || fRButtonDown )
{
if(_fWantDrag
&& !_fUsePassword
&& !IsProtected(_fReadOnly ? WM_COPY : WM_CUT, dwFlags,
MAKELONG(x,y)) )
{
TxKillTimer(RETID_DRAGDROP);
_ldte.StartDrag(psel, publdr);
// the mouse button may still be down, but drag drop is over
// so we need to _think_ of it as up.
_fMouseDown = FALSE;
// similarly, OLE should have nuked the capture for us, but
// just in case something failed, release the capture.
TxSetCapture(FALSE);
_fCapture = FALSE;
}
else if (_fMouseDown)
{
POINT pt = _mousePt;
// We think the mouse is down and the mouse is down
if (_ldte.fInDrag())
{
// Only do drag scrolling if a drag operation is in progress.
_pdp->DragScroll(&pt);
}
AssertSz(psel,"CTxtEdit::OnMouseMove: No selection object !");
psel->ExtendSelection(pt); // Extend the selection
CheckInstallContinuousScroll ();
}
}
else if ( GetAsyncKeyState( VK_MBUTTON ) < 0 )
{
; /* do nothing, middle button pressed. */
}
else
{
if (_fMButtonCapture)
{
OnTxMButtonUp (x, y, dwFlags);
}
if (_fMouseDown )
{
// Although we thought the mouse was down, at this moment it
// clearly is not. Therefore, we pretend we got a mouse up
// message and clear our state to get ourselves back in sync
// with what is really happening.
OnTxLButtonUp(x, y, dwFlags, TRUE);
}
}
// Either a drag was started or the mouse button was not down. In either
// case, we want no longer to start a drag so we set the flag to false.
_fWantDrag = FALSE;
return S_OK;
}
/*
* CTxtEdit::OnTxMButtonDown (INT x, INT y, DWORD dwFlags)
*
* @mfunc
* The user pressed the middle mouse button, setup to do
* continuous scrolls, which may in turn initiate a timer
* for smooth scrolling.
*/
HRESULT CTxtEdit::OnTxMButtonDown (INT x, INT y, DWORD dwFlags)
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxMButtonDown");
#if !defined(NOMAGELLAN)
POINT mDownPt = {x,y};
if( !_fFocus )
{
TxSetFocus();
}
if ( mouse.MagellanStartMButtonScroll( *this, mDownPt ) )
{
TxSetCapture(TRUE);
_fCapture = TRUE; // Capture the mouse
_fMouseDown = TRUE;
_fMButtonCapture = TRUE;
}
#endif
return S_OK;
}
/*
* CTxtEdit::OnTxMButtonUp (INT x, INT y, DWORD dwFlags)
*
* @mfunc
* Remove timers and capture assoicated with a MButtonDown
* message.
*/
HRESULT CTxtEdit::OnTxMButtonUp (INT x, INT y, DWORD dwFlags)
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxMButtonUp");
#if !defined(NOMAGELLAN)
mouse.MagellanEndMButtonScroll( *this );
#endif
if(_fCapture)
{
TxSetCapture(FALSE);
}
_fCapture = FALSE;
_fMouseDown = FALSE;
_fMButtonCapture = FALSE;
return S_OK;
}
/*
* CTxtEdit::CheckInstallContinuousScroll ( )
*
* @mfunc
* There are no events that inform the app on a regular
* basis that a mouse button is down. This timer notifies
* the app that the button is still down, so that scrolling can
* continue.
*/
void CTxtEdit::CheckInstallContinuousScroll ( )
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::CheckInstallContinuousScroll");
if ( !_fContinuousScroll && TxSetTimer(RETID_AUTOSCROLL, cmsecScrollInterval) )
{
_fContinuousScroll = TRUE;
}
}
/*
* CTxtEdit::CheckRemoveContinuousScroll ( )
*
* @mfunc
* The middle mouse button, or drag button, is up
* remove the continuous scroll timer.
*/
void CTxtEdit::CheckRemoveContinuousScroll ( )
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::CheckRemoveContinuousScroll");
if( _fContinuousScroll )
{
TxKillTimer(RETID_AUTOSCROLL);
_fContinuousScroll = FALSE;
}
}
/*
* CTxtEdit::OnTxTimer(UINT idTimer)
*
* @mfunc
* Handle timers for doing background recalc and scrolling.
*/
HRESULT CTxtEdit::OnTxTimer(UINT idTimer)
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxTimer");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -