跟我一起玩Win32开发(21):复制&粘贴&剪贴板操作
我要提醒一下大家,看了我的博文学到的知识,千万不要用于实际开发,不然你会被你的上司骂:“妈的,这些东西哪来的,从来没有人这样做过。”不信你试试,脑细胞被冻结的经理或者技术总监们肯定会这样说的。
如果是一些有X年工作经验(X永远不可能大于100)的程序员肯定会说:“你怎么这么不成熟?”你如果被别人这么说之后,不知道你会不会很伤心,或者很生气?
我呢,曾经被N个人这样教育过,不过你猜猜我当时的心情,我非常高兴,喜悦。为什么呢?
你不妨想想,当一个人说你不成熟的时候,你说他其实在说什么,他其实是在说他自己很成熟,就因为他自己熟得快腐烂了,满身恶臭,才会显得你不成熟,仔细想想,是不是这个事儿?
那么,成熟到底好不好呢?我相信小学生都有这样的常识,当一个果子熟透了的时候,会怎么样?它会从树枝上高空坠落,然后狠巴巴地摔到地上,粉身碎骨。呵呵,所以,你现在明白了吧,当别人说我不成熟的时候,我会非常高兴,我心里想:“快了快了,你快完蛋了。”
----------------------------------------------------------------------------------------------------------------
好,牛皮吹完,乐一乐。下面开始干正事,今天咱们来认识一下怎么操作粘贴板,即复制和粘贴数据。我不知道大家看不看恐怖片,反正我现在不得不吓你一回。这个粘贴板的操作,其实挺痛苦的,所以,如果在实际开发中,我肯定用CLR的类来弄,是的,这是我的做事原则,哪种方法最简单就用哪种,这叫什么?效率最大化,只有闲着没事干的人才会简单问题复杂化。
不过呢,毕竟这里咱们要了解一下在Win32下操作粘贴板的,所以呢,我还是用API来解决,至于CLR方法,相信你比我更会用,你不信算了,反正我信了,我不是菜鸟,但我是菜鹤。
读写粘贴板就像我们上厕所一样,首先打开厕所门(调用OpenClipboard函数),然后大动作(SetClipboardData或GetClipboardData),干完了出来,关上厕所门(调用CloseClipboard)。
我说它有点痛苦是因为操作的时睺,与我们平常读写一些数据不同,数据写入到剪贴板后就由操作系统接管了,期间你不能任意读写,就像公共厕所是提供给你用的,你不能在里面给人家装修,拆掉人家的东西。
一、复制数据
我这里就不弄太复杂了,就复制一串文本吧,这也常用。先看看代码。
- //复制内容
- //打开剪贴板
- OpenClipboard(hdlg);
- //清空剪贴板
- EmptyClipboard();
- //向剪贴板中放东西
- HWND hedt = GetDlgItem(hdlg, IDC_EDTCPY);
- WCHAR ntext[100];
- SendMessage(hedt, WM_GETTEXT, (WPARAM)100, (LPARAM)ntext);
- //分配内存
- HGLOBAL hgl = GlobalAlloc(GMEM_MOVEABLE, 100 * sizeof(WCHAR));
- LPWSTR lpstrcpy = (LPWSTR)GlobalLock(hgl);
- memcpy(lpstrcpy, ntext, 100 * sizeof(WCHAR));
- GlobalUnlock(hgl);
- SetClipboardData(CF_TEXT, lpstrcpy);
- //关闭剪贴板
- CloseClipboard();
大家看到,在打开剪贴板后,要先清空一下,调用EmptyClipboard函数,把里面的东西清了,才能放东西进去。但是我们不能直接用SetClipboardData设置数据,不然你试试,会失败,因为数据虽然是我们放进去的,但他归系统管,虽然我们的房子是自己买的,但也归小区物业公司管理。
因此,我们要通过内存拷贝来完成,GlobalAlloc函数分配全局内存块,不过标志参数要用GMEM_MOVEABLE,为什么,看MSDN怎么说的。
你可能会问,SetClipboardData中的参数是HANDLE类型的,为什么不用转换就能与
If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system, but it can lock and read from the data until the CloseClipboard function is called. (The memory must be unlocked before the Clipboard is closed.) If the hMem parameter identifies a memory object, the object must have been allocated using the function with the GMEM_MOVEABLE flag.
这段话不知道你看懂了没有,反正我看不懂,很难翻译,干脆不译了。就是这段话告诉了我们,用GlobalAlloc分配内存时要用GMEM_MOVEABLE标志。既然内存是动的(当然物理内存是固定的),那我们在拷贝前当然要把它锁定,拷贝完了再解锁,防止这块内存被外星人意外修改了。
二、粘贴数据
复制完了,就粘贴了。
- else if(LOWORD(wParam) == IDC_BTNPAST)
- {
- HWND hedtPas = GetDlgItem(hdlg, IDC_EDTPAST);
- OpenClipboard(hdlg);
- //判熂是否为文本内容
- if(IsClipboardFormatAvailable(CF_TEXT))
- {
- //取出数据
- HGLOBAL hg = GetClipboardData(CF_TEXT);
- //锁定内存块
- LPWSTR wstr = (LPWSTR)GlobalLock(hg);
- if(wstr != NULL)
- {
- SendMessage(hedtPas, WM_SETTEXT, NULL, (LPARAM)wstr);
- }
- GlobalUnlock(hg);
- }
- CloseClipboard();
- }
这里干吗要用IsClipboardFormatAvailable来检测一下剪贴板中是不是CF_TEXT格式的数据呢?因为在你复制了文本后,有可能在这期间其他程序把其他数据放到剪贴板上了,所以,要检查一下好,谨慎一点总是没有错的。
也许你会问,GetClipboardData不是返回HANDLE类型吗?怎么可以赋给HGLOBAL类型的变量而不用转换呢,你把开对应头文件看看就懂了,HGLOBAL就是HANDLE。
好了,就这样吧,只要你简单了解操作过程就够了,不必深究,呵呵,因为有比这更简单的方法。
跟我一起玩Win32开发(21):复制&粘贴&剪贴板操作的更多相关文章
- 跟我一起玩Win32开发(转自CSDN-东邪独孤)
跟我一起玩Win32开发(1):关于C++的几个要点 跟我一起玩Win32开发(2):完整的开发流程 跟我一起玩Win32开发(3):窗口的重绘 跟我一起玩Win32开发(4):创建菜单 跟我一起玩W ...
- 跟我一起玩Win32开发(17):启动和结束进程
这里我再次说明一下,我不知道为什么,现在的人那么喜欢走极端,估计是价值观都“升级”了的缘故吧. 我撰写这一系列Win32相关的文章,并不是叫大家一定要用Win32去开发项目,仅仅是给大家了解一下,Wi ...
- 跟我一起玩Win32开发(12):使用控件——单选按钮
今天,咱们还是接着玩“控件斗地主”,这是我原创的超级游戏,有益身心健康,玩一朝,十年少. 哦,对,脑细胞极速运动了一下,想起了一个问题,这个破问题虽然网上有很多种解决方案,但是,并没有让所有人都解决问 ...
- 跟我一起玩Win32开发(18):使用对话框的两个技巧
相信大家知道对话框怎么用了,就是先用“资源编辑器”设计一个对话框,然后在代码中加载处理.今天,我向大家分享两个使用对话框的技巧,还是比较实用的.不用担心,先喝杯茶,很简单的,一点也不复杂,总之,看俺写 ...
- iOS开发之--复制粘贴功能
复制粘贴功能,代码如下: 1.复制功能 UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; pasteboard.string = ...
- Android 复制 粘贴 剪贴板的使用 ClipboardManager
Copy and Paste 版本:Android 4.0 r1 快速查看 用于复制粘贴数据的基于剪贴板的框架. 同时支持简单和复杂的数据,包括文本串.复杂的数据结构.文本和二进制流数据.程序 as ...
- 跟我一起玩Win32开发(19):浏览和打开文件
在应用程序中,我们很经常要实现的功能,是Open文件或保存文件对话框,让用户来选择一个或N个文件.本文我将介绍两种思路,第一种方法较为复杂,第二种方法较为简单. 方法一:老规矩 这是一种传统方法,使用 ...
- 跟我一起玩Win32开发(25):监视剪贴板
自从郭大侠和蓉儿离开桃花岛后,最近岛比较寂静,有一种“门前冷落鞍马稀”的感觉.于是,老邪就拿出<九阴真经>认真阅读,同时用迅雷下载经典大剧<汉武大帝>晚上睡觉前看上几集,老邪一 ...
- 跟我一起玩Win32开发(4):创建菜单
也不知道发生什么事情,CSDN把我的文章弄到首页,结果有不少说我在误人子弟,是啊,我去年就说过了,如果你要成为砖家级人物,请远离我的博客,我这个人没什么特长,唯一厉害的一点就是不相信权威,鄙视砖家,所 ...
随机推荐
- Qt中 QString 和int,double等的转换
Qt中 int ,float ,double转换为QString 有两种方法 1.使用 QString::number(); 如: long a = 63; QString s = QString:: ...
- 云打印-Beta-凡事预则立
凡事预则立 课程名称:软件工程1916|W(福州大学) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标:Beta冲刺 团队队员 队员学号 队员姓名 个人博客地址 备注 221600 ...
- sendmessage传递数组
1.在初始化数组尤其是需要每次都初始化的时候,很多同学使用循环来进行,这样不但速度慢,而且写起来也很长.所以现在提供一个函数来实现这个功能... 原型:extern void *memset(void ...
- CH 5402 选课(分组背包+树形DP)
CH 5402 选课 \(solution:\) 很有讨论套路的一道题,利用树的结构来表示出不同课程之间的包含关系(这里还要建一个虚点将森林变成一颗打大树).然后用子树这个概念巧妙的消除了因为这些包含 ...
- acd - 1427 - Nice Sequence(线段树)
题意:一个由n个数组成的序列(序列元素的范围是[0, n]).求最长前缀 j .使得在这个前缀 j 中对于随意的数 i1 < i2.都满足随意的 m <= j.i1 在前 m 个数里出现的 ...
- ICMP协议 广播以查询局域网内的所有主机
看到了很多局域网内的主机扫描工具,在想怎么去实现这样一个工具.前几天看了Ping源码--ICMP协议的实例,ICMP可以用来探测网联网内的任一主机,ICMP和广播地址结合来扫描局域网内的所有主机不是很 ...
- 获取Android系统应用信息
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- spin_lock、spin_lock_irq、spin_lock_irqsave区别
void spin_lock(spinlock_t *lock); void spin_lock_irq(spinlock_t *lock); void spin_lock_irqsave(spinl ...
- chmod更改文件的权限
#include "apue.h" int main(int argc,char *argv[]) { struct stat stabuf; ) err_sys("st ...
- 织梦文章页调用当前栏目名称和url地址的方法
其实织梦本身有这2个调用标签,可能大家没怎么注意,下面的代码就是织梦文章页调用当前栏目名称和url地址的方法: {dede:field name='typeurl' function=”GetType ...