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?
have you tried to use clipbaord.astext between your tmemo and "another program"
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.
"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 thefinally
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 viaGlobalAlloc
, so you need to lock the handle to get a pointer to it viaGlobalLock
(and once done, unlock withGlobalUnlock
.) 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, useGlobalSize
. - 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 NULL
s 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.
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.