rovershen 阅读(1160) 评论(0)

有时候我们希望在资源管理器中拷贝或者剪切文件,在自己的程序里粘贴,怎么来实现呢?

其实它们都在剪贴板里,以ITEMIDLIST数组存放,第一项是父目录的绝对路径的ITEMIDLIST,其余的为每一项则为相对路径的ITEMIDLIST,可以直接跟父目录的合成一个完整的绝对路径ITEMIDLIST,或者先转换成文件名再相加。

#define GetPIDFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0])
#define GetPIDItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
	COleDataObject	obj;
	obj.AttachClipboard();
	UINT CF_ITEMIDLIST=RegisterClipboardFormat(CFSTR_SHELLIDLIST);
	if(!obj.IsDataAvailable(CF_ITEMIDLIST))
		return;
	HGLOBAL hGbl=obj.GetGlobalData(CF_ITEMIDLIST);
	if(hGbl==NULL)
		return;
	LPIDA pIDList=(LPIDA)GlobalLock(hGbl);
	if(pIDList==NULL)
		return;
	int count=pIDList->cidl;
	char FileName[MAX_PATH];
	LPCITEMIDLIST pFolder=GetPIDFolder(pIDList);
	SHGetPathFromIDList(pFolder,FileName);
	CString Folder=FileName;
	CString PathName;
	if(Folder[Folder.GetLength()-1]!='\\')
		Folder+="\\";
	SHFILEINFO sfi;
	int flen=Folder.GetLength();
	for(int index=0;index<count;index++){
		LPCITEMIDLIST pChild=GetPIDItem(pIDList,index);
		SHGetPathFromIDList(pChild,FileName);
		PathName=Folder+FileName;
		SHGetFileInfo(PathName,0,&sfi,sizeof(sfi),SHGFI_ATTRIBUTES);
		if(sfi.dwAttributes&SFGAO_FILESYSTEM==SFGAO_FILESYSTEM){
			if((sfi.dwAttributes&SFGAO_FOLDER)!=SFGAO_FOLDER){
				//process the file
			}
			else{
				//process the folder
			}
		}
	}
	obj.Detach();
	GlobalUnlock(hGbl);

至于是拷贝还是剪切,可以通过格式为CFSTR_PREFERREDDROPEFFECT的剪贴板数据第一个DWORD来判断,它的值DROPEFFECT_COPY就是拷贝,是DROPEFFECT_MOVE则是剪切。


发表评论
切换编辑模式