Setting HTML and plain text formatting to clipboard

Working on adding text selection and copy-paste to HTML Renderer I wanted to add rich text copy capability.

My first thought was to use Clipboard.SetText method with TextDataFormat.Html but to my surprise it just didn’t work. Turning to Google I finally found this post, harder to find than what I expected, that explained what needs to be done.

Apparently when setting html text you need to provide a header with additional information to what fragment of the html you actually want to paste while being able to provide additional styling around it:

Version:1.0
StartHTML:000125
EndHTML:000260
StartFragment:000209
EndFragment:000222
<HTML>
<head>
<title>HTML clipboard</title>
</head>
<body>
<!–StartFragment–><b>Hello!</b><!–EndFragment–>
</body>
</html>

Worked like a charm to paste rich html text!

But then when I tried to paste to non rich editor like Notepad I got nothing, it actually what I excepted.

To handle html and plain text paste you can’t use Clipboard.SetText method as it clears the clipboard each time called,  you need to create DataObject instance, call its SetData method once with html format and once with text format, and then set the object to clipboard using Clipboard.SetDataObject.

The complete code I come up with based on Mike’s code:

public static void CopyToClipboard(string html, string plainText)
{
    var data = GetHtmlData(html);

    var dataObject = new DataObject();
    dataObject.SetData(DataFormats.Html, data);
    dataObject.SetData(DataFormats.Text, plainText);

    Clipboard.SetDataObject(dataObject);
}
private static string GetHtmlData(string html)
{
    var sb = new StringBuilder();

    const string header = @"Format:HTML Format
Version:1.0
StartHTML:<<<<<<<1
EndHTML:<<<<<<<2
StartFragment:<<<<<<<3
EndFragment:<<<<<<<4
StartSelection:<<<<<<<3
EndSelection:<<<<<<<3";

    sb.Append(header);
    int startHtml = sb.Length;

    sb.Append(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN""><!--StartFragment-->");
    int fragmentStart = sb.Length;

    sb.Append(html);
    int fragmentEnd = sb.Length;

    sb.Append(@"<!--EndFragment-->");
    int endHtml = sb.Length;

    // Backpatch offsets

	sb.Replace("<<<<<<<1", String.Format("{0,8}", startHtml));
    sb.Replace("<<<<<<<2", String.Format("{0,8}", endHtml));
    sb.Replace("<<<<<<<3", String.Format("{0,8}", fragmentStart));
    sb.Replace("<<<<<<<4", String.Format("{0,8}", fragmentEnd));

    return sb.ToString();
}
About these ads

3 comments on “Setting HTML and plain text formatting to clipboard

  1. [...] Copy selected rich html text. [...]

  2. gby85 says:

    This works very well! Thanks for your CopyToClipboard method!

  3. krishnakant says:

    nice post solve my problem perfectly

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s