12.1剪贴簿的简单使用
标准剪贴簿数据格式
Windows支持不同的预先定义剪贴簿格式, 这些格式在WINUSER.H定义成以CF为前缀的标识符。
■三种能够储存在剪贴簿上的文字数据型态:
①CF_TEXT 以NULL结尾的ANSI字符集字符串。它在每行末尾包含一个carriage return和linefeed字符,这是最简单的剪贴簿数据格式。
②CF_OEMTEXT 含有文字数据(与CF_TEXT类似)的内存块。但是它使用的是OEM字符集。
③CF_UNICODETEXT 含有Unicode文字的内存块。与CF_TEXT类似,它在每一行的末尾包含一个carriage return和linefeed字符,以及一个NULL字符(两个0字节)以表示数据结束。CF_UNICODETEXT只支援Windows NT。
■两种附加的剪贴簿格式、但是它们不需要以NULL结尾,因为格式已经定义了数据的结尾。
①CF_SYLK 包含Microsoft 「符号连结」数据格式的整体内存块。这种格式用在Microsoft的Multiplan、Chart和Excel程序之间交换数据,它是一种ASCII码格式。
②CF_DIF 包含数据交换格式(DIF)之数据的整体内存块。用于把数据送到VisiCalc电子表格程序中。这也是一种ASCII码格式
■下面三种剪贴簿格式与位图有关。所谓位图就是数据位的矩形数组
①CF_BITMAP 与设备相关的位图格式。位图是通过位图句柄传送给剪贴簿的。
②CF_DIB 定义一个设备无关位图的内存块。
③CF_PALETTE 调色盘句柄。
■下面是两个metafile格式、metafile就是一个以二进制格式储存的画图命令集
①CF_METAFILEPICT 以旧的metafile格式存放的「图片」 。
②CF_ENHMETAFILE 增强型metafile(32位Windows支持的)句柄。
■最后介绍几个混合型的剪贴簿格式:
CF_PENDATA与Windows的笔式输入扩充功能联合使用。
CF_WAVE声音(波形)文件。
CF_RIFF使用资源交换文件格式(Resource Interchange File Format)的多媒体数据。
CF_HDROP与拖放服务相关的文件列表。
内存配置
程序向剪贴簿传输一些数据的时候,必须配置一个内存块,并且将这块内存交给剪贴簿处理。Windows中执行的应用程序之间必须要共享剪贴簿所储存的内存块,所以可以使用下面的函数来配置一块内存:此函数有两个参数:一系列可能的旗标和内存块的字节大小。函数传回一个HGLOBAL型态的句柄,称为「整体内存块句柄」或「整体句柄」。传回值为NULL表示不能配置足够的内存。 GlobalAlloc的两个参数略有不同,但它们都是32位的无正负号整数。
hGlobal = GlobalAlloc(uiFlags, dwSize);
下面是一个重新配置函数:
hGlobal = GlobalReAlloc (hGlobal, dwSize, uiFlags);
下面是获得内存块大小的函数:
dwSize = GlobalSize(hGlobal);
释放内存块的函数:
GlobalFree(hGlobal);
GMEM_MOVEABLE旗标允许Windows在虚拟内存中移动一个内存块。这不是说将在物理内存中移动内存块,只是应用程序用于读写这块内存的地址可以被变动
p = (int *)GlobalLock(hGlobal);
此函数将句柄转换为指标。在内存块被锁定期间,Windows将固定虚拟内存中的地址,不再移动那块内存。存取结束后呼叫:GlobalUnlock(hGlobal);
为剪贴簿配置内存时,您应该以GMEM_MOVEABLE和GMEM_SHARE旗标呼叫GlobalAlloc函数。GMEM_SHARE旗标使得其它应用程序也可以使用那块内存。
将文字传送到剪贴簿
1.希望传送这个字符串的iLength字符,这些字符可能以NULL结尾也可能不以NULL结尾。hGlobal = GlobalAlloc (GHND | GMEM_SHARE, iLength + 1) ;
2.如果配置成功,则锁定这块内存 pGlobal = GlobalLock (hGlobal) ;
3.将字符串复制到内存块中:
for (i = 0 ; i < wLength ; i++)
*pGlobal++ = *pString++;
4.内存块解锁 GlobalUnlock(hGlobal);
5.打开剪贴簿并把它清空:
OpenClipboard (hwnd);
EmptyClipboard ();
6.利用CF_TEXT标识符把内存句柄交给剪贴簿,关闭剪贴簿:
SetClipboardData(CF_TEXT, hGlobal);
CloseClipboard();
当呼叫SetClipboardData后,请不要再继续使用该内存块。它不再属于使用者程序
从剪贴簿上取得文字
确定剪贴簿是否含有文字一共有2种方法。
①bAvailable = IsClipboardFormatAvailable(CF_TEXT); 如果剪贴簿上含有CF_TEXT数据,这个函数将传回TRUE(非零)IsClipboardFormatAvailable是少数几个不需先打开剪贴簿就可以使用的剪贴簿函数之一。
②为了传送出文字,首先打开剪贴簿: OpenClipboard(hwnd);
会得到代表文字的内存块代号: hGlobal = GetClipboardData(CF_TEXT);
hGlobal句柄仅在GetClipboardData和CloseClipboard呼叫之间这个句柄才有效。
如果剪贴簿不包含CF_TEXT格式的数据,此句柄就为NULL。如果GetClipboardData传回NULL,则关闭剪贴簿,不做其它任何工作
将数据复制到使用者程序中的方法:
配置一块与剪贴簿数据块大小相同的内存块,并配置一个指向该块的指标:pText = (char*)malloc(GlobalSize (hGlobal));
锁定以后就可以复制数据了: 复制数据可以用下面2种方法:①strcpy(pText, pGlobal); ②while(*pText++ = *pGlobal++);
打开和关闭剪贴簿
在任何时候,只有一个程序可以打开剪贴簿。
剪贴簿和Unicode
如果先在Unicode版的CLIPTEXT中选择了「Copy」命令,然后在非Unicode版中选择「Paste」命令,那么您就能看到文字已经从Unicode转换成了ANSI。类似地,如果您执行相反的操作,那么文字就会从ANSI转换成Unicode。