复制和粘贴文本很容易,因为它内置在 TMemo 中,但它似乎只能处理文本。不过,在我看来,任何类型的数据都可以表示为字符串。如果我从另一个程序复制一些任意数据并想将其粘贴到 TMemo 中,我如何让 Delphi 将其作为原始字符串接受?
4 回答
“如果我从另一个程序复制一些任意数据并想将其粘贴到 TMemo 中,我如何让 Delphi 接受它作为原始字符串?” 因此,为了澄清您的问题,您:
- 想要使用任何其他应用程序(一个您没有代码的普通应用程序)并在其中复制一些内容
- 想要将此复制的数据(可以是任何格式,包括非文本)粘贴为备忘录中的文本。
那是对的吗?如果是这样,您不能使用- 只有在剪贴板上Clipboard.AsText
有格式的数据时才会返回文本。CF_TEXT
您需要直接使用剪贴板 API。剪贴板保存带有格式代码的数据,您可以获得指向该数据的指针和大小,并将其视为字符串或您想要的任何方式。
所以:
- 找出您要粘贴的格式。您可以通过 遍历剪贴板上当前的所有格式
EnumClipboardFormats
,或使用预定义的常量之一(用于文本、图像、音频等)。剪贴板可以同时保存多种格式的数据,因此您可能需要选择多种格式中的哪一种你用。 - 如果剪贴板上有这种格式的数据,请打开它。确保将此代码包装在 a 中
try/finally
并关闭finally
子句中的剪贴板。如果您不关闭剪贴板,其他应用程序将无法使用它,因此即使您的应用程序崩溃,您也希望将其关闭。 - 调用
GetClipboardData
以获取该格式数据的句柄。上的数据(或给定,如果您稍后实现 Copy)是通过 分配的GlobalAlloc
,因此您需要锁定句柄以通过获取指向它的指针GlobalLock
(一旦完成,使用 解锁GlobalUnlock
。)数据归剪贴板所有,所以不要使用后释放它。要查找此数据的大小(以字节为单位),请使用GlobalSize
. - 这为您提供了一个指向已知大小的数据的指针。在这一点上,你可以用它做任何你想做的事情。将其视为字符串是一种选择。由于您的应用程序不拥有数据,因此您应该复制它,而不是直接操作它。
您的代码应该知道数据具有一定的大小,并且可能不会以空值结尾(或者其中可能包含空值),因此在转换为字符串时,请确保不要超出缓冲区。您可以对其进行编码以避免NULL
s 等。如果您想了解更多关于此类内容的详细信息,可能值得提出另一个问题(或搜索将任意数据编码为字符串。)最简单的做法是将数据复制到 size+ 1个缓冲区,将最后一个字节设置为null,遍历除最后一个字节之外的每个字节,对于不可打印的字符(字节值<32)将其更改为“。” 或其他一些字符。然后将指向此缓冲区的指针传递给AnsiString
的构造函数,转换为PAnsiChar
. (这可确保您的数据被视为字节大小的字符字符串 - 如果您使用 D2009+,请记住,因为本机字符串类型是 Unicode。)要使用的另一种字符串类型是RawByteString
. 一旦你有了一个字符串,就把它添加到你的备忘录中。
有一个很好的例子(在 C 中,对不起)在 MSDN 上粘贴特定格式的数据。您可以以此为起点,添加您自己的数据自定义处理。粘贴为字符串可能不是查看任意二进制数据的最佳方式 - 您可以使用十六进制编辑器组件或其他可视化工具来更好地查看数据。
梅森我不确定我是否理解你的答案,但是你可以使用 Clipboard.AsText 就像 avar 说的那样,只需将 clipbrd 添加到使用子句。请注意,如果您的字符串中某处有一个空字符,那么 KAZAM 您的字符串将从头开始粘贴到空字符#0。另一种方法是使用内存映射文件或消息在应用程序之间发送数据。
您是否尝试在 tmemo 和“另一个程序”之间使用 clipbaord.astext
我不确定您的陈述“任何类型的数据都可以表示为字符串”是否有意义。二进制数据可能嵌入了空值,这会干扰将数据视为字符串。例如,位图图像的字符串表示形式是什么值?
由应用程序设置剪贴板来确定剪贴板信息的格式。如果应用程序足够周到地提供非文本信息的文本表示(例如,图像的文件名,如果有的话),那么您可以使用该字符串信息。否则,不清楚将这些信息粘贴到 TMemo 中意味着什么。