您的位置:首页 > 其它

复制、剪切、粘贴文件夹(剪切板)

2014-04-03 17:02 148 查看
本程序下载地址:

  类似于windows的复制、剪切、粘贴操作、我们也可以使用剪切板来实现这样的功能。

  下面通过一个例子来演示:点击 “复制” 按钮,可以把"D:\temp"文件夹放到剪切板, 右键选择粘贴,可以把该文件夹放到硬盘目录下。点击 “粘贴” 按钮,可以把"D:\temp"这个路径名显示到文本框中。

  程序运行界面如下:



复制按钮响应过程:

  先建立一个自定义剪切板,用来存放复制或者剪切操作标识符号,判断是哪一种操作;

  然后建立一个文件夹剪切板,头部存放一个DROPFILES结构大小内容,之后的空间用来存放文件夹列表

void CMyDlg::OnBtnCopy()
{
// TODO: Add your control notification handler code here

//要复制剪切的文档或者文件夹
char *lpBuffer = "D:\\Temp";
UINT uBufLen = strlen(lpBuffer);

//true拷贝,false剪切
bool bCopy = true;

UINT uDropEffect = 0;
DROPFILES dropFiles = {0};
UINT uGblLen = 0;
UINT uDropFilesLen = 0;
HGLOBAL hGblFiles;
HGLOBAL hGblEffect;
char * szData = NULL;
char * szFileList = NULL;
DWORD * dwDropEffect = NULL;

///////////////////////////自定义剪切板,用来设置标识(复制还是剪切)/////////////////////////

uDropEffect = RegisterClipboardFormat("Preferred DropEffect");    //参数随便填

hGblEffect = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, sizeof(DWORD));
dwDropEffect = (DWORD*)GlobalLock(hGblEffect);

//设置自定义剪切板的内容为复制或者剪切标识
if(bCopy)
{
*dwDropEffect = DROPEFFECT_COPY;
}
else
{
*dwDropEffect = DROPEFFECT_MOVE;
}

GlobalUnlock(hGblEffect);

///////////////////////////文件剪切板,用来存放文件列表/////////////////////////

uDropFilesLen = sizeof(DROPFILES);
//DROPFILES结构的大小
dropFiles.pFiles = uDropFilesLen;
dropFiles.pt.x = 0;
dropFiles.pt.y = 0;
dropFiles.fNC =FALSE;
//true: UNICODE, false: ascii
dropFiles.fWide =TRUE;

//uBufLen * 2表示的是宽字符大小, 加8表示文件末尾需要2个空指针结尾,每个指针占4个字节大小
uGblLen = uDropFilesLen + uBufLen * 2 + 8;
hGblFiles = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, uGblLen);

szData = (char * )GlobalLock(hGblFiles);

//把DROPFILES结构大小的内容放到szData剪切板空间的最开始
memcpy(szData, (LPVOID)(&dropFiles), uDropFilesLen);

//szFileList指向需要放入文件的那个空间,前面存放了DROPFILES结构大小的空间
szFileList = szData + uDropFilesLen;

//把文件列表转为宽字符,并存放到szFileList指向的那片空间
MultiByteToWideChar(CP_ACP,MB_COMPOSITE,
lpBuffer,uBufLen,(WCHAR *)szFileList,uBufLen);

GlobalUnlock(hGblFiles);

if( ::OpenClipboard(NULL) )
{
EmptyClipboard();

//可以设置剪切板内容为拖动文件
SetClipboardData( CF_HDROP, hGblFiles );

//可以设置剪切板内容为复制或者剪切标识
SetClipboardData(uDropEffect,hGblEffect);

//关闭剪切板
CloseClipboard();
}
}


  执行复制操作的时候,程序相当于建立了两个剪切板, 但是想要执行粘贴操作,又该选择哪一个剪切板呢?

  执行粘贴操作的时候,我们可以先判断文件夹剪切板格式是否存在,如果存在,则判断自定义剪切板格式是否存在,自定义剪切板格式存在,则判断是执行复制还是剪切操作。之后就是查询所有的文件类表了。当然如果剪切板格式不存在就不进行处理了。

  粘贴操作响应函数代码:

void CMyDlg::OnBtnPaste()
{
// TODO: Add your control notification handler code here

//自定义剪切板,名称要和复制注册的名称一样
UINT uDropEffect = RegisterClipboardFormat("Preferred DropEffect");
UINT cFiles = 0;
DWORD dwEffect = 0;
DWORD * dw = NULL;

if( ::OpenClipboard(this->m_hWnd) )
{
//获取CF_HDROP剪切板的内容
HDROP hDrop = HDROP( GetClipboardData( CF_HDROP));

//判断文件夹剪切板是否存在,如果存在,在判断自定义剪切板格式是否存在
//如果自定义剪切板格式存在,则判断是复制操作还是剪切操作
if( hDrop)
{
//获取自定义剪切板的内容
dw = (DWORD*)(GetClipboardData( uDropEffect));

if(dw==NULL)
{
dwEffect = DROPEFFECT_COPY;
}
else
{
dwEffect = *dw;
}

//查询获取到的文件或文档
cFiles = DragQueryFile( hDrop, (UINT) -1, NULL, 0);
char szFile[ MAX_PATH] = {'\0'};
char lpBuffer[ MAX_PATH] = {'\0'};

//查询所有的文件列表,并把路径显示到文本框中
for( UINT count = 0; count < cFiles; count++ )
{
DragQueryFile( hDrop, count, szFile, sizeof( szFile));

lstrcat(lpBuffer,szFile);
lstrcat(lpBuffer,"\r\n");

//把文件显示到文本框
SetDlgItemText(IDC_EDIT_DISPLAY, lpBuffer);
}
}

CloseClipboard();
}

if(cFiles==0)
{
return ;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: