Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c# - Copy binary data to clipboard

How can I copy binary data in the clipboard? For example if I pack the number 1 as a 4-byte little-endian integer I want my clipboard to show 00 00 00 01

For text data this is trivial, with the option of having unicode text or ascii text.

Clipboard.SetData(DataFormats.Text, "Some text");
Clipboard.SetData(DataFormats.UnicodeText, "赤");

However for binary data I don't know what to do.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are actually two ways to do this:

First one, and by far the simplest one: you simply put the byte array into the clipboard. This will automatically serialize the byte array, and deserialize it on retrieve, and all you need to do is check for typeof(Byte[]). In fact, this works for any serializable type (and you can make your own classes serializable with the [Serializable] attribute).

Put on clipboard:

public void PutBytesOnClipboardObj(Byte[] byteArr)
{
    DataObject data = new DataObject();
    // Can technically just be written as "SetData(byteArr)", but this is more clear.
    data.SetData(typeof(Byte[]), byteArr);
    // The 'copy=true' argument means the data will remain available
    // after the program is closed.
    Clipboard.SetDataObject(data, true);
}

Retrieve from clipboard:

public byte[] GetBytesFromClipboardObj()
{
    DataObject retrievedData = Clipboard.GetDataObject() as DataObject;
    if (retrievedData == null || !retrievedData.GetDataPresent(typeof(Byte[])))
        return null;
    return retrievedData.GetData(typeof(Byte[])) as Byte[];
}

If you absolutely want it to be on there as pure raw bytes, another possibility is to put it on the clipboard as MemoryStream. There is no specific type for this in the DataFormats list, but since the listed data formats are just strings, you can just make up your own. I used "rawbinary" in the following example.

Put on clipboard:

public void PutBytesOnClipboardRaw(Byte[] byteArr)
{
    DataObject data = new DataObject();
    using (MemoryStream memStream = new MemoryStream())
    {
        memStream.Write(byteArr, 0, byteArr.Length);
        data.SetData("rawbinary", false, memStream);
        // The 'copy=true' argument means the MemoryStream
        // can be safely disposed after the operation.
        Clipboard.SetDataObject(data, true);
    }
}

Retrieve from clipboard:

public Byte[] GetBytesFromClipboardRaw()
{
    DataObject retrievedData = Clipboard.GetDataObject() as DataObject;
    if (retrievedData == null || !retrievedData.GetDataPresent("rawbinary", false))
        return null;
    MemoryStream byteStream = retrievedData.GetData("rawbinary", false) as MemoryStream;
    if (byteStream == null)
        return null;
    return byteStream.ToArray();
}

This second type is often used for custom formats; for example, the Office clipboard puts images into the clipboard as PNG byte stream (with identifier "PNG") because the standard clipboard image type lacks transparency support.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...