Рассмотрим достаточно интересную и нетривиальную задачу: как программно поместить графическое изображение в буфер обмена операционной системы из платформы 1С:Предприятие. Очень часто в интернете можно встретить инструкции по получению картинок из буфера, а вот обратная операция вызывает множество вопросов. Проанализируем типичные ошибки разработчиков, разберем по шагам, почему некоторые популярные подходы не работают, и посмотрим на рабочие варианты решения этой проблемы.
Многие разработчики, столкнувшись с задачей работы с буфером обмена, вспоминают про объект htmlfile. Для текста этот подход работает отлично. Посмотрим на пример кода, который часто пытаются использовать для работы с буфером:
Функция УстановитьТекстВБуферОбмена(Текст) Экспорт
#Если Клиент Тогда
Объект = Новый COMОбъект("htmlfile");
Объект.ParentWindow.ClipboardData.Setdata("Text", Текст);
Возврат Текст;
#КонецЕсли
КонецФункции
Возникает логичная мысль: а что, если перевести картинку в Base64 или прочитать ее как бинарные данные и передать в этот же объект? Разберем пример такой попытки с использованием ADODB.Stream:
Объект = Новый COMОбъект("htmlfile");
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Open();
ДвоичныеДанные.Записать(ИмяВременногоФайла);
Поток.LoadFromFile(ИмяВременногоФайла);
Значение = Поток.ReadText();
Объект.ParentWindow.ClipboardData.Setdata("text", Значение);
Выясним причину неудачи: данный код отработает без ошибок в 1С, но если вы откроете графический редактор (например, Paint) и попытаетесь вставить картинку, ничего не произойдет. Почему так происходит? Операционная система Windows строго разделяет форматы данных в буфере обмена. Если мы помещаем данные с указанием формата Text, система ставит на этот блок памяти флаг текстового формата. Внешняя программа (тот же Paint) обращается к буферу, ищет флаги графики (например, CF_BITMAP) и, не находя их, считает буфер пустым. Метод SetData объекта htmlfile сильно ограничен и предназначен только для строк.
Если нет возможности использовать современные платформы, а результат нужен "здесь и сейчас", можно прибегнуть к рабочему костылю, к которому в итоге приходят многие разработчики — использованию MS Word. Создавая невидимый экземпляр Word.Application, можно вставить картинку в документ, а затем скопировать ее встроенными средствами Word в системный буфер. Этот метод рабочий, но требует обязательного наличия установленного пакета MS Office на компьютере пользователя, что подходит не для всех ситуаций.
Разберем подробнее самое правильное и современное решение. Начиная с версии 1С:Предприятие 8.3.24, разработчики платформы добавили встроенную поддержку записи в буфер обмена через глобальный менеджер СредстваБуфераОбмена.
Теперь для помещения картинки в буфер не нужны внешние компоненты. Проанализируем порядок действий:
ЭлементБуфераОбмена.СтандартныйФорматДанныхБуфераОбмена.Картинка.СредстваБуфераОбмена.ПоместитьДанныеАсинх().Важный нюанс: в ранних релизах этого механизма замечена особенность — картинки корректно вставляются в Paint, Telegram, браузеры, но могут не распознаваться некоторыми приложениями MS Office (Outlook, Word) из-за специфики формирования заголовков DIB. Тем не менее, это самый надежный нативный способ.
Если конфигурация работает на старой платформе, а использовать Word нельзя по условиям задачи, рассмотрим отличную альтернативу — вызов системных API Windows через скрипт PowerShell. Этот метод работает быстро и не требует установки сторонних библиотек.
Алгоритм работы выглядит так:
COMОбъект("WScript.Shell") формируем и запускаем PowerShell-скрипт.System.Windows.Forms.[System.Drawing.Image]::FromFile.[System.Windows.Forms.Clipboard]::SetImage().Этот метод гарантированно помещает картинку в нужном графическом формате, и она распознается любыми редакторами и мессенджерами.
Для высоконагруженных систем или специфических задач можно использовать внешние компоненты. В сообществе 1С существует множество готовых DLL-библиотек (написанных на C++ или C#). Они подключаются к платформе через технологию NativeAPI и обращаются напрямую к системным функциям ОС (OpenClipboard, SetClipboardData).
Использование внешней компоненты — это самый мощный инструмент, так как он позволяет передавать в буфер обмена графику в строгих системных форматах (CF_BITMAP или CF_DIB). Картинки, помещенные таким образом, будут со 100% вероятностью читаться абсолютно в любом приложении Windows.
Подводя итоги: мы проанализировали различные варианты. Если вы работаете на свежей версии платформы 1С — смело используйте объект СредстваБуфераОбмена. Если версия платформы старая и установка MS Office не проблема — подойдет Word.Application. В остальных случаях вас выручит простой вызов PowerShell.