剪切板操作 复制,剪切

CopyFile.h:

#pragma once
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


class CCopyFilesOper
{
public:
	CCopyFilesOper();
	~CCopyFilesOper();

	/**
	* @brief 将文件拷贝到剪切板
	* @param[in]  std::list FileList 需要拷贝的文件列表
	* @param[in]  DWORD DropEffect  DROPEFFECT_COPY 表示复制,  DROPEFFECT_MOVE 表示剪切
	* @return 无
	*/
	bool CopyToClipboard(std::list FileList, DWORD DropEffect);

	void OpenCopyClipboard();

private:
	/*
	* @brief 计算需要分配内存的总长度
	* @param[in] std::list FileList  需要处理的列表
	* @param[out] std::map &MapFile 文件名对应长度列表
	* @return int 总长度
	*/
	int CalFileListLen(std::list FileList, std::map &MapFile);

	/*
	* @brief 将文件列表拷贝到 DROPFILES 文件列表区域内存
	* @param[in] std::map &MapFile 文件列表
	* @param[out] char* pData DROPFILES 文件列表区域内存首地址
	* @return 
	*/
	void CopyFileListIntoDropFiles(char* pData, std::map &MapFile);

};

CopyFile.cpp

#include "stdafx.h"
#include 
#include "CopyFiles.h"

CCopyFilesOper::CCopyFilesOper()
{

}

CCopyFilesOper::~CCopyFilesOper()
{

}

bool CCopyFilesOper::CopyToClipboard(std::list FileList, DWORD DropEffect)
{
    bool bRes = false;

    std::map MapFile;
    UINT uBufLen = CalFileListLen(FileList, MapFile);//文件列表中所有文件的总长度

    UINT uDropEffect = 0;
    DROPFILES dropFiles = { 0 };//
    UINT uGblLen = 0;//总长度
    UINT uDropFilesLen = 0;
    HGLOBAL hGblFiles;//
    HGLOBAL hGblEffect;
    char * pszData = NULL;
    char * szFileList = NULL;
    DWORD * dwDropEffect = NULL;

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

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

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

    //设置自定义剪切板的内容为复制或者剪切标识
    *dwDropEffect = DropEffect;


    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+1) * sizeof(TCHAR) + 8;
    uGblLen = uDropFilesLen + uBufLen + 8;
    hGblFiles = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, uGblLen);

    pszData = (char *)GlobalLock(hGblFiles);

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

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

    CopyFileListIntoDropFiles(szFileList, MapFile);
	
    GlobalUnlock(hGblFiles);

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

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

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

	//关闭剪切板
	CloseClipboard();
	bRes = true;
//	OpenCopyClipboard();
    }

    return bRes;
}

void CCopyFilesOper::OpenCopyClipboard()
{
    UINT cFiles = 0;
    DWORD dwEffect = 0;
    DWORD * dw = NULL;

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

         //判断文件夹剪切板是否存在,如果存在,在判断自定义剪切板格式是否存在
         //如果自定义剪切板格式存在,则判断是复制操作还是剪切操作
         if (hDrop)
         {
             //查询获取到的文件或文档
             cFiles = DragQueryFile(hDrop, (UINT)-1, NULL, 0);
             TCHAR szFile[MAX_PATH] = { '\0' };
             TCHAR lpBuffer[MAX_PATH] = { '\0' };

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

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

         CloseClipboard();
     }

     if (cFiles == 0)
     {
         return;
     }
}

int CCopyFilesOper::CalFileListLen(std::list FileList, std::map &MapFile)
{
	int iLen = 0;

	std::list::iterator it = FileList.begin();
	for ( ; it != FileList.end(); ++it)
	{
		wstring wstrFile = *it;
		int iFileLen = (wstrFile.size() + 1) * sizeof(TCHAR);
		if (0 == iFileLen)//文件长度为0 过滤
		{
			continue;
		}

		iLen = iLen + iFileLen;
		MapFile.insert(make_pair(wstrFile, iFileLen));
	}

	return iLen;
}

void CCopyFilesOper::CopyFileListIntoDropFiles(char* pData, std::map &MapFile)
{
	std::map::iterator it = MapFile.begin();
	for (int i = 0; i < MapFile.size(); i++)
	{
		wstring wstrFile = it->first;
		memmove(pData, wstrFile.c_str(), it->second);
		pData = pData + it->second;
		++it;
	}
}

 Main.h

#include "stdafx.h"
#include "CopyFiles.h"


int main()
{
    std::list FileList;
    FileList.push_back(L"C:\\Users\\myPC\\Desktop\\C++ Primer Plus(第6版)_中文版_带书签_超清.pdf");
    FileList.push_back(L"C:\\Users\\myPC\\Desktop\\文件");

    CCopyFilesOper copy;
    copy.CopyToClipboard(FileList, DROPEFFECT_COPY);//复制
    copy.CopyToClipboard(FileList, DROPEFFECT_MOVE);//移动,剪切

    return 0;
}

 

 

你可能感兴趣的:(C++)