0

0

c++如何操作剪贴板数据_c++ Windows Clipboard API文本读写【方法】

尼克

尼克

发布时间:2025-12-29 19:40:02

|

495人浏览过

|

来源于php中文网

原创

Windows剪贴板纯文本读写必须使用Win32 API,首选CF_UNICODETEXT格式;需严格配对OpenClipboard/CloseClipboard、GlobalLock/GlobalUnlock,且全程在同一线程执行。

c++如何操作剪贴板数据_c++ windows clipboard api文本读写【方法】

OpenClipboard + GetClipboardData 读取纯文本

Windows 剪贴板文本读取必须走 Win32 API,不能直接访问内存。核心流程是打开剪贴板、请求 CF_TEXT 或更推荐的 CF_UNICODETEXT 格式数据、再用 GlobalLock 取出内容。

常见错误是没检查 IsClipboardFormatAvailable 就直接调 GetClipboardData,结果返回 NULL;或者忘了 GlobalUnlockCloseClipboard,导致后续操作失败(比如其他程序无法写入)。

  • CF_UNICODETEXT 是首选:支持中文、emoji、全角符号,CF_TEXT 只能处理 ANSI 编码(基本废了)
  • 返回的 HGLOBAL 指针需用 GlobalLock 转成 LPCWSTR,且不能直接当 C++ 字符串用——它不带长度信息,得用 wcslen 或按 null 终止判断
  • 必须在同一线程中完成 OpenClipboard → 读取 → CloseClipboard 全流程,跨线程调用会失败
if (OpenClipboard(NULL)) {
    if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
        HANDLE hData = GetClipboardData(CF_UNICODETEXT);
        if (hData) {
            LPCWSTR lpcwstr = static_cast(GlobalLock(hData));
            if (lpcwstr) {
                std::wstring text(lpcwstr); // 自动截断到第一个 \0
                GlobalUnlock(hData);
            }
        }
    }
    CloseClipboard();
}

SetClipboardData 写入 Unicode 文本

写入比读取更易出错:必须先 OpenClipboard,再 GlobalAlloc 分配可移动内存(GMEM_MOVEABLE),GlobalLock 后 memcpy 内容,GlobalUnlock,最后 SetClipboardData。漏掉任意一步都会导致写入失败或剪贴板卡死。

关键点在于分配的内存大小:要包含末尾的 \0,且单位是字节wchar_t 是 2 字节),所以长度是 (text.length() + 1) * sizeof(wchar_t)

立即学习C++免费学习笔记(深入)”;

Figma
Figma

Figma 是一款基于云端的 UI 设计工具,可以在线进行产品原型、设计、评审、交付等工作。

下载
  • 不要用 GMEM_FIXED:系统要求剪贴板数据必须是可移动(GMEM_MOVEABLE)内存块
  • SetClipboardData 接管内存所有权,你不能再 GlobalFree 它,否则系统崩溃
  • 如果写入后立刻被其他程序清空,大概率是没调 CloseClipboard,或调用前已有程序占着剪贴板没释放
std::wstring text = L"你好,clipboard!";
if (OpenClipboard(NULL)) {
    EmptyClipboard();
    size_t size = (text.length() + 1) * sizeof(wchar_t);
    HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, size);
    if (hMem) {
        LPWSTR lpMem = static_cast(GlobalLock(hMem));
        if (lpMem) {
            memcpy(lpMem, text.c_str(), size);
            GlobalUnlock(hMem);
            SetClipboardData(CF_UNICODETEXT, hMem); // 系统接管 hMem
        }
    }
    CloseClipboard();
}

为什么 CF_OEMTEXTCF_LOCALE 基本不用

CF_OEMTEXT 对应 DOS 时代 OEM 字符集(如 GBK 的变体),现在 Windows 默认用 Unicode,该格式只在极老终端程序里出现;CF_LOCALE 是辅助信息,存区域设置 ID,单独存在无意义,且现代应用完全不依赖它做编码推断。

真正需要多格式支持时(比如粘贴进 Word 要保留粗体),得用 CF_HTMLCF_RTF,但它们结构复杂,需手动构造 MIME 头或 RTF 控制字——对纯文本场景属于过度设计。

  • 只要目标是“人眼可读的字符串”,坚持用 CF_UNICODETEXT 就够了
  • 试图兼容 CF_TEXT 反而引入乱码风险:系统不会自动转码,只会原样返回 ANSI 字节流
  • 某些远程桌面或沙盒环境会禁用非 Unicode 格式,CF_UNICODETEXT 是唯一稳定选项

常见报错:OpenClipboard 返回 false 或 GetClipboardData 返回 NULL

这不是代码写错了,而是系统级阻塞。最常见三种情况:剪贴板正被另一进程独占(如微信钉钉后台监听)、当前线程没消息循环(GUI 程序必须有 GetMessage 循环)、或调用发生在 DLL 的 DllMain / 静态构造函数中(Windows 明确禁止)。

  • 调试时可在调用前加 printf("open: %d\n", OpenClipboard(NULL)); 快速确认是否被占用
  • 控制台程序也能用剪贴板,但必须确保不是以“管理员权限”运行的 GUI 程序正在拖拽——UAC 隔离会导致跨权限访问失败
  • 没有异常处理机制,所有 API 调用后都应检查返回值,尤其 OpenClipboardGetClipboardData

真正麻烦的不是 API 调用本身,而是状态管理:开没开、锁没锁、关没关、内存谁释放——每一步都得严格配对。稍有遗漏,剪贴板就进入不可用状态,连 Ctrl+V 都失灵。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

227

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

432

2024.03.01

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

72

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

275

2023.11.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

246

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

204

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1431

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

606

2023.11.24

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.7万人学习

AngularJS教程
AngularJS教程

共24课时 | 2.1万人学习

CSS教程
CSS教程

共754课时 | 17万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号