剪切板

本文详细介绍了Windows剪切板的基本操作,包括写入和读取数据的过程,如何使用延迟渲染技术减少内存占用,以及如何处理私有数据格式和实现剪切板监视。还介绍了剪切板相关API的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

剪切板数据格式有三类:文本(text)、位图(bitmap)和元文件(metafile),每类又有细分,定义在WINUSER.H中,CF_开头。

写入剪切板

GlobalAlloc(GHND | GMEEM_SHARE,nSize):返回一个全局句柄

GlobalLock(hGlobal):返回内存块指针。

写数据

GlobalUnlock(hGlobal)

OpenClipboard(hwnd):任何时候只能有一个程序打开剪切板,打开成功返回TRUE。

EmptyClipboard()

SetClipboardData(CF_TEXT,hGlobal):第一个参数是数据格式,都以CF_开头。不要传送一个加锁的句柄给剪切板。调用这个函数后,不能继续使用内存块。这个函数返回一个可用全局句柄,加锁后可以访问内存,在CloseClipboard之前开锁。

CloseClipboard():要尽可能早关,如果有模态对话框,一定要先关剪切板再弹对话框。

 

从剪切板读

IsClipboardFormatAvailbale(CF_TEXT):可以不打开剪切板调用,如果要读取,在打开剪切板之后应该再调用一次,确保数据还在。

GetClipboardData(CF_TEXT):返回全局句柄,也是判断剪切板中有没有CF_TEXT的一种方法。

OpenClipboard(hwnd);

GlobalSize(hGlobal):句柄所指内存块大小。

GlobalLock(hGlobal);

读数据

GlobalUnlock(hGlobal):

CloseClipboard();

 

在向剪切板写数据前,要先清空剪切板,但可以在清空后多次调用SetClipboardData,每次写入不同的格式的数据,但不要写不同的文本数据、位图数据或元文件数据。

EnumClipboardFormats(iFormat):返回剪切板中的数据类型。在打开剪切板前初始化iFormat=0,打开后循环iFormat=EnumClipboardFormats(iFormat)直到iFormat为0。

CountClipboardFormats():返回剪切板中现在可能的类型数。

 

推迟拷贝(Delay Rendering)

上面的方法,数据写到剪切板直到下次拷贝才能清除。如果写入剪切板数据量大时,就会很占内存。为避免这个问题,可以使用Delay Rendering技术。在调用SetClipboardData第二个参数设为NULL,然后直接关闭剪切板。这样,有用户拷贝数据时会给剪切板的拥有者(调用EmptyClipboard时Windows标记窗口为剪切板拥有者)发送消息。

使用这种技术需要在窗口过程中处理三个消息:WM_RENDERFORMAT、WM_RENDERALLFORMAT、WM_DESTROYCLIPBOARD。

当用户调用GetClipboardData时给剪切板拥有者发送WM_RENDERFORMAT消息,wParam是请求的数据格式。处理这个消息时,不要打开和清空剪切板,直接调用SetClipboardData把全局数据转换为剪切板数据。

当其他的程序清空剪切板时,系统发送WM_DESTORYCLIPBOARD。

如果程序结束时,该程序还是剪切板拥有者,系统发送WM_RENDERALLFORMAT消息,一般在这个消息中要打开、清空剪切板,把所有格式数据写到剪切板。

 

私有数据格式

GetClipboardOwner():返回剪切板拥有者窗口句柄。

GetClassName(hwnd,szClassName,iMaxLen):获取hwnd的窗口类名,如果名字一样,说明是同一个程序的不同实例,可以拷贝私有格式数据。

RegisterClipboardFormat(szFormatName):注册私有格式,返回值在0xC000到0xFFFF之间。

GetClipboardFormatName(iFormat,pzBuffer,iMaxCount):通过EnumClipboardFormats能够得到数据格式ID,这个函数可以以ID获取格式名,这样当一个私有数据广泛应用时,私有数据可以在不同的程序间拷贝。

 

剪切板监视器(Clipboard Viewer)

Windows可以有任意数量的剪切板监视器,但对系统而言只有一个——当前监视器窗口,所有监视器通过监视链维护,系统只给第一个监视器发消息,之后消息由监视器向后传。当剪切板内容变化时,系统发送WM_DRAWCLIPBOARD消息

SetClipboardViewer(hwnd):把hwnd加入监视链,返回上一个加入的窗口句柄,如果是第一个,则返回值为NULL。新加的窗口在链条头部,成为“当前监视器”,因而返回的窗口句柄应该是“下一个”

ChangeClipboardChain(hwnd,hwndNextViewer):移除监视。参数分别是本窗口和下个监视窗口的句柄。这个函数给当前窗口发送WM_CHANGECBCHAIN消息,wParam是要移除的窗口(函数的第一个参数),lParam是移除窗口的下一个窗口(函数的第二个参数),所有监视器都要处理这个消息,下面是个示例代码:第一个判断是判断本窗口是不是移除窗口的上一个窗口,如果是,把下个窗口改为移除窗口的下一个窗口,如果不是,继续向后传递这个消息。

GetClipboardViewer():返回第一个监视窗口句柄。这个函数一般不需要。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值