C如何获取剪贴板内的带格式内容?WPS为什么可以知道一段文字的格式信息?

1

WPS可以带格式粘贴,但是WPS是如何得到格式信息的呢?

将带有格式的内容粘贴到文本文档中,却没有任何HTML标签出现来证明他是带格式的内容

一开始我以为是GetClipboardData函数的参数问题,通过改变他的参数可以得到带格式的内容,于是我在MSDN查到了他的所有参数并逐个进行了尝试:

https://docs.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats

但是仍然无法得到一段带格式文本的格式信息,得到的内容不过是纯文本。

如何得到一段带格式文本的格式信息?

ava
huidong

2020-8-16

0

你需要注册 HTML 类型的剪贴板格式。

以下是读取 HTML / Word 类型剪贴板的完整例子。
注意:剪贴板里面的同一个内容,可能有多种格式。这个例子仅仅处理 HTML 格式。

// 读取剪贴板中 HTML 格式的数据
// 编译环境:VS2019
//
#include <windows.h>
#include <stdio.h>
#include <locale.h>
#include <string>


// 从剪贴板中获取 HTML 格式的数据
std::wstring GetClipboardHtmlData()
{
	std::wstring out;

	// 注册剪贴板格式
	static UINT CF_HTML = 0;
	if (CF_HTML == 0)
		CF_HTML = RegisterClipboardFormat(L"HTML Format");

	if (OpenClipboard(NULL))	// 打开剪贴板
	{
		if (IsClipboardFormatAvailable(CF_HTML))		// 判断剪贴板是否含有所需格式
		{
			HANDLE hClip = GetClipboardData(CF_HTML);	// 读取剪贴板数据
			char* pBuf = (char*)GlobalLock(hClip);		// 获取文本数据指针

			// 将 UTF-8 数据转换为 Unicode
			int i = MultiByteToWideChar(CP_UTF8, NULL, pBuf, -1, NULL, 0);	// 获取转换后的长度
			out.resize(i);
			MultiByteToWideChar(CP_UTF8, NULL, pBuf, -1, &out[0], i);		// Utf-8 转换为 Unicode

			GlobalUnlock(hClip);
			CloseClipboard();							// 关闭剪贴板
		}
	}

	return out;
}


// 主函数
int main()
{
	std::wstring s = GetClipboardHtmlData();	// 从剪贴板获取 HTML 格式的数据

	setlocale(LC_ALL, "");		// 设置控制台显示 Unicode 字符串
	wprintf(s.c_str());			// 输出结果

	return 0;
}
ava
慢羊羊

2020-8-16

现在可以得到HTML标签了,但是剪贴板内容不一样时,程序有时会崩溃,例如就是这个网页,Ctrl+A,Ctrl+C复制下来再运行程序,就会崩溃。还有一个问题,自定义CF_HTML的时候为什么是HTML Format呢?如果是其它格式,是不是有对应的 xxx Format呢? - huidong 2020-8-16
1 @huidong 不同的 app 通过 RegisterClipboardFormat() 注册相同的剪贴板格式,就可以共享剪贴板内容。浏览器注册了“HTML Format”格式,你也注册相同格式,那么你就可以在浏览器和你的 App 之间共享剪贴板。剪贴板格式的名字可以自己定义,只需要不同的 App 都注册相同的格式,就可以相互拷贝粘贴数据。 - 慢羊羊 2020-8-16
@慢羊羊  噢,明白了。不知道您有没有测试一下程序崩溃的问题?我后来发现,在win7上有时会崩溃(提示访问xxx内存时…),而在win10不会(但是内容不完整),我以为是内存泄漏,但是我记得string应该不会内存泄漏的吧,是什么问题呢? - huidong 2020-8-16
@huidong 崩溃,是哪一行崩溃?内容不完整,是函数获取到的不完整,还是输出的时候没有输出完整?这些基本的调试你要先自己试试。范例,只是讲解知识用的。我不会在剪贴板的范例中还对 wstring 的输出做更多工作,喧宾夺主了。 - 慢羊羊 2020-8-16