📄 draglist.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 + -