//根据结果进行相应处理,成功后由目标对象释放内存 switch (DpEffect) { case DROPEFFECT_COPY: case DROPEFFECT_MOVE: { for (listSelItem=listct.GetNextItem(-1,LVNI_SELECTED); listSelItem!=-1; listSelItem=listct.GetNextItem(listSelItem,LVNI_SELECTED)) { listct.DeleteItem(listSelItem); listSelItem--; } listct.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER ); listct.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER ); //listct.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER ); } break; case DROPEFFECT_NONE: { //在winNT/2000下,若成功,也返回DROPEFFECT_NONE,需要判断操作系统 if (0==(GetVersion()&0x80000000)) //winNT/2000下 { bool bDeleted=false; for (listSelItem=listct.GetNextItem(-1, LVNI_SELECTED); listSelItem!=-1; listSelItem=listct.GetNextItem(listSelItem,LVNI_SELECTED)) { CString Filename=listct.GetItemText(listSelItem,0); //文件已经被移出,不能找到文件和得到文件属性 if (0xFFFFFFFF==GetFileAttributes(Filename)&&GetLastError()==ERROR_FILE_NOT_FOUND ) { listct.DeleteItem(listSelItem); listSelItem--; bDeleted=true;//从列表中移出成功 } } if (bDeleted) { listct.SetColumnWidth(0,LVSCW_AUTOSIZE_USEHEADER); listct.SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER); //listct.SetColumnWidth(2,LVSCW_AUTOSIZE_USEHEADER); } else {//winNT/2000下失败,释放内存 GlobalFree(DropGlb); } } else {//win95/98下失败,释放内存 GlobalFree(DropGlb); } } break; } }
DROPEFFECT CDraglist1View::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { // TODO: Add your specialized code here and/or call the base class DROPEFFECT dpEffect = DROPEFFECT_NONE;//初始返回值 //检查有无数据 if (NULL!=pDataObject->GetGlobalData(CF_HDROP)) { //if(0==(GetVersion()&0x80000000))//检查操作系统版本,是否为winNT/2000 //dpEffect=DROPEFFECT_COPY; //else dpEffect=DROPEFFECT_COPY; }
return dpEffect; }void CDraglist1View::OnDragLeave() { // TODO: Add your specialized code here and/or call the base class CListView::OnDragLeave(); }DROPEFFECT CDraglist1View::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { // TODO: Add your specialized code here and/or call the base class
if (NULL==hdp) { GlobalUnlock(Dropglb2); return FALSE; }
Filesnum=DragQueryFile(hdp,-1,NULL,0);//得到文件数
for (UINT Fileitem=0;Fileitem<Filesnum;Fileitem++) { if (DragQueryFile(hdp,Fileitem,FileNext,MAX_PATH)>0) { if (-1!=listct.FindItem(&stlvFindInfo,-1))//文件名存在则跳过 continue;
http://www.vckbase.com/document/viewdoc.asp?id=340
//#include "stdafx.h"
#include "draglist1.h"#include "draglist1Doc.h"
#include "draglist1View.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//#include <shlwapi.h>
/////////////////////////////////////////////////////////////////////////////
// CDraglist1View
//需要在程序类实现文件中添加AfxOleInit();IMPLEMENT_DYNCREATE(CDraglist1View, CListView)BEGIN_MESSAGE_MAP(CDraglist1View, CListView)
//{{AFX_MSG_MAP(CDraglist1View)
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBegindrag)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CDraglist1View construction/destructionCDraglist1View::CDraglist1View()
{
// TODO: add construction code here}CDraglist1View::~CDraglist1View()
{
}BOOL CDraglist1View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs return CListView::PreCreateWindow(cs);
}/////////////////////////////////////////////////////////////////////////////
// CDraglist1View drawingvoid CDraglist1View::OnDraw(CDC* pDC)
{
CDraglist1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}void CDraglist1View::OnInitialUpdate()
{
CListView::OnInitialUpdate();
CListCtrl& listct=GetListCtrl();
listdroptarget.Register(this);//成为拖曳操作的接收目标
SHFILEINFO stInfo;
HIMAGELIST hImglist;
hImglist=(HIMAGELIST)SHGetFileInfo(_T(""),0,&stInfo,sizeof(SHFILEINFO), SHGFI_ICON|
SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
imglist.Attach(hImglist);
listct.ModifyStyle(LVS_TYPEMASK,LVS_REPORT|LVS_NOSORTHEADER|LVS_SHAREIMAGELISTS);
listct.SetImageList(&imglist,LVSIL_SMALL);
listct.SetExtendedStyle(LVS_EX_INFOTIP);
listct.InsertColumn(0,_T("文件名"),LVCFMT_LEFT,0,0);
listct.InsertColumn(1,_T("类型"),LVCFMT_LEFT,0,1);
//listct.InsertColumn(2,_T("大小"),LVCFMT_LEFT,0,2); listct.SetColumnWidth(0,LVSCW_AUTOSIZE_USEHEADER);
listct.SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER);
//listct.SetColumnWidth(2,LVSCW_AUTOSIZE_USEHEADER); // TODO: You may populate your ListView with items by directly accessing
// its list control through a call to GetListCtrl().
}/////////////////////////////////////////////////////////////////////////////
// CDraglist1View printingBOOL CDraglist1View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}void CDraglist1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}void CDraglist1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}/////////////////////////////////////////////////////////////////////////////
// CDraglist1View diagnostics#ifdef _DEBUG
void CDraglist1View::AssertValid() const
{
CListView::AssertValid();
}void CDraglist1View::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}CDraglist1Doc* CDraglist1View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDraglist1Doc)));
return (CDraglist1Doc*)m_pDocument;
}
#endif //_DEBUG
// CDraglist1View message handlersvoid CDraglist1View::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; // TODO: Add your control notification handler code here
*pResult = 0; CListCtrl& listct = GetListCtrl();
COleDataSource listdatasrc; //定义数据
HGLOBAL DropGlb;
DROPFILES* pDropfiles;
CStringList listDraggedFiles;
CString listFile;
UINT listBuffSize=0;
TCHAR* listpBuff;
FORMATETC etc={CF_HDROP,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
POSITION Itempos;
int listSelItem; Itempos=listct.GetFirstSelectedItemPosition();
while (NULL!=Itempos)//取出文件名
{
listSelItem=listct.GetNextSelectedItem(Itempos);
listFile=listct.GetItemText(listSelItem, 0);
listDraggedFiles.AddTail(listFile);
listBuffSize+=lstrlen(listFile)+1;//计算总长度,准备分配内存
} listBuffSize=sizeof(DROPFILES)+sizeof(TCHAR)*(listBuffSize+1);
DropGlb=GlobalAlloc(GHND|GMEM_SHARE,listBuffSize);//在堆上分配内存 if(NULL==DropGlb) //若句柄为空,分配失败
return; pDropfiles=(DROPFILES*)GlobalLock(DropGlb); //得到内存地址,准备写数据 if (NULL==pDropfiles)
{
GlobalFree(DropGlb);
return;
} pDropfiles->pFiles=sizeof(DROPFILES); //填充DROPFILES结构 #ifdef _UNICODE //如果是unicode模式,设置相应标志
pDropfiles->fWide=TRUE;
#endif Itempos=listDraggedFiles.GetHeadPosition(); //将所有选中文件名写进内存
listpBuff=(TCHAR*)(LPBYTE(pDropfiles)+sizeof(DROPFILES));//得到DROPFILES结构后的内存地址
while(NULL!=Itempos)
{
lstrcpy(listpBuff,(LPCTSTR)listDraggedFiles.GetNext(Itempos));
listpBuff=1+_tcschr(listpBuff,'\0');//下一个文件名的地址
} GlobalUnlock(DropGlb); listdatasrc.CacheGlobalData(CF_HDROP,DropGlb,&etc);//将数据加入数据源对象 DROPEFFECT DpEffect=listdatasrc.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE);//允许拷贝和移动
//根据结果进行相应处理,成功后由目标对象释放内存
switch (DpEffect)
{
case DROPEFFECT_COPY:
case DROPEFFECT_MOVE:
{
for (listSelItem=listct.GetNextItem(-1,LVNI_SELECTED);
listSelItem!=-1;
listSelItem=listct.GetNextItem(listSelItem,LVNI_SELECTED))
{
listct.DeleteItem(listSelItem);
listSelItem--;
} listct.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER );
listct.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER );
//listct.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER );
}
break; case DROPEFFECT_NONE:
{
//在winNT/2000下,若成功,也返回DROPEFFECT_NONE,需要判断操作系统 if (0==(GetVersion()&0x80000000)) //winNT/2000下
{
bool bDeleted=false; for (listSelItem=listct.GetNextItem(-1, LVNI_SELECTED);
listSelItem!=-1;
listSelItem=listct.GetNextItem(listSelItem,LVNI_SELECTED))
{
CString Filename=listct.GetItemText(listSelItem,0);
//文件已经被移出,不能找到文件和得到文件属性
if (0xFFFFFFFF==GetFileAttributes(Filename)&&GetLastError()==ERROR_FILE_NOT_FOUND )
{
listct.DeleteItem(listSelItem);
listSelItem--;
bDeleted=true;//从列表中移出成功
}
}
if (bDeleted)
{
listct.SetColumnWidth(0,LVSCW_AUTOSIZE_USEHEADER);
listct.SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER);
//listct.SetColumnWidth(2,LVSCW_AUTOSIZE_USEHEADER);
}
else
{//winNT/2000下失败,释放内存
GlobalFree(DropGlb);
}
}
else
{//win95/98下失败,释放内存
GlobalFree(DropGlb);
}
}
break;
} }
{
// TODO: Add your specialized code here and/or call the base class
DROPEFFECT dpEffect = DROPEFFECT_NONE;//初始返回值
//检查有无数据
if (NULL!=pDataObject->GetGlobalData(CF_HDROP))
{
//if(0==(GetVersion()&0x80000000))//检查操作系统版本,是否为winNT/2000
//dpEffect=DROPEFFECT_COPY;
//else
dpEffect=DROPEFFECT_COPY;
}
return dpEffect;
}void CDraglist1View::OnDragLeave()
{
// TODO: Add your specialized code here and/or call the base class
CListView::OnDragLeave();
}DROPEFFECT CDraglist1View::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
// TODO: Add your specialized code here and/or call the base class
DROPEFFECT dpEffect=DROPEFFECT_NONE;
if (NULL!=pDataObject->GetGlobalData(CF_HDROP))
dpEffect=DROPEFFECT_COPY;
return dpEffect;
}BOOL CDraglist1View::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
{
HGLOBAL Dropglb2;
HDROP hdp;
UINT Filesnum;
TCHAR FileNext[MAX_PATH];
SHFILEINFO stFileInfo;
LVFINDINFO stlvFindInfo={LVFI_STRING,FileNext};
LVITEM stlvItem;
CListCtrl& listct=GetListCtrl();
int Index=listct.GetItemCount();
//HANDLE hFind;
//WIN32_FIND_DATA stwinFind;
//TCHAR FileLen[64];
//读数据
Dropglb2=pDataObject->GetGlobalData(CF_HDROP);//得到内存句柄
if (NULL==Dropglb2)
{
return FALSE;
}
hdp=(HDROP)GlobalLock(Dropglb2); //得到内存地址
if (NULL==hdp)
{
GlobalUnlock(Dropglb2);
return FALSE;
}
Filesnum=DragQueryFile(hdp,-1,NULL,0);//得到文件数
for (UINT Fileitem=0;Fileitem<Filesnum;Fileitem++)
{
if (DragQueryFile(hdp,Fileitem,FileNext,MAX_PATH)>0)
{
if (-1!=listct.FindItem(&stlvFindInfo,-1))//文件名存在则跳过
continue;
SHGetFileInfo(FileNext,0,&stFileInfo,sizeof(stFileInfo),SHGFI_ATTRIBUTES|SHGFI_TYPENAME|SHGFI_SYSICONINDEX);
ZeroMemory(&stlvItem, sizeof(LVITEM));//内存清零
stlvItem.mask =LVIF_TEXT|LVIF_IMAGE;//填充LVITEM结构
stlvItem.iItem =Index;
stlvItem.pszText=FileNext;
stlvItem.iImage =stFileInfo.iIcon;
if (stFileInfo.dwAttributes&SFGAO_GHOSTED)
{
stlvItem.mask|=LVIF_STATE;
stlvItem.state=stlvItem.stateMask=LVIS_CUT;
}
listct.InsertItem(&stlvItem); //插入列表项,填充第一列
listct.SetItemText(Index,1,stFileInfo.szTypeName);//填充第二列
//hFind=FindFirstFile(FileNext,&stwinFind);
//if (INVALID_HANDLE_VALUE!=hFind)
// {
// StrFormatByteSize(stwinFind.nFileSizeLow,FileLen,64);
// FindClose(hFind);
// }
//listct.SetItemText(Index,2,FileLen);//填充第三列
Index++;
}
}
listct.SetColumnWidth(0,LVSCW_AUTOSIZE_USEHEADER);//调整列宽
listct.SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER);
//listct.SetColumnWidth(2,LVSCW_AUTOSIZE_USEHEADER);
listct.EnsureVisible(Index-1,FALSE);//根据需要添加滚动条 GlobalUnlock(Dropglb2);
GlobalFree(Dropglb2);//释放内存 return TRUE;}
void CDraglist1View::OnDestroy()
{
if (NULL!=imglist.GetSafeHandle())
imglist.Detach();
CListView::OnDestroy();
// TODO: Add your message handler code here
}