加载中
加载中
表情图片
评为精选
鼓励
加载中...
分享
加载中...
文件下载
加载中...
修改排序
加载中...
C++操作Windows剪贴板
acmilan2015/07/15软件综合 IP:四川
C++操作剪贴板是调用WinAPI来实现的,常用的剪贴板操作函数有:
BOOL OpenClipboard(所有者窗口) 打开剪贴板
BOOL EmptyClipboard() 清空剪贴板
HANDLE SetClipboardData(类型, 内存块句柄) 设置剪贴板内容
HANDLE GetClipboardData(类型) 返回包含剪贴板内容的内存块句柄
BOOL CloseClipboard() 关闭剪贴板

常用的剪贴板数据类型(还包括很多其它类型,详情请参考MSDN相关内容):
CF_TEXT 一段ANSI文本
CF_OEMTEXT 一段DOS文本
CF_UNICODETEXT 一段Unicode文本
CF_LOCALE 区域标识
CF_BITMAP 位图
CF_DIB 设备无关位图

需要使用Win32内存块与剪贴板交互,常用Win32内存块操作函数(另有LocalAlloc等,功能完全相同):
HGLOBAL GlobalAlloc(分配选项, 分配内存大小) 分配全局内存并返回它的句柄或指针
HGLOBAL GlobalFree(内存块句柄) 释放全局内存
SIZE_T GlobalSize(内存块句柄) 返回全局内存的大小
LPVOID GlobalLock(内存块句柄) 获得全局内存所有权,并返回指向全局内存的指针
BOOL GlobalUnlock(内存块句柄) 释放全局内存所有权
GlobalAlloc分配选项如果是GHND,则分配可变内存,清零内存并返回全局内存句柄,需要GlobalLock以获取指针
GlobalAlloc分配选项如果是GPTR,则分配固定内存,清零内存并直接返回指针

复制(向剪贴板写内容)操作流程:
创建一块内存块
1.分配一个适当大小的内存块(GlobalAlloc,GHND)
2.锁定它并获得所有权(GlobalLock)
3.将要复制的内容拷贝到该内存
4.释放内存的所有权(GlobalUnlock)
将剪贴板内容设置为它
5.打开剪贴板(OpenClipboard)
6.清空剪贴板(EmptyClipboard)
7.将该内存块设为剪贴板的数据(SetClipboardData)
8.关闭剪贴板(CloseClipboard)

粘贴(读剪贴板内容)操作流程:
1.打开剪贴板(OpenClipboard)
2.获取包含剪贴板内容的内存块句柄(GetClipboardData)
3.锁定该内存块并获得指针(GlobalLock)
3.读取该内存的内容
4.关闭剪贴板(CloseClipboard)

示例程序:
剪贴板客户端client(),用以发送文本到剪贴板,剪贴板监视器monitor(),用以读取并监视剪贴板的变化。
包含ANSI和Unicode的示例。启动时可以选择模式:c=客户端,m=监视器;a=ANSI文本,u=Unicode文本

捕获.png

Other
// ClipboardConsole.cpp : 定义控制台应用程序的入口点。 //    #include "stdafx.h"    #include <windows.h> #include <stdio.h> #include <locale.h>    void clientA() // ANSI版剪贴板客户端(复制操作) {     DWORD content;     char buf[200] = {0};     HGLOBAL hGlobal;        while (true)     {         fgets(buf, sizeof(buf), stdin); // 获取输入的字符串            hGlobal = GlobalAlloc(GPTR, (lstrlenA(buf) + 1)); // 新建一个Win32内存块         char *pGlobal = (char*)GlobalLock(hGlobal); // 锁定并获取它的指针         lstrcpyA(pGlobal, buf); // 将字符串复制到它的上边         GlobalUnlock(hGlobal); // 释放内存块所有权            OpenClipboard(NULL); // 打开剪贴板(拥有者窗口为NULL)         EmptyClipboard(); // 清空         SetClipboardData(CF_TEXT, hGlobal); // 放置已复制到hGlobal中的ANSI文本         CloseClipboard(); // 关闭剪贴板     } }    void monitorA() // ANSI版剪贴板监视器(粘贴操作) {     DWORD content;     HGLOBAL hGlobal;     char *recstr = NULL;        while (true) {         OpenClipboard(NULL); // 打开剪贴板,所属窗口为NULL         if (hGlobal = GetClipboardData(CF_TEXT)) // 获取包含剪贴板内容的Win32内存块句柄(ANSI文本)         {             char *pGlobal = (char*)GlobalLock(hGlobal); // 锁定它并获得内存块指针             if (recstr == NULL || lstrcmpA(pGlobal, recstr) != 0) // 如果获得了新的字符串             {                 free(recstr); // 释放以前的字符串                 recstr = (char*)malloc(GlobalSize(hGlobal)); // 分配一个新的缓冲区                 if (recstr != NULL)                 {                     lstrcpyA(recstr, pGlobal); // 复制新的字符串                     fputs(recstr, stdout); // 显示该字符串                 }             }         }         CloseClipboard(); // 关闭剪贴板         Sleep(500); // 延时等待     } }    void clientW() // Unicode版剪贴板客户端(复制操作) {     DWORD content;     wchar_t wbuf[200] = {0}; // wchar_t     HGLOBAL hGlobal;        while (true)     {         fgetws(wbuf, sizeof(wbuf)/sizeof(wchar_t), stdin); // fgetws sizeof(wchar_t)                    hGlobal = GlobalAlloc(GHND, (lstrlenW(wbuf) + 1) * sizeof(wchar_t)); // lstrlenW sizeof(wchar_t)         wchar_t *pGlobal = (wchar_t*)GlobalLock(hGlobal); // wchar_t         lstrcpyW(pGlobal, wbuf); // lstrcpyW         GlobalUnlock(hGlobal);            OpenClipboard(NULL);         EmptyClipboard();         SetClipboardData(CF_UNICODETEXT, hGlobal); // Unicode文本CF_UNICODETEXT         CloseClipboard();     } }    void monitorW() // Unicode版剪贴板监视器(粘贴操作) {     DWORD content;     HGLOBAL hGlobal;     wchar_t *recstr = NULL; // wchar_t        while (true) {         OpenClipboard(NULL);         if (hGlobal = GetClipboardData(CF_UNICODETEXT)) // Unicode文本CF_UNICODETEXT         {             wchar_t *pGlobal = (wchar_t *)GlobalLock(hGlobal); // wchar_t             if (recstr == NULL || lstrcmpW(pGlobal, recstr) != 0) // lstrcmpW             {                 free(recstr);                 recstr = (wchar_t*)malloc(GlobalSize(hGlobal)); // wchar_t                 if (recstr != NULL)                 {                     lstrcpyW(recstr, pGlobal); // lstrcpyW                     fputws(recstr, stdout); // fputws                 }             }         }         CloseClipboard();         Sleep(500);     } }    int main(int argc, char* argv[]) {     char mode[2], charset[2];            setlocale(LC_CTYPE, ""); // 获取系统的区域设定,显示wchar_t需要        printf("模式(【m】onitor或【c】lient):");     scanf("%1s", mode);     printf("字符集(【a】nsi或【u】nicode):");     scanf("%1s", charset);        if (mode[0] == 'm') {         if (charset[0] == 'a') {             monitorA();         } else {             monitorW();         }     } else {         if (charset[0] == 'a') {             clientA();         } else {             clientW();         }     }        return 0; }</locale.h></stdio.h></windows.h>

[修改于 10年2个月前 - 2015/07/23 02:40:50]

来自:计算机科学 / 软件综合
1
新版本公告
~~空空如也

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,6年7个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的