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:

Update

Although basically works, I have made a few mistakes in this code, see: Setting HTML/Text to Clipboard revisited for better clipboard handling.

Code (deprecated)

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

5 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

  4. […] getting feedback that my original clipboard code doesn’t handle all scenarios, especially with Chrome, I went back to the code to get a […]

  5. […] Copy selected rich html text . […]

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