Когда мы разрабатываем сложные интерфейсы в 1С:Предприятие 7.7, часто возникает необходимость в динамическом создании элементов управления, таких как кнопки на тулбаре. Для этих целей программисты активно используют внешние компоненты, например, класс DWX.ToolBar. Он позволяет расширить стандартные возможности формы и создать кастомную панель инструментов. Однако при переносе обработки из внешней формы в конфигурацию мы можем столкнуться с неочевидной проблемой: кнопки отрисовываются и нажимаются, но соответствующая процедура обработки нажатия не вызывается.
В этой статье мы подробно разберем, почему возникает такая ситуация, как ее диагностировать и какие шаги предпринять для устранения неисправности, опираясь на опыт решения аналогичной задачи.
Рассмотрим ситуацию, когда мы используем класс DWX.ToolBar для создания дополнительных кнопок на тулбаре нашей обработки. Внешние компоненты типа DWX.ToolBar используют механизм динамического вызова методов, например, через объект Wrap, который ищет процедуру-обработчик в контексте формы. Обычно это выглядит так: num = Wrap.FindMethod("ButtonClick"). Если все работает корректно, этот метод возвращает индекс найденной процедуры, и далее происходит ее вызов.
Однако, когда наша обработка, содержащая динамические кнопки, помещается непосредственно в конфигурацию, мы можем заметить, что Wrap.FindMethod("ButtonClick") начинает возвращать значение -1. Это критично, поскольку -1 означает, что процедура "ButtonClick" не была найдена, и, соответственно, дальнейший вызов обработчика не происходит. Нажатия на кнопки тулбара становятся "холостыми" — визуальный эффект есть, но логика не срабатывает.
Для наглядности, посмотрим на базовый пример кода, который демонстрирует инициализацию тулбара и процедуру обработки нажатия:
Перем ТулБар;
// Процедура обработки нажатия кнопки
Процедура ButtonClick(actID)
Сообщить("ОбработкаНажатияКнопки, actID = " + СокрЛП(actID));
КонецПроцедуры
// Процедура для добавления кнопок на тулбар
Процедура Добавить()
ТулБар.ЗагрузитьКартинкуИзРесурса(1037);
// Ид кнопки должен быть в диапазоне 65536 - 66000
ТулБар.ДобавитьКнопку(65563 + 49, 49,"Ввод новой строки","Новая строка (Insert)");
ТулБар.ДобавитьКнопку(65563 + 50, 50,"Изменить (открыть) строку","Изменить (открыть) (Shift+Enter)");
ТулБар.ДобавитьКнопку(65563 + 69, 69,"Открыть объект для просмотра","Просмотр");
ТулБар.ДобавитьКнопку(65563 + 51, 51,"Ввести новую строку скопировав текущую","Копировать строку (F9)");
ТулБар.ДобавитьКнопку(65563 + 57, 57,"Ввести документ использую текущий как основание","Ввести на основании (Alt+F9)");
ТулБар.ДобавитьКнопку(65563 + 52, 52,"Пометить на удаление","Пометить на удаление");
ТулБар.ДобавитьКнопку(65563 + 58, 58,"Установить интервал просмотра документов","Интервал");
ТулБар.ЗагрузитьКартинкуИзРесурса(128);
ТулБар.ДобавитьКнопку(65600, 49 + 49 + 6,"Печать реестра документов по текущему отбору","Печать реестра");
КонецПроцедуры
// Процедура, выполняемая после открытия формы
Процедура ПослеОткрытия()
ТулБар = СоздатьОбъект("DWX.ToolBar");
ТулБар.УстановитьКонтекстФорму(Контекст, Форма);
Добавить();
ТулБар.УдалитьКнопку(0, 4); // Пример удаления кнопки
Форма.Обновить();
КонецПроцедуры
В этом коде процедура ButtonClick(actID) должна была бы вызывать сообщение при каждом нажатии на добавленную кнопку. Однако, как мы видим, этого не происходит.
Одной из наиболее частых причин подобных "необъяснимых" проблем в 1С 7.7 является конфликт между различными внешними компонентами (DLL-библиотеками), загруженными в систему. В нашем случае, выяснилось, что проблема заключалась в конфликте между компонентой turbomd.dll и dynwrapx.dll. Класс DWX.ToolBar использует dynwrapx.dll для своей работы, в частности, для динамического вызова методов формы. Компонента turbomd.dll, в свою очередь, также является широко используемой внешней компонентой для 1С 7.7, предоставляющей различные доработки платформы. При одновременной загрузке этих двух компонент (особенно если turbomd.dll загружается первой или является устаревшей), turbomd.dll могла перехватывать или некорректно обрабатывать системные вызовы, необходимые для правильной работы dynwrapx.dll, что приводило к невозможности найти процедуру ButtonClick.
Диагностировать такой конфликт бывает непросто. Один из эффективных способов — это пошаговое отключение или комментирование строк загрузки внешних компонент в глобальном модуле или процедурах инициализации. В данном случае, проблема была выявлена именно таким образом: комментирование строки загрузки turbomd.dll приводило к тому, что обработка нажатий кнопок DWX.ToolBar начинала работать корректно.
После выявления конфликта с turbomd.dll, первым шагом к решению является ее обновление. Важно понимать, что не все версии turbomd.dll одинаково полезны или совместимы. Некоторые старые версии, даже если они были доступны на популярных ресурсах, могли содержать ошибки или несовместимости с другими компонентами.
Разберем шаги по обновлению:
turbomd.dll. Следует искать проверенные источники и самые свежие сборки компоненты. Иногда на форумах 1С++ пользователи делятся наиболее стабильными и совместимыми версиями.turbomd.dll в каталоге bin вашей установки 1С:Предприятие 7.7. Рекомендуется предварительно сделать резервную копию заменяемого файла.regsvr32 C:\Путь\К\1С\bin\turbomd.dll (укажите ваш актуальный путь). Это гарантирует, что система корректно зарегистрирует новую версию компоненты.В нашем случае, использование определенной, более новой версии turbomd.dll, найденной на форумах 1С++, решило проблему с обработкой нажатий кнопок DWX.ToolBar. Это подтверждает, что разработчики turbomd.dll устранили внутренние несовместимости в более поздних версиях.
После решения основной проблемы с turbomd.dll, мы можем столкнуться с новой, но также связанной с внешними компонентами: аварийным завершением работы 1С при закрытии обработки. Если в глобальном модуле или в других частях кода у вас загружается компонента vkloader.dll (например, с помощью ЗагрузитьВнешнююКомпоненту("vkloader.dll")), то она может стать причиной сбоев.
В логах ошибок Windows (Журнал событий) или при краше 1С вы можете увидеть сообщение, указывающее на vkloader.dll_unloaded как на модуль, вызвавший проблему. Это означает, что при выгрузке vkloader.dll происходит ошибка, приводящая к падению приложения.
Если компонента vkloader.dll не является критически важной для вашей текущей задачи и не используется активно, самым простым решением будет ее отключение:
vkloader.dll в вашем коде.
// ЗагрузитьВнешнююКомпоненту("vkloader.dll"); // Закомментировали, чтобы избежать конфликтов
Если же vkloader.dll необходима для работы других частей системы, рассмотрите возможность ее обновления до последней стабильной версии. Как и в случае с turbomd.dll, устаревшие версии vkloader.dll могут содержать ошибки, приводящие к конфликтам и сбоям.
Работа с внешними компонентами в 1С 7.7 требует внимательности и систематического подхода. Чтобы минимизировать риски возникновения конфликтов и ошибок, рекомендуем придерживаться следующих правил:
ЗагрузитьВнешнююКомпоненту() в глобальном модуле может влиять на стабильность работы. Если мы сталкиваемся с необъяснимыми ошибками, стоит попробовать изменить порядок загрузки компонент.Хотя DWX.ToolBar и решает задачу создания динамических кнопок, существуют и другие, более мощные или стабильные решения для расширения пользовательского интерфейса в 1С 7.7. Если текущее решение вызывает слишком много проблем или мы ищем более универсальные инструменты, стоит рассмотреть следующие альтернативы:
FormEx (ФормЭкс): Это одна из самых известных и широко используемых внешних компонент для 1С 7.7. FormEx предоставляет практически безграничные возможности по управлению формами, созданию сложных панелей инструментов, вкладок, табличных полей с расширенным функционалом, элементов управления типа "дерево" и многое другое. FormEx часто является выбором по умолчанию для создания нестандартных и функционально насыщенных интерфейсов, поскольку она обычно отличается высокой стабильностью и широкой поддержкой сообщества.
RWidget: Еще одна библиотека, предлагающая дополнительные визуальные компоненты и возможности для интерфейса 1С 7.7. RWidget может быть хорошим выбором для специфических задач, дополняя или заменяя некоторые элементы стандартного интерфейса.
ПоставщикДанных (ПД) и VBCCR: Этот подход заслуживает особого внимания, особенно если мы работаем в современных операционных системах (например, Windows 10 x64), где старые компоненты MSComctlLib (Microsoft Common Controls) могут работать нестабильно или вовсе не функционировать. Механизм "ПоставщикДанных" позволяет значительно расширить функционал табличных полей, предоставляя гибкие возможности для отображения и взаимодействия с данными.
Для обеспечения стабильности и совместимости мы можем заменить стандартные элементы управления MSComctlLib на аналоги из VBCCR (VB6 Common Controls Replacement). Этот подход позволяет сохранить внешний вид и функциональность, избегая проблем совместимости. Например, можно произвести следующие замены:
MSComctlLib.ImageListCtrl, отвечающий за библиотеки изображений, может быть заменен на VBCCR17.ImageList.MSComctlLib.Toolbar.2, используемый для панелей инструментов, может быть заменен на VBCCR17.ToolBar.Такие замены минимизируют зависимость от устаревших системных компонентов и повышают общую стабильность решения, особенно на новых операционных системах, где старые библиотеки OWC (Office Web Components) также проявляют нестабильность.
В конечном итоге, проблема необработки нажатия кнопок на тулбаре DWX.ToolBar во внутренней обработке 1С 7.7, является ярким примером комплексности разработки в этой платформе, где взаимодействие множества внешних компонент может приводить к неожиданным конфликтам. Мы выяснили, что основная причина кроется в несовместимости версий turbomd.dll, а также выявили вторичную проблему с vkloader.dll. Обновление компонент до актуальных версий и системное управление ими — ключ к стабильной и эффективной работе наших решений.