《Windows程序设计》读书笔十二 剪贴板

本文详细介绍了Windows程序设计中关于剪贴板的使用,包括剪贴板数据的多种标准格式如CF_TEXT、CF_BITMAP等,内存分配的GlobalAlloc函数,以及如何将文本传入和从剪贴板获取文本。还探讨了剪贴板的高级用法,如延迟呈现、私有数据类型以及实现一个剪贴板查看器所需的功能和消息处理。
摘要由CSDN通过智能技术生成

第十二章 剪贴板


12.1 剪贴板的简单用法

12.1.1 剪贴板数据的标准格式

CF_TEXT  一种以NULL结尾的ANSI字符集字符串,字符串的每行结尾有一个回车换行符。

CF_OEMTEXT 包含文本数据(CF_TEXT)但使用OEM字符集的内存块。 在窗口运行MS-DOS程序时如果使用剪贴板需要使用这种类型

CF_UNICODETEXT 包含Unicode文本的内存块。类似于CF_TEXT, 以回车换行结束,字符NULL(两个0字节)标志整个数据结束。

CF_LOCALE  指向区域设置标识符的句柄,表明了与剪贴板相关的区域设置


CF_SYLK  包含微软符号链接格式数据的内存块。用作multiplan, chart Excel程序之间交换数据。 一种ASCII格式,每行以回车换行符结束。

CF_DIF 含有数据交换格式DIF数据的内存块。 


与位图相关的剪贴板格式有三种。即位图对应于输出设备像素的矩形位数组。

CF_BITMAP 设备相关位图。 (程序把位图传给剪贴板之后不应该继续使用此位图)

CF_DIB 定义了设备无关位图的内存块。

CF_PALETTE 指向调色板的句柄。 通常和CF_DIB一起使用,用来定义设备相关位图中使用的调色板。

CF_TIFF 包含标签图像文件格式(Tag Image File Format)数据的内存块。

还有两种图元格式(以二进制形式存储的绘图命令的集合)

CF_METAFILEPICT 基于windows过去支持的图元文件的“图元文件图片”。

CF_ENHMETAFILE 指向32位windows版本支持的增强型图元文件的句柄


CF_PENDATA  和windows画笔一起使用

CF_WAVE 声音波形文件

CF_RIFF  资源交换文件格式(RIFF)的多媒体数据

CF_HDROP 和拖放服务一起使用的文件列表。


12.1.2  内存分配

由于剪贴板中存储的内存块必须在windows下运行的应用程序之间共享,malloc函数不足以完成此任务。


取而代之的是,windows早起设计的内存分配函数,

hGlobal = GlobalAlloc(uiFlags, dwSize);

返回HGLOBAL类型的句柄,称为 指向全局内存块的句柄(handle to a global memory block) "全局句柄"

返回NULL表示没有足够的内存空间可以分配。

uiFlags  0  使用GME_FIXED   函数返回的全局句柄实际是一个指向被分配内存块的指针

   GME_ZEROINIT    把分配的内存块初始化为0.

#define GPTR (GMEM_FIXED | GMEM_ZEROINIT)

内存重分配函数

hGlobal = GlobalReAlloc(hGlobal, dwSize, uiFlags);

取得内存分配大小

dwSize = GlobalSize(hGlobal);

释放内存的函数是

GlobalFree(hGlobal);


#define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT)

GMEM_MOVEABLE 使得windows能在虚拟内存中移动内存块。 并不意味内存块绘制物理内存中移动,仅仅是此应用程序用来读写内存块的地址可能会改变。


GMEM_MOVEABLE 仅用16位系统上。

如果应用程序频繁分配,重分配,释放不同大小的内存块,应用程序虚拟机制控件会变得七零八碎。可能会把虚拟内存地址用完。如果是个潜在问题,就需要使用可移动内存。


做法如下

定义一个指针

int * p;

GLOBALHANDLE hGlobal;


分配内存

hGlobal = GlobalAlloc(GHND, 1024);

p = (int *) GlobalLock(hGlobal);  //把全局内存句柄转换为指针, windows会修复内虚拟内存地址。内存块不会移动。

使用完以后调用

GlobalUnlock(hGlobal); 解锁内存块

释放内存 GlobalFree(hGlobal); //参数是全局内存句柄而非指针

如果没有可访问的句柄可以使用

hGlobal = GlobalHandle(p);

使用可移动内存的原因是防止内存碎片,在使用剪贴板时也可以使用可移动内存。

为剪贴板分配内存使用  GlobalAlloc   标志使用  GMEM_MOVEABLE 和  GMEM_SHARE标志作为参数。GMEM_SHARE标志使得内存能被其他应用程序共享


12.1.3 把文本传到剪贴板

hGlobal = GlobalAlloc(GHND | GMEM_SHARE, iLength + 1); //给字符串终止符预留空间

如果分配失败 hGlobal = NULL

如果分配成功,锁定此空间

pGlobal = GlobalLock(hGlobal);

把字符串复制到内存块

for ( i  = 0; i < wLength; i++)

    *pGlobal++ = *pString++;   //不需要加终止符,因为GHND标志初始化时全部填充0

解锁内存

GlobalUnlock(hGlobal);

现在可以传入剪贴板

OpenClipboard(hwnd);

EmptyClipboard(); 清空剪贴板


SetClipboardData(CF_TEXT, hGlobal); // 把全局句柄传入,标志设置为CF_TEXT

CloseClipboard();  完事


注意:

在单个消息过程中调用OpenClipboard 和CloseClipboard. 避免不必要长时间打开剪贴板

不要把锁定的内存传给剪贴板 (应该解锁)

调用SetClipboardData 以后不可再使用该内存块,他已经不再属于程序。 如果需要继续使用,应该在复制一份或者从剪贴板中读取。

在SetClipboardData 和  CloseClipboard之间,可以继续应用该内存块,但是不要使用传给SetClipboardData函数的全局句柄。

你可以使用SetClipboardData返回的句柄,并锁定来修改内存。  在调用CloseClipboard之前解锁这个句柄。



12.1.4  从剪贴板中取得文本

判断是否存在文本

bAvailable = IsClipboardFormatAvailable(CF_TEXT);

若存在返回TRUE


OpenClipboard(hwnd)    打开剪贴板

hGlobal = GetClipboardData(CF_TEXT);  获取全局句柄,如果无CF_TEXT 则返回NULL,并关闭剪贴板 CloseClipboard

pText = (char *)malloc(GlobalSize(hGlobal));   申请内存

pGlobal = GlobalLock(hGlobal);   锁定全局句柄

strcpy(pText, pGlobal); 拷贝数据

或者  while( *pText++ = *pGlobal++)

;

GlobalUnlock(pGlobal);   解锁全局句柄

CloseClipboard 关

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值