4

I'm trying to copy some HTML text into the clipboard and be able to paste it.

An example:

var text = @"<html>
<a href=""#"">Click me!</a><br/>
</html>";

Clipboard.SetText(text, TextDataFormat.Html);

When I try this, clipboard becomes empty, I cannot paste anything to a text document or anywhere. Ofcourse I can get the text by doing:

var text = Clipboard.GetText(TextDataFormat.Html);

But that's not what I want. The behaviour I want is copying an HTML text from the browser and pasting it on a Word document for example, the format must be preserved. If I don't use any text format or use TextDataFormat.Text it pastes the text without formatting.

Is there any way to achieve this?

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • The Clipboard class can only be used in threads set to single thread apartment (STA) mode. To use this class, ensure that your Main method is marked with the STAThreadAttribute attribute. https://msdn.microsoft.com/en-us/library/tbfb3z56(v=vs.110).aspx – Dipen Shah Aug 08 '18 at 15:16
  • 1
    @DipenShah the thread is STA, otherwise it would throw an exception as mentioned in the documentation you shared. there is no exception thrown. – Selman Genç Aug 08 '18 at 15:17
  • May be this will help https://stackoverflow.com/questions/45286635/clipboard-settexthtml-no-longer-work – Dipen Shah Aug 08 '18 at 15:22
  • Where is `Clipboard.GetText(text, TextDataFormat.Html);` defined? Did you mean `var text = Clipboard.GetText(TextDataFormat.Html);`? –  Aug 08 '18 at 15:39
  • @MickyD yes I meant `Clipboard.GetText(TextDataFormat.Html);` – Selman Genç Aug 08 '18 at 15:43
  • Where are you trying to paste that? – Alejandro Aug 08 '18 at 15:47
  • @RufusL I'm losing everything, after `Clipboard.SetText(text, TextDataFormat.Html);` I can't paste anything with CTRL + V – Selman Genç Aug 08 '18 at 15:47
  • @Alejandro tried to paste to notepad and google docs. same result – Selman Genç Aug 08 '18 at 15:47
  • @SelmanGenç Oh, right. I mean what do you lose if you don't include `TextDataFormat.Html` (where you say, *"If I don't use any text format or use TextDataFormat.Text it pastes the text without formatting."*)? – Rufus L Aug 08 '18 at 15:47
  • @RufusL there is no formatting, it just pastes the text as raw HTML. I want the same behaviour as if I copied the text from browser and pasted it to a word document – Selman Genç Aug 08 '18 at 15:49
  • @SelmanGenç Notepad doesn't knows anything about HTML format, you must provide **both** html and plain text. Programs that understand html will use that, but almost anything can get the plain text. Word probably only uses rtf and not html. Ideally, provide the clipboard data in as many formats as you can. – Alejandro Aug 08 '18 at 15:49
  • @Alejandro RTF seems to work for Word but still the text is pasted as raw HTML, e.g: the link is not formatted with blue underlined text. – Selman Genç Aug 08 '18 at 15:52

1 Answers1

7

The HTML data format doesn't mean the payload is plain HTML. The structure of the content is described in the docs, in HTML Clipboard Format. The Version, StartHTML and EndHTML elements are mandatory.

The following code will put an HTML snippet in the Clipboard that can be pasted in applications that understand the HTML format, like Word :

var text = @"Version:0.9
StartHTML:0000000055
EndHTML:0000000088
<a href='#'>Click me!</a><br/>";

System.Windows.Forms.Clipboard.SetText(text,TextDataFormat.Html);

Without those elements the text isn't recognized as an HTML payload and can't be pasted.

The HTML format can contain more than the snippet. If someone copies text from a browser, the HTML payload may end up containing styles, fonts and indexes that aren't part of the actual snippet but are necessary to allow correct rendering. This question's title looks like this when copied:

Version:0.9
StartHTML:0000000224
EndHTML:0000001613
StartFragment:0000000260
EndFragment:0000001577
SourceURL:https://stackoverflow.com/questions/51750187/why-i-cannot-paste-formatted-text-copied-to-clipboard#51750187
<html>
<body>
<!--StartFragment--><h1 itemprop="name" class="grid--cell fs-headline1 fl1" style="margin: 0px 0px 0.5em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: inherit; font-stretch: inherit; line-height: 1.3; font-family: Arial, &quot;Helvetica Neue&quot;, Helvetica, sans-serif; font-size: 2.07692rem !important; vertical-align: baseline; box-sizing: inherit; flex: 1 1 auto !important; color: rgb(36, 39, 41); letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"><a href="https://stackoverflow.com/questions/51750187/why-i-cannot-paste-formatted-text-copied-to-clipboard" class="question-hyperlink" style="margin: 0px 0px 0.5em; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: normal; font-stretch: inherit; line-height: 1.35; font-family: inherit; font-size: 24px; vertical-align: baseline; box-sizing: inherit; color: rgb(36, 39, 41); text-decoration: none; cursor: pointer;">Why I cannot paste formatted text copied to clipboard?</a></h1><!--EndFragment-->
</body>
</html>00

The code that returned the HTML content is :

var obj=System.Windows.Forms.Clipboard.GetDataObject();
var html=obj.GetData("HTML Format");
Console.WriteLine(html);

The browser adds the data using multiple formats. The following line

Console.WriteLine(obj.GetFormats());

Returned 6 different formats :

  • HTML Format
  • System.String
  • UnicodeText
  • Text
  • Locale
  • OEMText

The reason for all this is that the clipboard is used to transfer data between applications that DON'T use or understand the same formats. The source application adds data to the clipboard in the formats it understands. It's the source's responsibility to put as much data in the clipboard as possible to ensure the content can be reproduced on the other end.

Target applications request the clipboard data in the format they understand. The clipboard can try and convert from one format to another. When that's not possible, it will return NULL.

Multiple Formats

To support multiple targets, an application can create one DataObject that contains multiple formats. The following code adds an HTML payload that can be pasted into Word and a Text payload that can be pasted into any text editor:

var html = @"Version:0.9
StartHTML:0000000055
EndHTML:0000000088
<a href='#'>Click me!</a><br/>";

var plainText=@"<a href='#'>Click me!</a><br/>";

var obj=new DataObject();
obj.SetText(html,TextDataFormat.Html);
obj.SetText(plainText,TextDataFormat.Text);

Clipboard.SetDataObject(obj);
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • Thanks! this works for Word but not for google docs, but I get the point, I will need to play with `obj.GetData("HTML Format");` to find out exact format and make it work. – Selman Genç Aug 08 '18 at 18:36