由于最近的一个项目需要实现与其它程序的文件拖放(拖进/拖出),而手上没有现成的控件.在网络上也找不到合适的原代码.因此,决定自己做了一个.它是继承于TLlistView类的.
对于拖进文件可以用简单的函数实现:步骤为:
No. 1在<create>构造或初始函数中,注册接受窗口DragAcceptFiles(ListView->Handle,true);
No.2加入窗口响应<WM_DROPFILES>消息的函数,并使用DragQueryFile检查拖放文件数量并枚举个文件名称.
No.3执行拖放完毕函数DragFinish
例:
if(Msg.Msg==WM_DROPFILES)
{
int filesize = DragQueryFile ((HWND)Msg.WParam, 0xFFFFFFFF, NULL, 0);
char name[80];
for(int n=0;n<filesize;n++)
{
DragQueryFile ((HWND)Msg.WParam, n,name, 80);
ListView_AppList->AddItem(name,NULL);
Caption=name;
}
DragFinish ((HWND)Msg.WParam);
}
而对于拖出,就比较复杂一点,需要使用到OLE对象.并且我是使用的VC++的CDataObject和CDragObject两个封装类,它们可以在网络上搜到.
步骤为:
No.1 初始OLE 在启动或初始的时候<OleInitialize(0);>
No.2 响应鼠标键按下并移动的事件 ,使用DoDragDrop启动拖放.
No.3在析构中注销OLE<OleUninitialize();>
;例如:
if(Shift.Contains(ssShift)&&mdown)
{
IDataObject *pDataObject;
IDropSource *pDropSource;
DWORD dwEffect;
DWORD dwResult;
//FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
FORMATETC fmtetc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stgmed = { TYMED_HGLOBAL, { 0 }, 0 };
HDROP hdrop;
//fmatetc.tymed=TYMED_FILE;
//stgmed.tymed=TYMED_FILE;
//HGLOBAL hMem = GlobalAlloc(GHND, Caption.Length()+1);
HGLOBAL hMem = GlobalAlloc(GHND|GMEM_SHARE,(DWORD) (sizeof(DROPFILES)+_MAX_PATH+1));
LPDROPFILES pDropFiles= (LPDROPFILES)GlobalLock(hMem);
pDropFiles->pFiles = sizeof(DROPFILES);
pDropFiles->fWide=FALSE;
lstrcpy((LPSTR)((LPSTR)(pDropFiles)+sizeof(DROPFILES)),TEXT(Caption.c_str()));
((LPSTR)pDropFiles)[sizeof(DROPFILES)+Caption.Length()]=0;
GlobalUnlock(hMem);
stgmed.hGlobal=hMem;
CreateDropSource(&pDropSource);//该函数为IDropSource 的实例化函数在下载的文件中可找到
CreateDataObject(&fmtetc,&stgmed,1,&pDataObject);//同上
DoDragDrop(pDataObject,pDropSource,DROPEFFECT_MOVE,&dwEffect); //DROPEFFECT_COPY|
pDataObject->Release();
pDropSource->Release();
}