Copy composite of multiple objects to clipboard (c# winforms)

470 Views Asked by At

C# Winforms app, Windows 10.

Form has a richtextbox and a chart (both MS). Currently have a function to copy richtextbox to clipboard:

    Clipboard.SetText(rtbContents.Rtf, TextDataFormat.Rtf);

and a function to copy chart to clipboard as an image:

    using (MemoryStream ms = new MemoryStream())
    {
        chart1.SaveImage(ms, ChartImageFormat.Bmp);
        Bitmap bm = new Bitmap(ms);
        Clipboard.SetImage(bm);
    }

Need a function to copy both as a unit (rich text on top with image beneath), so that ctrl-v will paste them both into, for example, a Word document.

Tried IDataObject, trouble storing rich text in object without losing colors, font sizes, special characters. Also looks like IDataObject can still only paste one thing at a time, just senses which thing the target application most likely wants.

Tried combining bmp's using DrawString, trouble preserving multiple colors in rich text, and assembling or concatenating bitmaps.

Tried CopyFromScreen, trouble with location using multiple monitors and determining actual location (this.Location.X relative to container, not screen), and doesn't exactly meet spec because if richtextbox is hidden or floating, won't show it at top. Not to mention that if you try to debug it, it copies a chunk of Visual Studio's display instead.

Open source third party solutions might be ok, looked for some but didn't see anything that could do this function. Win32 API calls would be a last resort.

Thanks in advance for any assistance.

1

There are 1 best solutions below

0
On BEST ANSWER

Solution is to use clipboard as an intermediate step. Hacky but works.

    using (MemoryStream ms = new MemoryStream())
    {
        chart1.SaveImage(ms, ChartImageFormat.Bmp);
        Bitmap bm = new Bitmap(ms);
        Clipboard.SetImage(bm);
    }
    RichTextBox rtbCombination = new RichTextBox();
    rtbCombination.Rtf = ucLegend.rtbContents.Rtf;
    rtbCombination.Select(rtbCombination.Rtf.Length, 0);
    rtbCombination.AppendText(Environment.NewLine);
    rtbCombination.Select(rtbCombination.Rtf.Length, 0);
    rtbCombination.Paste();
    Clipboard.SetText(rtbCombination.Rtf, TextDataFormat.Rtf);