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

本程序下载地址:

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

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

  程序运行界面如下:

复制按钮响应过程:

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

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

 1 void CMyDlg::OnBtnCopy() 
 2 {
 3     // TODO: Add your control notification handler code here
 4 
 5     //要复制剪切的文档或者文件夹
 6     char *lpBuffer = "D:\Temp";                
 7     UINT uBufLen = strlen(lpBuffer);
 8     
 9     //true拷贝,false剪切
10     bool bCopy = true;                            
11     
12     UINT uDropEffect = 0;
13     DROPFILES dropFiles = {0};
14     UINT uGblLen = 0;
15     UINT uDropFilesLen = 0;
16     HGLOBAL hGblFiles;
17     HGLOBAL hGblEffect;
18     char * szData = NULL;
19     char * szFileList = NULL;
20     DWORD * dwDropEffect = NULL;
21     
22 ///////////////////////////自定义剪切板,用来设置标识(复制还是剪切)/////////////////////////
23     
24     uDropEffect = RegisterClipboardFormat("Preferred DropEffect");    //参数随便填
25     
26     hGblEffect = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, sizeof(DWORD));
27     dwDropEffect = (DWORD*)GlobalLock(hGblEffect);
28 
29     //设置自定义剪切板的内容为复制或者剪切标识
30     if(bCopy)
31     {
32         *dwDropEffect = DROPEFFECT_COPY;
33     }
34     else
35     {
36         *dwDropEffect = DROPEFFECT_MOVE;
37     }
38         
39     GlobalUnlock(hGblEffect);
40 
41 ///////////////////////////文件剪切板,用来存放文件列表/////////////////////////    
42 
43     uDropFilesLen = sizeof(DROPFILES);
44     //DROPFILES结构的大小
45     dropFiles.pFiles = uDropFilesLen;            
46     dropFiles.pt.x = 0;
47     dropFiles.pt.y = 0;
48     dropFiles.fNC =FALSE;
49     //true: UNICODE, false: ascii
50     dropFiles.fWide =TRUE;                        
51     
52     //uBufLen * 2表示的是宽字符大小, 加8表示文件末尾需要2个空指针结尾,每个指针占4个字节大小
53     uGblLen = uDropFilesLen + uBufLen * 2 + 8;            
54     hGblFiles = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, uGblLen);
55     
56     szData = (char * )GlobalLock(hGblFiles);
57 
58     //把DROPFILES结构大小的内容放到szData剪切板空间的最开始
59     memcpy(szData, (LPVOID)(&dropFiles), uDropFilesLen);
60 
61     //szFileList指向需要放入文件的那个空间,前面存放了DROPFILES结构大小的空间
62     szFileList = szData + uDropFilesLen;
63     
64     //把文件列表转为宽字符,并存放到szFileList指向的那片空间
65     MultiByteToWideChar(CP_ACP,MB_COMPOSITE,    
66         lpBuffer,uBufLen,(WCHAR *)szFileList,uBufLen);
67     
68     GlobalUnlock(hGblFiles);
69     
70     if( ::OpenClipboard(NULL) )
71     {
72         EmptyClipboard();
73         
74         //可以设置剪切板内容为拖动文件
75         SetClipboardData( CF_HDROP, hGblFiles );
76 
77         //可以设置剪切板内容为复制或者剪切标识
78         SetClipboardData(uDropEffect,hGblEffect);
79 
80         //关闭剪切板
81         CloseClipboard();
82     }
83 }

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

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

  粘贴操作响应函数代码:

 1 void CMyDlg::OnBtnPaste() 
 2 {
 3     // TODO: Add your control notification handler code here
 4 
 5     //自定义剪切板,名称要和复制注册的名称一样
 6     UINT uDropEffect = RegisterClipboardFormat("Preferred DropEffect");
 7     UINT cFiles = 0;
 8     DWORD dwEffect = 0;
 9     DWORD * dw = NULL;
10     
11     if( ::OpenClipboard(this->m_hWnd) ) 
12     {
13         //获取CF_HDROP剪切板的内容
14         HDROP hDrop = HDROP( GetClipboardData( CF_HDROP));        
15 
16         //判断文件夹剪切板是否存在,如果存在,在判断自定义剪切板格式是否存在
17         //如果自定义剪切板格式存在,则判断是复制操作还是剪切操作
18         if( hDrop)
19         {
20             //获取自定义剪切板的内容
21             dw = (DWORD*)(GetClipboardData( uDropEffect));        
22 
23             if(dw==NULL)
24             {
25                 dwEffect = DROPEFFECT_COPY;
26             }    
27             else
28             {
29                 dwEffect = *dw;
30             }
31                 
32             //查询获取到的文件或文档
33             cFiles = DragQueryFile( hDrop, (UINT) -1, NULL, 0);
34             char szFile[ MAX_PATH] = {''};
35             char lpBuffer[ MAX_PATH] = {''};
36 
37             //查询所有的文件列表,并把路径显示到文本框中
38             for( UINT count = 0; count < cFiles; count++ )
39             {
40                 DragQueryFile( hDrop, count, szFile, sizeof( szFile));
41 
42                 lstrcat(lpBuffer,szFile);
43                 lstrcat(lpBuffer,"
");
44 
45                 //把文件显示到文本框
46                 SetDlgItemText(IDC_EDIT_DISPLAY, lpBuffer);
47             }
48         }
49 
50         CloseClipboard();
51     } 
52 
53     if(cFiles==0)
54     {
55         return ;
56     }
57 }
原文地址:https://www.cnblogs.com/xydblog/p/3643453.html