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

📄 cdragedit.cpp

📁 深入剖析Visual C++编程技术及应用实例
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// CDragEdit.cpp : implementation file
//
// Author : Sam Lu
// E-mail : ysl@springsoft.com.tw
//

#include "stdafx.h"
#include "Exam1_1_10.h"
#include "CDragEdit.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define MAXLINELEN 2048

enum {
    DE_INSEL, DE_BEFORESEL, DE_AFTERSEL
};

/////////////////////////////////////////////////////////////////////////////
// CDragEdit

CDragEdit::CDragEdit()
{
    ms_bDragInit=FALSE;
    ms_nEnableFlags=0;
    ms_bInDragging=FALSE;
    ms_bDropEqualDrag=FALSE;
}

CDragEdit::~CDragEdit()
{
}


BEGIN_MESSAGE_MAP(CDragEdit, CDragEditBase)
	//{{AFX_MSG_MAP(CDragEdit)
	ON_WM_LBUTTONDOWN()
	ON_WM_SETCURSOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDragEdit message handlers
BOOL CDragEdit::ms_bOleInit=FALSE;

BOOL CDragEdit::Init(int nFlags) 
{
    if (!ms_bOleInit) {
        if (!AfxOleInit()) {
            TRACE("Fail in OLE initialating\n");
            return FALSE;
        }
        ms_bOleInit=TRUE;
    }

    if (ms_bDragInit) return FALSE;

    ms_nEnableFlags=nFlags;

    if (!GetSafeHwnd()) {
        TRACE("You should create CDragEdit first, before this function is called\n");
		return FALSE;
    }
	if (!ms_dropTarget.Register(this)) {
		TRACE("Fail in registing drop target\n");
		return FALSE;
	}
    ms_bDragInit=TRUE;
	return TRUE;
}

//we reimpelmented this function for fixing SDK's bug that
//it always returns (-1,-1) when the uChar is the last char
CPoint CDragEdit::PosFromChar(UINT uChar)
{
    if (0==uChar)
        return CPoint(0,0);
    CPoint pt=CDragEditBase::PosFromChar(uChar);
    if (pt.x<0 && pt.y<0) {
        int nLine, nPos;
        _CharToLinePos((int)uChar,&nLine,&nPos);
        //get dc and select current using font
        CClientDC dc(this);
        dc.SelectObject(GetFont());
        //get position of previous char
        pt=CDragEditBase::PosFromChar(uChar-1);        
        if (nPos==0) {
            //if current char is the first char
            //we get the current y from previous y plus font height
            CSize szFont=dc.GetTextExtent("A",1);
            pt.y+=szFont.cy;
            pt.x=0;
        }
        else {
            char szBuf[MAXLINELEN];
            GetLine(nLine,szBuf,sizeof(szBuf));
            CSize szFont=dc.GetTextExtent(&szBuf[nPos-1],1);
            pt.x+=szFont.cx;
        }
        dc.SelectStockObject(SYSTEM_FONT);
    }
    return pt;
}

//get line and pos information from current selection range
BOOL CDragEdit::GetCurRange(int& nLine1, int& nPos1, int& nLine2, int& nPos2)
{
    //get current selection range
    GetSel(nPos1,nPos2);
    //and trans. to line, pos
    _CharToLinePos(nPos1,&nLine1,&nPos1);
    _CharToLinePos(nPos2,&nLine2,&nPos2);
    return TRUE;
}

//get line and pos from current cursor position
//return TRUE, if cursor is exactly at a char
//return FALSE, if cursor is at white space area
BOOL CDragEdit::GetLinePosByCursor(int& nLine, int& nPos)
{
    CPoint ptCursor;
    GetCursorPos(&ptCursor);
    ScreenToClient(&ptCursor);

    nPos=(int)(short)LOWORD((DWORD)CharFromPos(ptCursor));
    if (nPos<0) nPos=0;
    _CharToLinePos(nPos,&nLine,&nPos);

    //the following codes will check if cusor is at white space area
    //get the maximum x of nLine
    CPoint ptChar;
    ptChar=PosFromChar(LineIndex(nLine)+LineLength(LineIndex(nLine)));
    if (ptChar.x<ptCursor.x || ptCursor.x<0)
        return FALSE;
    return TRUE;
}

//set edit's caret position by current cursor position
BOOL CDragEdit::SetCaretByCursor()
{
    //get cursor's position and translate it to client coordinate
    CPoint ptCursor;
    GetCursorPos(&ptCursor);
    ScreenToClient(&ptCursor);
    //set caret position
    int nChar=(int)LOWORD((DWORD)CharFromPos(ptCursor));
    SetSel(nChar,nChar);
    return TRUE;
}

BOOL CDragEdit::SetCaret(int nLine, int nPos)
{
    int nChar=_LinePosToChar(nLine,nPos);
    SetSel(nChar,nChar);
    return TRUE;
}

//draw a caret at current cursor position
//this function will not affect the caret position or selection status
BOOL CDragEdit::DrawCaretByCursor()
{
    int nLine, nPos;
    GetLinePosByCursor(nLine,nPos);
    SetCaretPos(GetPosFromLinePos(nLine,nPos));
    return TRUE;
}

//test if (nLine,Pos) is within (nLine1,nPos1)~(nLine2,nPos2)
static int LinePosInRange(int nLine, int nPos,
                           int nLine1, int nPos1,
                           int nLine2, int nPos2)
{
    if (nLine1==nLine2) {//single line selection mark
        if (nLine<nLine1) return DE_BEFORESEL;
        if (nLine>nLine1) return DE_AFTERSEL;
        //nLine==nLine1
        if (nPos<nPos1) return DE_BEFORESEL;
        if (nPos>nPos2) return DE_AFTERSEL;
    }
    else { //multi-line selection mark
        if (nLine<nLine1) return DE_BEFORESEL;
        if (nLine>nLine2) return DE_AFTERSEL;
        if (nLine==nLine1 && 
            nPos<nPos1) return DE_BEFORESEL;
        if (nLine==nLine2 && 
            nPos>nPos2) return DE_AFTERSEL;
    }
    return DE_INSEL;
}

//return TRUE, if cursor is within the selection mark
BOOL CDragEdit::IsInSelRange()
{
    int nLine1, nPos1, nLine2, nPos2;
    GetCurRange(nLine1,nPos1,nLine2,nPos2);
    if (nLine1==nLine2 && nPos1==nPos2) //no selection mark
        return FALSE;

    int nLine, nPos;
    if (!GetLinePosByCursor(nLine,nPos)) //out of selection mark
        return FALSE;
    return (LinePosInRange(nLine,nPos,nLine1,nPos1,
                           nLine2,nPos2)==DE_INSEL) ? TRUE : FALSE;
}

BOOL CDragEdit::_GetSelText(CString& str)
{
    int nLine1, nPos1, nLine2, nPos2;
    GetCurRange(nLine1,nPos1,nLine2,nPos2);
    ASSERT(nLine1>=0 && nPos1>=0 && nLine2>=0 && nPos2>=0);
    char szBuf[MAXLINELEN];
    int nLen;
    //single-line selection
    if (nLine1==nLine2) {
        nLen=GetLine(nLine1,szBuf,sizeof(szBuf));
        szBuf[nLen]='\0';
        szBuf[nPos2]='\0';
        str=szBuf+nPos1;
        return TRUE;
    }
    //multi-line section
    nLen=GetLine(nLine1,szBuf,sizeof(szBuf));
    szBuf[nLen]='\0';
    str=szBuf+nPos1;
    for (int i=nLine1+1; i<nLine2; i++) {
        str+="\r\n";
        nLen=GetLine(i,szBuf,sizeof(szBuf));
        szBuf[nLen]='\0';
        str+=szBuf;
    }
    str+="\r\n";
    nLen=GetLine(nLine2,szBuf,sizeof(szBuf));
    szBuf[nLen]='\0';
    szBuf[nPos2]='\0';
    str+=szBuf;
    return TRUE;
}

void CDragEdit::OnLButtonDown(UINT nFlags, CPoint point) 
{
    if (!EnableDrag()) {
        CDragEditBase::OnLButtonDown(nFlags, point);
        return;
    }

    if (IsInSelRange()) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -