Разработчики, работающие с платформой 1С:Предприятие 7.7, часто сталкиваются с аппаратными и программными ограничениями интерфейса. Одной из таких проблем является интерактивность элементов управления. Например, стандартный элемент формы Картинка имеет только идентификатор, но не предоставляет штатного события для обработки клика мыши. В этой статье мы подробно разберем, как решить эту задачу различными способами: от простых штатных обходных путей до продвинутых решений с использованием внешних компонент и ActiveX.
Это наиболее популярный, надежный и полностью штатный способ имитации клика по изображению без использования сторонних библиотек. Суть метода заключается в наложении невидимого текстового поля на элемент картинки.
Рассмотрим по шагам процесс реализации этого метода:
КартинкаТовара.ОткрытьИзображение().КартинкаТовара. Только в этом случае клик мыши будет перехватываться текстовым полем, а не уходить «в пустоту» картинки.Теперь напишем обработчик в модуле формы. Обратите внимание, что формула элемента формы требует вызова именно функции, а не процедуры:
Функция ОткрытьИзображение()
// Здесь мы прописываем логику, выполняемую при клике на картинку
ИмяФайла = ПолучитьПутьКФайлу();
Если ФС.СуществуетФайл(ИмяФайла) = 1 Тогда
ЗапуститьПриложение(ИмяФайла);
Иначе
Предупреждение("Файл изображения не найден!");
EndIf;
Возврат ""; // Возвращаем пустое значение для корректной работы формулы
КонецФункции
Если вам не требуется отображать сложное динамическое фото большого размера, а картинка выполняет роль интерактивной иконки или кнопки, мы можем использовать штатный элемент управления Кнопка.
Выполним следующие действия:
Этот метод прост, однако имеет существенный недостаток: кнопка сохраняет свои стандартные трехмерные рамки Windows, что не всегда вписывается в современный плоский дизайн интерфейсов.
Рассмотрим комплексное практическое решение, которое реализовал автор темы для организации хранения картинок номенклатуры в локальной папке информационной базы и их интерактивного просмотра.
Для начала проанализируем функции, которые необходимо разместить в Глобальном модуле конфигурации для обеспечения централизованного формирования путей к файлам:
// Функция нормализует артикул, удаляя запрещенные символы файловой системы
Функция НормализоватьАртикул(Арт) Экспорт
Рез = СокрЛП(Арт);
Рез = СтрЗаменить(Рез, "\", "_");
Рез = СтрЗаменить(Рез, "/", "_");
Возврат Рез;
КонецФункции
// Функция возвращает полный физический путь к файлу картинки на диске
Функция ВернутьИмяФайлаКартинки(Код, Артикул) Экспорт
ИмяФайлаКартинки = КаталогИБ() + СокрЛП(Константа.КаталогКартинок) + "\" + СокрЛП(Код) + "_" + НормализоватьАртикул(Артикул) + ".jpg";
Возврат ИмяФайлаКартинки;
КонецФункции
Теперь разберем код, размещаемый непосредственно в модуле формы справочника номенклатуры. Мы создадим процедуры для загрузки изображения на форму, добавления нового файла, удаления картинки и ее открытия во внешнем просмотрщике операционной системы Windows:
// Процедура загружает картинку из файла для показа на форме справочника
Процедура ЗагрузитьКартинку()
ИмяФайлаКартинки = ВернутьИмяФайлаКартинки(Код, Артикул);
Если ФС.СуществуетФайл(ИмяФайлаКартинки) = 1 Тогда
Картинка.Загрузить(ИмяФайлаКартинки);
Иначе
// Если файла нет, очищаем поле картинки пустым объектом
ПустКартинка = СоздатьОбъект("Картинка");
Картинка.УстановитьКартинку(ПустКартинка);
КонецЕсли;
КонецПроцедуры
// Процедура интерактивного удаления файла картинки с диска
Процедура УдалитьКартинку()
Если Вопрос("Вы уверены, что хотите удалить картинку?", 4, 10) = 6 Тогда
ИмяФайлаКартинки = ВернутьИмяФайлаКартинки(Код, Артикул);
Если ФС.СуществуетФайл(ИмяФайлаКартинки) = 1 Тогда
ФС.УдалитьФайл(ИмяФайлаКартинки);
КонецЕсли;
ПустКартинка = СоздатьОбъект("Картинка");
Картинка.УстановитьКартинку(ПустКартинка);
Форма.Обновить(0);
КонецЕсли;
КонецПроцедуры
// Процедура выбора нового файла изображения и копирования его в базу
Процедура ЗагрузитьКартинкуВБазу()
ИмяФайлаКартинки = ВернутьИмяФайлаКартинки(Код, Артикул);
Если ФС.СуществуетФайл(ИмяФайлаКартинки) = 1 Тогда
Если Вопрос("Вы уверены, что хотите заменить существующую картинку?", 4, 10) <> 6 Тогда
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецЕсли;
НоваяКартинка = "";
КатЗагрКартинки = "";
Если ФС.ВыбратьФайлКартинки(0, НоваяКартинка, КатЗагрКартинки, "Выберите файл картинки для текущего товара!", "jpg", 10) = 1 Тогда
ФС.КопироватьФайл(КатЗагрКартинки + НоваяКартинка, ИмяФайлаКартинки, 0);
Картинка.Загрузить(ИмяФайлаКартинки);
КонецЕсли;
КонецПроцедуры
// Процедура запуска внешнего приложения для детального просмотра картинки
Процедура ПросмотрКартинки()
ИмяФайлаКартинки = ВернутьИмяФайлаКартинки(Код, Артикул);
Если ФС.СуществуетФайл(ИмяФайлаКартинки) = 1 Тогда
ЗапуститьПриложение(ИмяФайлаКартинки);
Иначе
Предупреждение("Файл изображения отсутствует!");
КонецЕсли;
КонецПроцедуры
Для интеграции этого решения мы можем разместить рядом с полем картинки небольшую стандартную кнопку с буквой "О" (Открыть) или воспользоваться Методом 1 (наложить прозрачный текст поверх элемента Картинка), привязав к нему вызов функции, которая внутри себя вызывает процедуру ПросмотрКартинки().
Внешняя компонента FormEx расширяет возможности работы с интерфейсом 1С 7.7. С её помощью можно напрямую перехватывать события мыши, происходящие над элементами формы, без создания «костылей» в виде прозрачных полей.
Для реализации этого подхода выполним следующие шаги:
FormEx.dll при запуске системы (например, в процедуре ПриНачалеРаботыСистемы Глобального модуля) с помощью команды ЗагрузитьВнешнююКомпоненту("FormEx.dll").ПриНажатииМыши или ПослеНажатияМыши, которая автоматически вызывается компонентой FormEx при любом клике на форме.Посмотрим на пример реализации кода обработки события клика:
Процедура ПриНажатииМыши(Контекст, Идентификатор, Флаг)
// Проверяем, что клик совершен именно левой кнопкой мыши по элементу КартинкаТовара
Если Идентификатор = "КартинкаТовара" Тогда
// Вызываем процедуру открытия полноразмерного файла
ПросмотрКартинки();
КонецЕсли;
КонецПроцедуры
Дополнительным преимуществом использования FormEx является возможность динамического изменения курсора мыши. При наведении на картинку мы можем превратить стандартный курсор в «указатель» (руку), что сразу даст пользователю визуальный сигнал о том, что картинка кликабельна.
Если штатный элемент Картинка вас не устраивает по функционалу, мы можем заменить его на полноценный объект ActiveX. В качестве контейнера отлично подойдет стандартный элемент Microsoft Forms 2.0 Image.
Алгоритм настройки выглядит следующим образом:
Microsoft Forms 2.0 Image.АктКартинка.Пример кода настройки и загрузки изображения в элемент ActiveX при открытии формы:
Процедура ПриОткрытии()
// Загружаем картинку в объект ActiveX программно
ИмяФайла = ВернутьИмяФайлаКартинки(Код, Артикул);
Если ФС.СуществуетФайл(ИмяФайла) = 1 Тогда
Форма.АктКартинка.Picture = LoadPicture(ИмяФайла);
КонецЕсли;
КонецПроцедуры
Поскольку событие клика по ActiveX обрабатывается платформой напрямую, мы можем прописать обработчик событий элемента формы, связав его с запуском нашего кода.
Для разработчиков, стремящихся к максимальной гибкости визуального отображения (например, к автоматическому масштабированию, поддержке анимаций GIF, CSS-стилям границ), отлично подойдет использование ActiveX-объекта Shell.Explorer (встроенного браузера Internet Explorer).
Схема реализации выглядит следующим образом:
Shell.Explorer на форме 1С и назовем его БраузерКартинки.Разберем пример реализации этого продвинутого метода:
Процедура ПриОткрытии()
// Инициализируем браузер и загружаем пустую страницу
Форма.БраузерКартинки.Navigate("about:blank");
// Формируем HTML-код с картинкой
ПутьКФайлу = ВернутьИмяФайлаКартинки(Код, Артикул);
HTMLКод = "<html><body style='margin:0;padding:0;overflow:hidden;'>
|<a href='run1c:open_image'>
|<img src='file://" + ПутьКФайлу + "' style='width:100%;height:100%;object-fit:contain;' />
|</a>
|</body></html>";
// Записываем сформированный код в документ браузера
Форма.БраузерКартинки.Document.write(HTMLКод);
КонецПроцедуры
Теперь нам остается только перехватить событие перехода по ссылке run1c:open_image в модуле формы 1С 7.7:
Процедура ПередНавигатором(Браузер, URL, Флаги, ЦелевойКадр, ДанныеПост, Заголовки, Отмена)
// Если пользователь нажал на картинку-ссылку
Если Найти(ВРег(URL), "RUN1C:OPEN_IMAGE") > 0 Тогда
// Отменяем стандартный переход браузера по ссылке
Отмена = 1;
// Выполняем нашу процедуру обработки
ПросмотрКартинки();
КонецЕсли;
КонецПроцедуры
Этот способ предоставляет невероятную свободу действий: вы можете делать плавные затухания, добавлять кнопки поверх картинки средствами HTML/CSS, отображать любые форматы файлов (включая PNG с прозрачностью, что стандартно не поддерживается платформой 1С 7.7) и легко масштабировать изображение под размеры окна формы.