windows剪切板文本和文件的获取设置

介绍

windows剪切板的内容包含很多不同的格式,例如:CF_TEXT、CF_BITMAP、CF_METAFILEPICT、CF_SYLK、CF_DIF、CF_TIFF、CF_OEMTEXT、CF_DIB、CF_PALETTE、CF_PENDATA、CF_RIFF、CF_WAVE、CF_UNICODETEXT、CF_ENHMETAFILE、CF_HDROP、CF_LOCALE、CF_DIBV5等。这里只涉及文本( CF_TEXT 和 CF_UNICODETEXT )和文件( CF_HDROP )格式的获取和设置,其它格式暂未涉及 。

代码

根据不同的字符集环境,我们定义了共用的字符串类型tstring,并且定义了可变长度的vvtstring用来存储文件列表。

#ifdef _UNICODE
typedef std::wstring	tstring;
#else
typedef std::string		tstring;
#endif	//_UNICODE

typedef std::vector
   
   
    
     vtstring;
typedef std::vector
    
    
     
      vvtstring;
    
    
   
   

定义

  Clipboard类实现了这些功能,它的主要函数功能介绍如下:readFromClipBoard获取剪切板的文本内容,writeToClipBoard设置剪切板的文本内容;copyFileToClipboard把文件列表设置到剪切板中,readFileFromClipBoard获取剪切板中文件列表。

class Clipboard {
public:
	static bool readFromClipBoard(tstring& str);

	static bool writeToClipBoard(const tstring& str);

	static bool copyFileToClipboard(const vvtstring& fileList);

	static bool readFileFromClipBoard(vvtstring& fileList);
private:
};

实现

readFromClipBoard根据字符集的类型,判断剪切板内容是否是文本内容。使用GetClipboardData获取文件内容并保存在传出参数str中。

bool Clipboard::readFromClipBoard(tstring& str) {
#ifdef _UNICODE
	const UINT CF_TCTEXT = CF_UNICODETEXT;
#else
	const UINT CF_TCTEXT = CF_TEXT;
#endif

	if (!IsClipboardFormatAvailable(CF_TCTEXT) || !OpenClipboard(NULL)) {
		return false;
	}

	HANDLE hglb = GetClipboardData(CF_TCTEXT);
	if (hglb != NULL) {
		const TCHAR *lpstr = (const TCHAR *)GlobalLock(hglb);
		if (lpstr != 0) {
			str.assign(lpstr);
			GlobalUnlock(hglb);
		}
	}
	CloseClipboard();
	return true;
}

writeToClipBoard先打开剪切板并清空剪切板中的内容,然后根据需要设置的文本内容的长度分配相应的内存空间,接着把写入分配的内存,SetClipboardData完成设置。

bool Clipboard::writeToClipBoard(const tstring& str) {
	if (OpenClipboard(NULL)) {
		EmptyClipboard();

		size_t clipSize = str.length() * sizeof(TCHAR);
		HGLOBAL hglb = GlobalAlloc(GMEM_MOVEABLE, clipSize);
		if (hglb) {
			TCHAR *buff = (TCHAR *)GlobalLock(hglb);
			memcpy(buff, str.c_str(), clipSize);
			GlobalUnlock(hglb);
#ifdef _UNICODE
			const UINT CF_TCTEXT = CF_UNICODETEXT;
#else
			const UINT CF_TCTEXT = CF_TEXT;
#endif
			SetClipboardData(CF_TCTEXT, hglb);
		}

		CloseClipboard();
	}

	return false;
}

copyFileToClipboard复制文件列表到剪切板。DROPEFFECT_COPY表明剪切板中的文件列表是复制,DROPEFFECT_MOVE表明是剪切。文件列表在剪切板中的格式是每个文件名以0结尾,最后一个文件名以两个0结尾。

bool Clipboard::copyFileToClipboard(const vvtstring& fileList)
{
	if (fileList.empty()) {
		return false;
	}

	UINT uDropEffect = RegisterClipboardFormat(L"Preferred DropEffect");
	HGLOBAL hGblEffect = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(DWORD));
	LPDWORD lpdDropEffect = (LPDWORD)GlobalLock(hGblEffect);
	*lpdDropEffect = DROPEFFECT_COPY;
	GlobalUnlock(hGblEffect);
	DROPFILES stDrop = {0};
	stDrop.pFiles = sizeof(DROPFILES);
	stDrop.pt.x = 0;
	stDrop.pt.y = 0;
	stDrop.fNC = FALSE;
	stDrop.fWide = TRUE;
	int filenameLength = 0;
	for (auto iter = fileList.begin(); iter != fileList.end(); ++ iter) {
		const vtstring& file = (*iter);
		filenameLength += file.size();
	}
	int totalLength = sizeof(DROPFILES) + filenameLength * sizeof(TCHAR) + 
		(fileList.size() - 1) * sizeof(TCHAR) + 2 * sizeof(TCHAR);
	HGLOBAL hGblFiles = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, totalLength);
	char* lpData = (char*)GlobalLock(hGblFiles);
	memcpy(lpData, &stDrop, sizeof(DROPFILES));
	char *lpStart = lpData + sizeof(DROPFILES);
	int iStart = 0;
	auto iter = fileList.begin();
	do {
		const vtstring& file = (*iter);
		memcpy(lpStart + iStart, &file.front(), file.size() * sizeof(TCHAR));
		++ iter;
		if (iter == fileList.end()) {
			break;
		}else {
			iStart += file.size() * sizeof(TCHAR);
			iStart += 1 * sizeof(TCHAR);	// '\0'
		}
	}while(true);

	GlobalUnlock(hGblFiles);
	if (OpenClipboard(NULL)) {
		EmptyClipboard();
		SetClipboardData(CF_HDROP,hGblFiles);
		SetClipboardData(uDropEffect,hGblEffect);
		CloseClipboard();
		return true;
	}else {
		return false;
	}
}

readFileFromClipBoard获取剪切板中的文件列表。首先根据剪切板中的格式来判断当前剪切板中的内容是否是文件类型(CF_HDROP)。然后使用DragQueryFile获取剪切板中的文件。

bool Clipboard::readFileFromClipBoard(vvtstring& fileList) {
	if(!IsClipboardFormatAvailable(CF_HDROP) || !OpenClipboard(NULL)) {
		return false;
	}

	HDROP hDrop=(HDROP)GetClipboardData(CF_HDROP);
	int iFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
	for (int i = 0; i < iFiles; i++) {
		int length = DragQueryFile(hDrop, i, NULL, 0);
		TCHAR* lpszFile = (TCHAR*)GlobalAlloc(GPTR, (length + 1) * sizeof(TCHAR));
		DragQueryFile(hDrop, i, lpszFile, length + 1);
		vtstring file(lpszFile, lpszFile + length);
		fileList.push_back(file);

		GlobalFree(lpszFile);
	}

	CloseClipboard();
	return true;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z小偉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值