admin 管理员组

文章数量: 1184232


2024年3月20日发(作者:css代码教程)

下载

第1 7章用剪贴板共享信息

本章内容:

• 剪贴板基础

• 创建你自己的剪贴板格式

以前,人类只为生存而奋斗。人们住在黑暗的山洞里,用长矛和石块打猎谋生,以喊叫和手势进

行交流。他们崇拜火,因为火给他们带来光明。随着时代的发展,人们现在使用计算机进行交流。起

初,由于受到硬件和软件的限制,计算机在同一时刻只能运行一个应用程序。因此,要想共享信息只

有一个办法,就是把信息保存到硬盘上,然后再复制到其他机器上。

今天,硬件和软件都有了改进。在Windows 95/98和Windows NT/2000等操作系统下都能够同时运

行多个应用程序,使得计算机用户的生活更加轻松、更有创造性。Wi ndows带来的一个好处是,在同

一台计算机中运行的应用程序之间可以共享信息。Wi n32剪贴板和动态数据交换( DDE)是早期的两个共

享信息技术。对于用户来说,使用任一方法都可以方便地把信息从一个应用程序复制到另一个应用程

序。

本章向你介绍如何使用D elphi环境下的Wi n32剪贴板。本书的前一版介绍过D DE,但是,有了功

能强大的信息交换技术如C OM后,我们不想再使用以前的笨方法。在稍后的第2 3章“C OM和A ctiveX”

中,我们将深入讨论C OM。但是要在应用程序间进行简单的信息共享,剪贴板仍不失为一个实用的解

决办法。

17.1 剪贴板基础

如果你是一个有经验的Wi ndows程序员,对Wi n32剪贴板应该很熟悉

至少在功能上。如果你是

一个Wi ndows编程新手,但用过Wi ndows,那么可能使用过剪贴板,但是并不知道它是怎样实现的。

几乎所有带编辑( Edit)菜单的应用程序都能使用剪贴板。究竟什么是剪贴板呢?简单来说,剪贴板

就是一块内存区域和一套Win32 API函数,通过这些函数,应用程序可在这块内存区域上保存和获取

信息。例如,你可以从D elphi编辑器中复制部分源代码并粘贴到Wi ndows记事本或其他编辑器内。

为什么Wi n32需要一套特殊的函数和消息来操纵剪贴板呢?因为,向剪贴板复制数据,并不只是

分配一块内存区域并将数据放到该区域中,还需要让其他应用程序知道数据如何读取、数据格式是否

是它支持的。Wi n32负责内存管理,你只管执行复制、粘贴和查询等操作就可以了。

剪贴板格式

Wi n32支持2 5种预定义格式,应用程序可从剪贴板复制和粘贴这些格式的数据。下面是常

用的几种格式:

CF_BITMAP位图数据。

CF_DIB带调色板的位图数据。

CF_PALETTE调色板。

CF_TEXT字符数组,每行结尾有回车/换行标志。这是最常用的格式。

如果你还想知道其他不常用的格式,可以参考Win32 API在线帮助的“S etClipboardData”

部分。此外,Win32允许你定义你自己的私有剪贴板格式,如本章稍后演示的。

5 4 0

第二部分高级技术

下载

在D elphi之前,不得不直接调用各种剪贴板函数,还需要保证应用程序不受剪贴板内容的错误影

响。有了D elphi,只需要使用一个叫C lipboard的全局变量即可。C lipboard是一个封装Wi n32剪贴板的

D elphi类。

17.1.1 剪贴板对文本操作

第1 6章“M DI应用程序”中,我们已经介绍了如何使用剪贴板来操作文本,特别是必须在M DI应

用程序中处理文本编辑器。为此,我们创建菜单项目以执行文本的剪切、复制、粘贴、删除和选择等

操作。

在M DI应用程序中,编辑器

T Memo组件覆盖了窗口的客户区。T Memo组件本身有函数与全局

C lipboard对象交互。这些函数是C utTo ClipBoard(),C opyTo ClipBoard()和P asteFromClipBoard()。

C learSelection()和S electAll()不是必须用到的剪贴板函数,但它们使你能够选择文本以拷贝到剪贴板。

清单1 7-1列出了处理编辑菜单项目的事件处理过程。

清单17-1 剪贴板对文本操作

正如清单1 7-1所示的,只要调用T Memo方法就能执行剪贴板函数。还能通过C xt属性

手工把文本放到剪贴板中。在以前的1 6位环境下,A sTe xt属性被限制在2 55个字符之内,要想把更长的

字符串复制到剪贴板中,就不得不调用函数S etTe xtBuf()和G etTe xtBuf()。在3 2位D elphi中,这个情况

是不存在的,因为A sTe xt属性现在是长字符串类型。你会注意到S etTe xtBuf()和G etTe xtBuf()仍然保留

着。

注意剪贴板函数GetTextBuf()和SetTextBuf()使用Pascal PChar类型的缓冲区来传递和接收剪贴

板的数据。在使用这些函数时,要转换长字符串为Pchar。

17.1.2 剪贴板对位图操作

剪贴板也能够复制和粘贴图像。你可以在相同的M DI例子程序中看到它的实现。清单1 7-2列出了

执行剪贴板操作的事件处理过程。

清单17-2 剪贴板对位图操作

下载

第1 7章用剪贴板共享信息

5 4 1

提示为了访问全局变量Clipboard,你必须在使用剪贴板单元的uses子句中包含ClipBrd。

在清单1 7-2中,事件处理过程m miCopyClick()调用了C ()方法来把图像复制到剪贴

板中。用这个方法,你可以把图像粘贴到另一个支持C F _ B I T M A P格式的Wi n 3 2应用程序中,如

Windows Paint()。

m miPasteClick()调用I ()方法从剪贴板中复制图像并相应重新调整滚动条。

注意C F_PICTURE不是标准的Wi n32剪贴板格式。相反,它是D elphi应用程序独有的格式,

用于判断剪贴板中的数据是否与T Picture兼容,如位图和图元文件( metafile)。如果你想注册自

己的图形格式,T Picture将支持这个格式。在D elphi在线帮助中,你可以进一步查找T Picture以

获取与TPicture兼容格式有关的信息。

17.2 创建你自己的剪贴板格式

假设我们正在使用一个地址输入程序。如果正要输入的记录与前一条记录只有细微的差别,方便

的做法是复制前一个记录的内容并将其粘贴到当前记录,而不是一个字段一个字段地再输入。可以在

其他应用程序中采用同样的方法下一个例子将介绍如何创建一个感知Wi n32剪贴板的对象,它能够把

自己的特殊格式的数据保存到剪贴板。还能学到怎样保存诸如C F_TEXT格式的信息,这样就能够在其

他支持C F_TEXT格式的应用程序中获取同样的数据。

17.2.1 创建一个感知剪贴板的对象

你可能会想到,自定义剪贴板格式的一种方法是创建一个了解新定义格式的T Clipboard派生类,

这个特殊的T Clipboard类要包含处理自定义格式的特殊方法。虽然这样的类可以解决某些特殊的格式,

但是当需要其他格式或重定义数据格式时,重复这个工作将是非常乏味的。如果7 0个不同的厂商为各

自的自定义剪贴板格式提供自己的T Clipboard派生类,即使只使用其中的两个格式也会出现问题,因

为它们之间会发生冲突。

一个比较好的办法是定义一个对象把数据包装起来,并使它与剪贴板相联系。剪贴板的这种独有

模式与B orland使用的D elphi组件方法相同。T Memo组件知道如何把数据放到剪贴板中,正如T Image组

件知道如何把数据放到剪贴板中一样。所有组件使用相同的T Clipboard对象,因此没有冲突。下面我

们将介绍这个方法,它定义一种剪贴板格式,该剪贴板格式大致是一个具体人的名字、年龄和出生日

期等信息的记录。清单1 7-3列出了定义数据的代码和从剪贴板复制和粘贴数据的方法。

清单17-3 自定义剪贴板数据的单元

5 4 2

第二部分高级技术

下载

下载

第1 7章用剪贴板共享信息

5 4 3

这个单元执行了几项任务。首先,它调用R egisterClipboardFormat()函数注册了Wi n32剪贴板的新

格式并返回这个新格式的标识号。任何其他函数若注册了相同的格式,调用这个函数会得到同样的返

回值。新格式将出现在剪贴板格式列表中,此格式列表可被C 属性访问。

这个单元还定义了一个记录T DataRec和一个对象,该记录包含了放到剪贴板的数据,而对象封装

5 4 4

第二部分高级技术

下载

了这个记录。T DataRec有一个字符串域用于存储姓名,一个整型域用于存储年龄,还有一个T DataTi me

类型域用于存储出生日期。

T Data对象封装了T DataRec记录,并且定义了两个方法:C opyTo Clipboard()和G etFromClipboard()。

TData. CopyTo Clipboard()方法以C F_DDGDATA和C F_TEXT两种格式把T 域的内容放到剪

贴板上。C F_TEXT是一个已定义的剪贴板格式。TData. Rec域的文本将连接成一个字符串,域与域之

间由回车/换行隔开,然后放到剪贴板中。在存放之前,非字符串类型的域已转换成字符串类型。

C andle()先要把给定的句柄存放到剪贴板中,格式由参数指定。这里,这个参数就是新

定义的剪贴板格式C F_DDGDATA。

然而,在调用C andle()之前,需要准备一个有效的T Handle句柄以传递给S etAs-

H andle()。这个句柄代表被放到剪贴板的数据所在的内存块,参见“使用T Handl”。下列代码让Wi n32

系统分配S izeOf(TDataRec)个字节的可移动内存,如果必要的话,同时返回变量D ata的内存句柄:

下列语句可获得该内存的指针:

调用M ove()函数就可把数据放到该内存块中。在剩下的代码行中,用Clipboard. Open ()方法打开

剪贴板,以防止其他应用程序向剪贴板送数据:

一般地,不需要调用O p e n ( ),除非要把多种格式的数据送到剪贴板中。这是因为,每次通过

C xtBuf()等方法和C xt()等属性使用剪贴板时,剪贴板会清空以前的内容,

因为它们内部也调用Open ()和C lose()。通过先调用C (),就可以阻止剪贴板清空,因此

能够同时把几种格式的数据放到剪贴板中。如果没有调用Open (),执行这个方法后只能传递C F_TEXT

格式的数据。调用Open ()并放置数据之后,需要调用ClipBoard. Close()。

在这里,Wi n32系统负责管理由G lobalAlloc()函数分配给剪贴板的内存。在传递数据的过程中,只

有发生异常时才需要调用G lobalFree()来释放内存,否则不需要调用它,因为Wi n32接管对剪贴板内存

的管理。

只要剪贴板支持C F_DDGDATA和C F_TEXT两种格式,就能够把数据粘贴到其他应用程序,就像

我们即将说明的那样。

T mClipboard()方法做相反的工作

它以C F_DDGDATA格式从剪贴板中获取数据并

放到T 域中。下面的清单将介绍如何使用这个方法。注意,只要适当修改,剪贴板对象就能存

储你可以定义的任何记录类型。

注意不要释放GetAsHandle()返回的句柄;它不属于应用程序,它属于剪贴板。因此,应该复

制句柄所引用的数据。

使用THandle

一个T Handle句柄只是个3 2位的变量,代表着一个Wi n32系统管理的内存块。T Handle类型

有许多种,Dephi用TIcon、TBitmap、TCanvas等封装了大多数的句柄。

下载

第1 7章用剪贴板共享信息

5 4 5

某些Wi n32函数,如各种剪贴板函数,使用堆来处理剪贴板数据。为了访问堆内存,你需

要使用下列内存分配函数:

GlobalAlloc()从堆中分配指定的字节数并返回指向内存对象的句柄。

GlobalFree()释放由GlobalAlloc()分配的内存。

GlobalLock()返回由GlobalAlloc()分配的全局内存对象的指针。

GlobalUnlock()解除GlobalLock()对内存的锁定。

17.2.2 使用自定义的剪贴板格式

下面要介绍的程序演示了如何使用自定义的剪贴板格式。这个程序的主窗口如图1 7-1所示。

图17-1 自定义剪贴板格式演示程序的主窗体

如图所示,这个窗体含有一些控件,用于填充T Data对象的T DataRec域。清单1 7-4列出了这个窗

体的源代码。这个程序在光盘上为D 。

清单17-4 使用自定义剪贴板格式的程序源代码

5 4 6

第二部分高级技术

下载

下载

第1 7章用剪贴板共享信息

5 4 7

当用户单击C opy按钮时,程序把T Edit、T DataTi me-

P icker和T MaskEdit控件中的数据复制到T Data对象的

T DataRec域内。然后,调用T Clipboard()把数

据放到剪贴板中。

当用户单击P aste按钮时,情况相反。首先,若剪贴

板中的数据为C F_DDGDATA类型,则从剪贴板复制数

据并把数据放到窗口上的编辑框中。同时,文本格式的

数据也被复制并放到主窗口的T Memo组件中。粘贴操作

的结果如图1 7-2所示。你也可以把文本格式的数据粘贴

到其他Wi ndows应用程序中,如记事本。

单击C lear按钮清空主窗口上所有控件的内容。

图17-2 在主窗口上粘贴数据

17.3 总结

与其他应用程序共享数据是一个非常有用的技术。这样会使应用程序发挥更大的作用,会使用户

更富有创造性。本章向你介绍了如何使用剪贴板内建函数来处理D elphi控件,以及如何创建你的自定

义剪贴板格式。下一章将深入讨论C OM,它是另一种更强大的在应用程序间通信的方法。


本文标签: 剪贴板 格式 数据 使用 应用程序