输出到剪贴板、从剪贴板获取带格式内容的方法(获取 HTML 等其他格式的剪切板内容)
[編輯] [转简体] (简体译文)概要
WPS 如何做到带格式粘贴,为什么粘贴到文本编辑器的时候又是不带有格式标志的纯文本?这就是剪贴板格式。
正文
基本剪贴板操作:http://www.huidong.xyz/?mode=2&id=134
复制数据到剪贴板的时候,SetClipboardData函数的第一个参数是内容类型
SetClipboardData(CF_TEXT, hClip);
获取剪贴板内容的时候,IsClipboardFormatAvailable函数和 GetClipboardData函数 的第一个参数也都是内容类型
CF_TEXT表示纯文本,是预定义的类型
预定义的类型大全在MSDN可以看到:https://docs.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats
当我们需要写入/读取带格式内容时,CF_XXX参数就代表我们需要的类型,但是很多时候,预定义的类型是不够的,我们可以自定义剪贴板支持的内容类型,比如浏览器就注册了HTML类型的剪贴板格式,我们注册相同的剪贴板格式,就可以得到对应格式的内容。
那么怎么做到像WPS一样的带格式粘贴(所见即所得)呢?
那就是,设置得到剪贴板内容的函数GetClipboardData的第一个参数,来确定我们需要得到的内容类型,比如我们需要得到HTML格式的内容:
【引用】
// 从剪贴板中获取 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; }
引用村长的话:
不同的 app 通过 RegisterClipboardFormat() 注册相同的剪贴板格式,就可以共享剪贴板内容。浏览器注册了“HTML Format”格式,你也注册相同格式,那么你就可以在浏览器和你的 App 之间共享剪贴板。剪贴板格式的名字可以自己定义,只需要不同的 App 都注册相同的格式,就可以相互拷贝粘贴数据。
参考资料:
https://qa.codeabc.cn/questions/detail/1873
村长的完整示例:
// 读取剪贴板中 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; }