⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdragedit.cpp

📁 深入剖析Visual C++编程技术及应用实例
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        //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 + -