如何将任意数据粘贴到 TMemo 中?

发布于 2024-08-11 03:33:43 字数 125 浏览 7 评论 0原文

复制和粘贴文本很容易,因为它内置于 TMemo 中,但它似乎只能处理文本。不过,在我看来,任何类型的数据都可以表示为字符串。如果我从另一个程序复制一些任意数据并希望将其粘贴到 TMemo 中,如何让 Delphi 将其接受为原始字符串?

Copying and pasting text is easy enough, since it's built into TMemo, but it seems that it can only handle text. Seems to me that any kind of data can be represented as a string, though. If I copy some arbitrary data from another program and want to paste it into a TMemo, how do I get Delphi to accept it as a raw string?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

远昼 2024-08-18 03:33:43

“如果我从另一个程序复制一些任意数据并希望将其粘贴到 TMemo 中,我如何让 Delphi 将其接受为原始字符串?”因此,为了澄清您的问题,您:

  • 想要使用任何其他应用程序(您没有代码的普通应用程序)并在其中复制一些内容
  • 想要粘贴此复制的数据(可以是包括非文本在内的任何格式)作为备忘录中的文本。

这是正确的吗?如果是这样,您不能使用 Clipboard.AsText - 仅当剪贴板上存在 CF_TEXT 格式的数据时才返回文本。您需要直接使用剪贴板 API。剪贴板保存带有格式代码的数据,您可以获得指向该数据的指针和大小,并将其视为字符串或您想要的任何方式。

所以:

您的代码应该知道数据具有一定的大小,并且可能不会以 null 终止(或者其中可能有 null),因此在转换为字符串时,请确保不会溢出缓冲区。您可以对其进行编码以避免 NULL 等。如果您想了解有关此类内容的更多详细信息,可能值得提出另一个问题(或搜索将任意数据编码为字符串)。最简单的做法是要将数据复制到 size+1 缓冲区中,请将最后一个字节设置为 null,迭代除最后一个字节之外的每个字节,对于不可打印字符(字节值 < 32)将其更改为“。”或其他一些字符。然后将指向此缓冲区的指针传递给 AnsiString 的构造函数,转换为 PAnsiChar。 (这可确保您的数据被视为字节大小的字符串 - 如果您使用的是 D2009+,则值得记住,因为本机字符串类型是 Unicode。)要使用的替代字符串类型是 RawByteString 。获得字符串后,将其添加到备忘录中。

有一个很好的例子(用C语言,抱歉) 粘贴MSDN上特定格式的数据。您可以使用它作为起点,添加您自己的数据自定义处理。作为字符串粘贴可能不是查看任意二进制数据的最佳方式 - 您可以使用十六进制编辑器组件或其他一些可视化工具来更好地查看数据。

"If I copy some arbitrary data from another program and want to paste it into a TMemo, how do I get Delphi to accept it as a raw string?" So to clarify your question, you:

  • Want to use any other application (one you don't have code for, a normal app) and copy something in it
  • Want to paste this copied data, which can be any format including non-text, as text in your memo.

Is that correct? If so, you can't use Clipboard.AsText - that only returns text if there is data with the CF_TEXT format on the clipboard. You'll need to use the clipboard APIs directly. The clipboard holds data with a format code, and you can get a pointer to that data, and a size, and treat it as a string or however you want.

So:

  • Figure out what format you want to paste. You can iterate through all formats currently on the clipboard via EnumClipboardFormats, or use one of the predefined constants (for text, images, audio, etc.) The clipboard can hold data in many formats at once, so you may want to choose which of many you use.
  • If data in this format is on the clipboard, open it. Ensure you wrap this code in a try/finally and close the clipboard in the finally clause. If you don't close the clipboard, no other application will be able to use it, so you want it to be closed even if your application crashes.
  • Call GetClipboardData to get a handle to the data in that format. Data on (or given to, if you later implement Copy) is allocated via GlobalAlloc, so you need to lock the handle to get a pointer to it via GlobalLock (and once done, unlock with GlobalUnlock.) The data's owned by the clipboard so don't free it after you've used it. To find the size of this data in bytes, use GlobalSize.
  • This gives you a pointer to data of a known size. At this point you can do anything you want with it. Treating it as a string is one option. Since your app does not own the data you should copy it, not directly manipulate it.

Your code should be aware the data is of a certain size and probably wont be null-terminated (or may have nulls in it) so when converting to a string, make sure you don't overrun the buffer. You could encode it to avoid NULLs etc. If you want more details on something like this it's probably worth asking another question (or search for encoding arbitrary data as string.) The simplest thing to do would be to copy the data into a size+1 buffer, set the last byte to null, iterate through every byte except the very last and for non-printable characters (byte value < 32) change it to "." or some other character. Then pass a pointer to this buffer to AnsiString's constructor, cast as a PAnsiChar. (This ensures your data is treated as a string of byte-size chars - worth keeping in mind if you're using D2009+ since the native string type is Unicode.) An alternative string type to use is RawByteString. Once you have a string, add it to your memo.

There is a good example (in C, sorry) of pasting data of a specific format on MSDN. You could use that as a starting point, adding in your own custom treatment of the data. Pasting as a string is probably not the best way to view arbitrary binary data - you could use a hex editor component or some other visualiser to give you a better view of the data.

寄风 2024-08-18 03:33:43

梅森我不确定我是否理解你的答案,但是是的,你可以使用 Clipboard.AsText 就像 avar 所说的那样,只需将 Clipbrd 添加到使用子句中即可。
请注意,如果字符串中某处有空字符,那么 KAZAM 将从开头粘贴字符串到空字符 #0。另一种方法是使用内存映射文件或消息在应用程序之间发送数据。

Mason I'm not sure I understand your answer, but yes you can use Clipboard.AsText like avar said just add clipbrd to uses clause.
Please note that if you have a null char somewhere in your string then KAZAM your string will be pasted from beginning till the null char #0. Another approach can be using memory mapped files or messages to send data between applications.

一枫情书 2024-08-18 03:33:43

您是否尝试过在 tmemo 和“另一个程序”之间使用 Clipbaord.astext

have you tried to use clipbaord.astext between your tmemo and "another program"

萌逼全场 2024-08-18 03:33:43

我不确定你的说法“任何类型的数据都可以表示为字符串”是否有意义。二进制数据可能嵌入了空值,这会干扰将数据视为字符串。例如,位图图像的字符串表示有什么价值?

由设置剪贴板的应用程序来确定剪贴板信息的格式。如果应用程序足够周到,可以提供非文本信息的文本表示(例如图像的文件名,如果有),那么您可以使用该字符串信息。否则,不清楚将该信息粘贴到 TMemo 中意味着什么。

I'm not sure that your statement "any kind of data can be represented as a string" is meaningful. Binary data may have embedded nulls, which would interfere with treating the data as a string. And of what value is a string representation of, for instance, a bitmap image?

It's up to the application that sets the clipboard to determine the format for the clipboard information. If the application is thoughtful enough to provide a text representation of non-text information (for instance, the filename for an image, if any) then you can use that string information. Otherwise, it's not clear what pasting that information into a TMemo would even mean.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文