Скопировать композит из нескольких объектов в буфер обмена (C# winforms)
Приложение C# Winforms, Windows 10.
Форма имеет richtextbox и диаграмму (оба MS). В настоящее время есть функция для копирования richtextbox в буфер обмена:
Clipboard.SetText(rtbContents.Rtf, TextDataFormat.Rtf);
и функция для копирования диаграммы в буфер обмена в виде изображения:
using (MemoryStream ms = new MemoryStream())
{
chart1.SaveImage(ms, ChartImageFormat.Bmp);
Bitmap bm = new Bitmap(ms);
Clipboard.SetImage(bm);
}
Нужна функция, чтобы скопировать оба как единое целое (форматированный текст сверху с изображением внизу), чтобы ctrl-v вставлял их обоих, например, в документ Word.
Пробовал IDataObject, проблема с сохранением форматированного текста в объекте без потери цветов, размеров шрифта, специальных символов. Кроме того, похоже, что IDataObject все еще может вставлять только одну вещь за раз, просто определяет, что именно хочет целевое приложение.
Попытка объединения bmp с использованием DrawString, проблемы с сохранением нескольких цветов в форматированном тексте и сборка или объединение растровых изображений.
Пробовал CopyFromScreen, проблема с местоположением с использованием нескольких мониторов и определением фактического местоположения (this.Location.X относительно контейнера, а не экрана), и не совсем соответствует спецификации, потому что если richtextbox скрыт или плавающий, он не будет отображаться сверху. Не говоря уже о том, что если вы попытаетесь отладить его, он скопирует фрагмент дисплея Visual Studio.
Могут быть в порядке сторонние решения с открытым исходным кодом, искали некоторые, но не видели ничего, что могло бы выполнить эту функцию. Вызовы Win32 API были бы последним средством.
Спасибо заранее за любую помощь.
1 ответ
Решение заключается в использовании буфера обмена в качестве промежуточного шага. Хаки но работает.
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);