Почему не обрабатывается нажатие кнопки на тулбаре DWX.ToolBar во внутренней обработке 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Когда мы разрабатываем сложные интерфейсы в 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 начинала работать корректно.

Решение 1: Обновление компоненты turbomd.dll

После выявления конфликта с turbomd.dll, первым шагом к решению является ее обновление. Важно понимать, что не все версии turbomd.dll одинаково полезны или совместимы. Некоторые старые версии, даже если они были доступны на популярных ресурсах, могли содержать ошибки или несовместимости с другими компонентами.

Разберем шаги по обновлению:

  1. Найдите актуальную версию turbomd.dll. Следует искать проверенные источники и самые свежие сборки компоненты. Иногда на форумах 1С++ пользователи делятся наиболее стабильными и совместимыми версиями.
  2. Загрузите и замените файл. После загрузки файла, замените им существующий turbomd.dll в каталоге bin вашей установки 1С:Предприятие 7.7. Рекомендуется предварительно сделать резервную копию заменяемого файла.
  3. Зарегистрируйте компоненту. Откройте командную строку с правами администратора и выполните команду regsvr32 C:\Путь\К\1С\bin\turbomd.dll (укажите ваш актуальный путь). Это гарантирует, что система корректно зарегистрирует новую версию компоненты.

В нашем случае, использование определенной, более новой версии turbomd.dll, найденной на форумах 1С++, решило проблему с обработкой нажатий кнопок DWX.ToolBar. Это подтверждает, что разработчики turbomd.dll устранили внутренние несовместимости в более поздних версиях.

Решение 2: Устранение конфликта с vkloader.dll

После решения основной проблемы с turbomd.dll, мы можем столкнуться с новой, но также связанной с внешними компонентами: аварийным завершением работы 1С при закрытии обработки. Если в глобальном модуле или в других частях кода у вас загружается компонента vkloader.dll (например, с помощью ЗагрузитьВнешнююКомпоненту("vkloader.dll")), то она может стать причиной сбоев.

В логах ошибок Windows (Журнал событий) или при краше 1С вы можете увидеть сообщение, указывающее на vkloader.dll_unloaded как на модуль, вызвавший проблему. Это означает, что при выгрузке vkloader.dll происходит ошибка, приводящая к падению приложения.

Если компонента vkloader.dll не является критически важной для вашей текущей задачи и не используется активно, самым простым решением будет ее отключение:

  1. Найдите строку загрузки vkloader.dll в вашем коде.
  2. Закомментируйте эту строку или полностью удалите ее.

// ЗагрузитьВнешнююКомпоненту("vkloader.dll"); // Закомментировали, чтобы избежать конфликтов

Если же vkloader.dll необходима для работы других частей системы, рассмотрите возможность ее обновления до последней стабильной версии. Как и в случае с turbomd.dll, устаревшие версии vkloader.dll могут содержать ошибки, приводящие к конфликтам и сбоям.

Общие рекомендации по работе с внешними компонентами в 1С 7.7

Работа с внешними компонентами в 1С 7.7 требует внимательности и систематического подхода. Чтобы минимизировать риски возникновения конфликтов и ошибок, рекомендуем придерживаться следующих правил:

  1. Актуальность версий: Мы всегда должны стремиться использовать самые свежие и стабильные версии внешних компонент. Разработчики постоянно исправляют ошибки, улучшают совместимость и добавляют новый функционал. Проверка актуальности компонент может предотвратить множество проблем.
  2. Минимизация количества компонент: Мы должны загружать только те компоненты, которые действительно необходимы для работы нашей конфигурации или обработки. Чем меньше сторонних DLL загружено, тем ниже вероятность возникновения конфликтов, перехвата общих ресурсов или некорректного взаимодействия.
  3. Порядок загрузки: В некоторых случаях последовательность вызовов ЗагрузитьВнешнююКомпоненту() в глобальном модуле может влиять на стабильность работы. Если мы сталкиваемся с необъяснимыми ошибками, стоит попробовать изменить порядок загрузки компонент.
  4. Тестирование в чистом окружении: При возникновении проблем, связанных с внешними компонентами, мы должны тестировать функционал в максимально "чистой" конфигурации 1С. Это означает, что мы последовательно подключаем только те компоненты, которые непосредственно участвуют в проблемном сценарии. Такой подход помогает быстро локализовать источник конфликта.

Альтернативные подходы к созданию пользовательских интерфейсов в 1С 7.7

Хотя DWX.ToolBar и решает задачу создания динамических кнопок, существуют и другие, более мощные или стабильные решения для расширения пользовательского интерфейса в 1С 7.7. Если текущее решение вызывает слишком много проблем или мы ищем более универсальные инструменты, стоит рассмотреть следующие альтернативы:

В конечном итоге, проблема необработки нажатия кнопок на тулбаре DWX.ToolBar во внутренней обработке 1С 7.7, является ярким примером комплексности разработки в этой платформе, где взаимодействие множества внешних компонент может приводить к неожиданным конфликтам. Мы выяснили, что основная причина кроется в несовместимости версий turbomd.dll, а также выявили вторичную проблему с vkloader.dll. Обновление компонент до актуальных версий и системное управление ими — ключ к стабильной и эффективной работе наших решений.

← На главную