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

📄 draglist.cpp

📁 类似 windows explorer的工具
💻 CPP
字号:
#include "stdafx.h"
#include "DragList.h"
//#include "ChildView.h"
#include "MainFrm.h"

BEGIN_MESSAGE_MAP(CDragList, CDragList_BaseClass)
	//{{AFX_MSG_MAP(CDragList)
	ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBeginDrag)
    ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteItem)
	
    ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CDragList::CDragList()
{
	m_pImgDragList = NULL;
}

CDragList::~CDragList()
{
    if (m_pImgDragList != NULL)
    {
        delete m_pImgDragList;
        m_pImgDragList = NULL;
    }
}

//功  能: 创建拖放图像列表
//返回值: 拖放图像列表,开始拖放的位置
CImageList* CDragList::CreateDragImage(LPPOINT lpPoint)
{
    CRect rcItem;
	CRect rcLable;
	CRect rcItemUnion(0,0,0,0); // 最后需要的矩形

	// 取得拖放图像矩形范围
    int nSelCount = GetSelectedCount(); // 试图拖动的文件个数
	int nItem = GetNextItem(-1,LVNI_SELECTED);
	const int nMaxShowCount = 5; // 最多显示的个数

    int nNo = 0; // 最多显示5个,所以需要计数
    while (nItem != -1)
	{
		GetItemRect(nItem,&rcItem, LVIR_BOUNDS);
		if(rcItemUnion.IsRectEmpty())
		{
			GetItemRect(nItem, &rcItemUnion, LVIR_BOUNDS);
		}
		rcItemUnion.UnionRect(rcItemUnion, rcItem);
		nItem=GetNextItem(nItem,LVNI_SELECTED);

        nNo++;
        if (nNo >= nMaxShowCount) // 最多显示5个
        {
            break;
        }
	}

	// 创建拖放图像
	CClientDC dcClient(this);	
    CDC       dcMem;	// 使用内存DC,防止闪烁

	CBitmap   bmp;
	CBitmap   *pOldBitmap;
	CPen      *pOldPen;
	CBrush    *pOldBrush;
    CBrush    brush(RGB(255, 255, 255));
    const int nPenWidth = 1;
    CPen      pen(PS_SOLID, nPenWidth, RGB(255, 0, 255));

	if (!dcMem.CreateCompatibleDC(&dcClient))
	{
		return NULL;
	}
    // 创建位图
	if (!bmp.CreateCompatibleBitmap(&dcClient,rcItemUnion.Width(),rcItemUnion.Height()))
	{
		dcMem.DeleteDC();
		return NULL;
	}
    // 创建字体(和ListCtrl中的文字字体一样)
    CFont lblFont;
    CFont *pOldFont;
    LOGFONT LogFont;
    
    GetFont()->GetLogFont(&LogFont);
    lblFont.CreateFontIndirect(&LogFont);
         
    pOldFont = dcMem.SelectObject(&lblFont);
	pOldBitmap = dcMem.SelectObject(&bmp);
	pOldBrush = dcMem.SelectObject(&brush);
	pOldPen   = dcMem.SelectObject(&pen);
	dcMem.FillSolidRect(0,0,rcItemUnion.Width(),rcItemUnion.Height(),RGB(255, 255, 255)); 
	nItem = GetNextItem(-1,LVNI_SELECTED);

    nNo = 0;
	while (nItem != -1)
	{
		nNo++;
        if (nNo > nMaxShowCount)
        {
            break;
        }

        GetItemRect(nItem,&rcLable,LVIR_LABEL); // 文字的矩形范围
		GetItemRect(nItem,&rcItem, LVIR_ICON);  // 图标的矩形范围

        dcMem.Rectangle(rcItem.left-rcItemUnion.left,
				        rcItem.top-rcItemUnion.top,
                        rcItem.left-rcItemUnion.left+rcItem.Width(),
                        rcItem.top-rcItemUnion.top+rcItem.Height());
        
        int nLine_x = rcLable.left - rcItemUnion.left;
        int nLine_y = rcLable.top + rcLable.Height()- rcItemUnion.top
                        - nPenWidth;

        dcMem.MoveTo(nLine_x, nLine_y);
		dcMem.LineTo(rcLable.right-rcItemUnion.left, nLine_y);

        // 画文字
        CString strCaption;
        
        if (nNo == nMaxShowCount)
        {
            strCaption = "......";
        }
        else
        {
            strCaption = GetItemText(nItem, 0);
        }

        nLine_y -= (rcItem.Height() - 1);
        dcMem.TextOut(nLine_x, nLine_y, strCaption);

        /* 画图标 (失败)
        LVITEM lv;
        
        ::ZeroMemory(&lv,sizeof(LVITEM));
        lv.mask = LVIF_IMAGE | LVIF_INDENT;

        lv.iItem = nItem;
        GetItem(&lv);
        
        IMAGEINFO iminfo;
        
        ::ZeroMemory(&iminfo, sizeof(IMAGEINFO));
        CImageList* pImageList = GetImageList(LVSIL_SMALL);
        if (pImageList->GetSafeHandle())
        {
            pImageList->GetImageInfo(lv.iImage, &iminfo);
        }
        
        //
        CDC       dcTmp;
        dcTmp.CreateCompatibleDC(&dcMem);

        BITMAP bmpInfo;
        ::GetObject(iminfo.hbmImage, sizeof(BITMAP), &bmpInfo);
        dcTmp.SelectObject(iminfo.hbmImage);
        dcMem.BitBlt(nLine_x,nLine_y,
				        bmpInfo.bmWidth, 
						bmpInfo.bmHeight,
                        &dcTmp,0,0,SRCCOPY);

        dcTmp.DeleteDC();
        */

		nItem = GetNextItem(nItem,LVNI_SELECTED);
	}
    
    dcMem.SelectObject(pOldFont);
    dcMem.SelectObject(pOldPen);
	dcMem.SelectObject(pOldBrush);
	dcMem.SelectObject(pOldBitmap);

	CImageList* pDragImageList = new CImageList;
	pDragImageList->Create(rcItemUnion.Width(), rcItemUnion.Height(),
		                   ILC_COLOR | ILC_MASK, 0, 1);
	pDragImageList->Add(&bmp, RGB(255, 255, 255)); 

    // 删除创建的GDI对象
	dcMem.DeleteDC();
    bmp.DeleteObject();

	// 计算开始拖放的位置
	if (lpPoint)
	{
		CPoint ptCursor;

		GetCursorPos(&ptCursor);
		ScreenToClient(&ptCursor);
		lpPoint->x = ptCursor.x - rcItemUnion.left;
		lpPoint->y = ptCursor.y - rcItemUnion.top;
	}

	return pDragImageList;
}

void CDragList::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	
	//创建拖放图像
	CPoint ptStart;

    if (m_pImgDragList != NULL)
    {
        delete m_pImgDragList;
        m_pImgDragList = NULL;
    }

	m_pImgDragList = CreateDragImage(&ptStart);
	
    if (m_pImgDragList != NULL)
	{
		m_pImgDragList->BeginDrag(0, ptStart);
		m_pImgDragList->DragEnter(CWnd::GetDesktopWindow(), pNMListView->ptAction);
		SetCapture();
	}
	
	*pResult = 0;
}
void CDragList::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (m_pImgDragList != NULL)
	{
		CPoint ptPos(point);
		ClientToScreen(&ptPos);
		m_pImgDragList->DragMove(ptPos);
	}
	CDragList_BaseClass::OnMouseMove(nFlags, point);
}

void CDragList::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (m_pImgDragList != NULL)
	{
		::ReleaseCapture();
		m_pImgDragList->DragLeave(CWnd::GetDesktopWindow());
		m_pImgDragList->EndDrag();

		m_pImgDragList->DeleteImageList();
		delete m_pImgDragList;
		m_pImgDragList = NULL;

		// 得到目标窗口句柄
        CPoint pt(point);
		ClientToScreen(&pt);

        HWND hWndDest = ::WindowFromPoint(pt);

        if (hWndDest != this->m_hWnd)
        {
            // TODO 发送消息,在打包成Release版本后,居然非法操作!??
            //::SendMessage(::GetParent(this->m_hWnd), WM_DROPFILEONLISTVIEW, (WPARAM)hWndDest, 0);
            //CChildView* pChildView = (CChildView*)::GetParent(hWndDest);
            
            //pChildView->OnDropFile(hWndDest);
            ((CMainFrame*)AfxGetMainWnd())->DragFiles(this, hWndDest);
        }

	}
	CDragList_BaseClass::OnLButtonUp(nFlags, point);
}

void CDragList::OnDeleteItem(NMHDR* pNMHDR, LRESULT* pResult) 
{
    CDragList_BaseClass::OnDeleteItem(pNMHDR, pResult);        
    *pResult = 0;
}

int CDragList::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDragList_BaseClass::OnCreate(lpCreateStruct) == -1)
		return -1;

    return 0;
}

⌨️ 快捷键说明

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