📄 cdragedit.cpp
字号:
//get selected text
CString str;
if (!_GetSelText(str)) {
CDragEditBase::OnLButtonDown(nFlags, point);
return;
}
int nLine1, nPos1, nLine2, nPos2;
GetCurRange(nLine1,nPos1,nLine2,nPos2);
//make a copy of selected text to a global memory
HGLOBAL hData=GlobalAlloc(GHND|GMEM_SHARE,strlen(str)+1);
strcpy((LPSTR)GlobalLock(hData),str);
GlobalUnlock(hData);
ms_dropSource.CacheGlobalData(CF_TEXT,hData);
//defined dragging area
CRect rc(point.x-5, point.y-5, point.x+5, point.y+5);
//It seems it is a MFC's bug that MFC will set capture to AfxGetMainWnd()
//and use its coordinate to test the lpRectStartDrag.
//So, we need to first translate the rc's coordinate.
MapWindowPoints(AfxGetMainWnd(),&rc);
//start dragging
ms_bDropEqualDrag=FALSE;
ms_bInDragging=TRUE;
DROPEFFECT dwEffect=ms_dropSource.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE,&rc);
ms_bInDragging=FALSE;
if (dwEffect & (DROPEFFECT_MOVE | DROPEFFECT_COPY)) {
if (dwEffect & DROPEFFECT_MOVE) {
if (ms_bDropEqualDrag) {
//If drag source equal to drop target and user want to
//move string
ms_bDropEqualDrag=FALSE;
int nSel=LinePosInRange(ms_nDropPtLine,ms_nDropPtPos,
nLine1,nPos1,nLine2,nPos2);
//we don't allow the string be moved into selection area
if (nSel==DE_INSEL)
return;
else {
if (nSel==DE_AFTERSEL) {
//If user want to move the string back,
//we need to adjust the ms_nDropPtLine
//and ms_nDropPtPos
int nChar=_LinePosToChar(ms_nDropPtLine,ms_nDropPtPos);
nChar-=str.GetLength();
//delet selected string first
ReplaceSel("",TRUE);
_CharToLinePos(nChar,&ms_nDropPtLine,&ms_nDropPtPos);
//set new insert point
SetCaret(ms_nDropPtLine,ms_nDropPtPos);
}
else {
//delet selected string first
ReplaceSel("",TRUE);
//set new insert point
SetCaret(ms_nDropPtLine,ms_nDropPtPos);
}
//insert dragged string and sel. it
int nBeg, nEnd;
GetSel(nBeg,nEnd);
nEnd+=str.GetLength();
ReplaceSel(str,TRUE);
SetSel(nBeg,nEnd);
}
}
else
ReplaceSel("",TRUE);
}
ms_bDropEqualDrag=FALSE;
return;
}
ms_bDropEqualDrag=FALSE;
//If user does not want to drag string, we reset the caret pos.
SetCaretByCursor();
return;
}
CDragEditBase::OnLButtonDown(nFlags, point);
}
BOOL CDragEdit::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (EnableDrag()) {
if (IsInSelRange()) {
//if the cursor is over a selection mark
//we will change the cursor shape to a arrow type
//It means user can drag it.
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
return FALSE;
}
}
//Otherwise, we keep the cursor shape as its original type
return CDragEditBase::OnSetCursor(pWnd, nHitTest, message);
}
/*************************************************************
CDEDropTarget
**************************************************************/
BOOL CDEDropTarget::Register(CDragEdit* pEdit)
{
ms_pEditCtl=pEdit;
return COleDropTarget::Register(pEdit);
}
DROPEFFECT CDEDropTarget::OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point)
{
ASSERT(ms_pEditCtl);
//if pWnd is kind of CView, we let COleDropTarget to handle it
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))
return COleDropTarget::OnDragScroll(pWnd,dwKeyState,point);
if (!ms_bBeginDrop)
return DROPEFFECT_NONE;
CRect rectClient;
ms_pEditCtl->GetClientRect(&rectClient);
CRect rect = rectClient;
//nScrollInset is a COleDropTarget's static member variable
rect.InflateRect(-nScrollInset, -nScrollInset);
// hit-test against inset region
if (rectClient.PtInRect(point) && !rect.PtInRect(point)) {
UINT uMsg;
int nCode;
CScrollBar* pScrollBar=NULL;
// determine which way to scroll along both X & Y axis
if (point.x<rect.left) {
pScrollBar=ms_pEditCtl->GetScrollBarCtrl(SB_HORZ);
uMsg=WM_HSCROLL;
nCode=SB_LINELEFT;
}
else if (point.x>=rect.right) {
pScrollBar=ms_pEditCtl->GetScrollBarCtrl(SB_HORZ);
uMsg=WM_HSCROLL;
nCode=SB_LINERIGHT;
}
if (point.y<rect.top) {
pScrollBar=ms_pEditCtl->GetScrollBarCtrl(SB_VERT);
uMsg=WM_VSCROLL;
nCode=SB_LINEUP;
}
else if (point.y>=rect.bottom) {
pScrollBar=ms_pEditCtl->GetScrollBarCtrl(SB_VERT);
uMsg=WM_VSCROLL;
nCode=SB_LINEDOWN;
}
LRESULT l=ms_pEditCtl->SendMessage(uMsg,MAKEWPARAM(nCode,0),
(LPARAM)(pScrollBar ? pScrollBar->GetSafeHwnd() : NULL));
ms_pEditCtl->DrawCaretByCursor();
if (dwKeyState & MK_CONTROL)
return DROPEFFECT_SCROLL | DROPEFFECT_COPY;
else
return DROPEFFECT_SCROLL | DROPEFFECT_MOVE;
}
return DROPEFFECT_NONE;
}
DROPEFFECT CDEDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
ASSERT(ms_pEditCtl);
if (!ms_pEditCtl->EnableDrop() ||
!pDataObject->IsDataAvailable(CF_TEXT))
return DROPEFFECT_NONE;
DROPEFFECT dwEffect;
if (dwKeyState & MK_CONTROL)
dwEffect=DROPEFFECT_COPY;
else
dwEffect=DROPEFFECT_MOVE;
ms_bBeginDrop=TRUE;
//we set focus to current window such that the caret will be shown
ms_pEditCtl->SetFocus();
return dwEffect;
}
void CDEDropTarget::OnDragLeave(CWnd* pWnd)
{
ASSERT(ms_pEditCtl);
ms_bBeginDrop=FALSE;
}
DROPEFFECT CDEDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
ASSERT(ms_pEditCtl);
if (!ms_bBeginDrop)
return DROPEFFECT_NONE;
DROPEFFECT dwEffect;
if (dwKeyState & MK_CONTROL)
dwEffect=DROPEFFECT_COPY;
else
dwEffect=DROPEFFECT_MOVE;
ms_pEditCtl->DrawCaretByCursor();
return dwEffect;
}
BOOL CDEDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point)
{
ASSERT(ms_pEditCtl);
if (!ms_bBeginDrop)
return FALSE;
if (ms_pEditCtl->IsInDragging() &&
ms_pEditCtl->IsInSelRange())
return DROPEFFECT_NONE;
HGLOBAL hData=pDataObject->GetGlobalData(CF_TEXT);
if (!hData) {
TRACE("Fail in getting data\n");
return FALSE;
}
LPCSTR lpcszData=(LPCSTR)GlobalLock(hData);
if ((dropEffect & DROPEFFECT_MOVE) &&
ms_pEditCtl->IsInDragging()) {
//If the drag window equal to drop window and
//user want to move string, we let drag source
//to move string by itself
ms_pEditCtl->SetDropEqualDrag(TRUE);
int nLine, nPos;
ms_pEditCtl->GetLinePosByCursor(nLine,nPos);
ms_pEditCtl->SetDropPos(nLine,nPos);
}
else {
//set dropped point
ms_pEditCtl->SetCaretByCursor();
//insert string and select the inserted string
int nBeg, nEnd;
ms_pEditCtl->GetSel(nBeg,nEnd);
nEnd+=strlen(lpcszData);
ms_pEditCtl->ReplaceSel(lpcszData,TRUE);
ms_pEditCtl->SetSel(nBeg,nEnd);
}
GlobalUnlock(hData);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -