Как в 1С отловить событие создания нового окна и программно изменить его содержимое

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие часто возникают задачи, требующие вмешательства в процесс отображения форм. Одной из наиболее интересных и сложных задач является «отлов» события создания нового окна. Это может потребоваться для автоматического перевода интерфейса на другой язык, динамической подмены заголовков, логирования действий пользователя или интеграции с внешними системами. Разберем детально, какими способами можно реализовать этот функционал в управляемом приложении.

Анализируем проблему: форма или окно?

Для начала проанализируем разницу между понятиями. В 1С существует создание объекта УправляемаяФорма на сервере и открытие окна на клиенте. Если нам нужно модифицировать состав реквизитов или заголовки, нам важно событие создания. Если же нужно управлять положением окна или перехватывать системные предупреждения (которые не всегда являются полноценными формами объектов), мы работаем с контекстом клиентского приложения.

Способ 1. Использование расширений и перехват ПриСозданииНаСервере

Рассмотрим наиболее современный и «чистый» способ — использование механизма расширений. Поскольку в 1С нет единого глобального обработчика события «Создание любой формы», мы можем использовать возможность расширений подцепляться к методам объектов.

Выясним, как это работает: мы создаем расширение и добавляем в него интересующие нас типы объектов (справочники, документы). Далее, используя аннотацию &После, мы внедряем свой код в процедуру ПриСозданииНаСервере. Это позволяет нам централизованно вызывать процедуру перевода или модификации.

Рассмотрим пример кода в общем модуле расширения:


&После("ПриСозданииНаСервере")
Процедура Мой_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Вызываем глобальную функцию перевода
    Мой_Локализатор.ПеревестиИнтерфейсФормы(ЭтотОбъект);
КонецПроцедуры

В методе ПеревестиИнтерфейсФормы мы можем рекурсивно обойти все элементы формы, проверяя их тип (ГруппаФормы, КнопкаФормы, ПолеФормы) и меняя их свойства Заголовок или Подсказка.

Способ 2. Использование обработчика ОбработкаПолученияФормы

Посмотрим на встроенное событие менеджера объекта ОбработкаПолученияФормы. Этот метод вызывается ПЕРЕД тем, как форма будет создана. Это крайне полезно, если нам нужно подменить одну форму другой или изменить параметры открытия до инициализации самой формы.

Проанализируем ситуацию: этот метод не является глобальным для всей конфигурации, он принадлежит менеджеру конкретного объекта (например, Справочники.Номенклатура.ОбработкаПолученияФормы). Однако, если ваша задача ограничена ключевыми документами (заказы, реализации), этот метод будет наиболее эффективным.


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    // Здесь можно перехватить запрос на открытие и добавить свои параметры
    Параметры.Вставить("МойПараметрЛокализации", Истина);
КонецПроцедуры

Способ 3. Перехват системных диалогов через Библиотеку стандартных подсистем (БСП)

Если наша цель — отлавливать предупреждения типа ПоказатьПредупреждение или ПоказатьВопрос, нам нужно заглянуть в общие модули БСП. В типовых конфигурациях (УНФ, ERP, БП) большинство диалогов вызывается через процедуры общего назначения.

Разберем по шагам: найдем общий модуль ОбщегоНазначенияКлиент. В нем часто инкапсулированы вызовы стандартных функций. Переопределив эти функции в расширении, мы получаем «точку входа» для изменения любого текста, который выводится пользователю в диалоговых окнах.

Способ 4. Клиентский мониторинг через ПолучитьОкна()

Существует специфический метод для случаев, когда нужно отследить появление окна, не имея доступа к коду его создания (например, окна, генерируемые самой платформой). Мы можем использовать обработчик ожидания.

Проанализируем этот метод подробнее. В модуле управляемого приложения мы запускаем периодическую проверку коллекции окон. Чтобы избежать «мигания» курсора и падения производительности, проверку нужно делать максимально легкой и только на стороне клиента.


Процедура ПриНачалеРаботыСистемы()
    ПодключитьОбработчикОжидания("ПроверитьНовыеОкна", 1);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьНовыеОкна() Экспорт
    МассивОкон = ПолучитьОкна();
    Для Каждого ТекущееОкно Из МассивОкон Цикл
        // Проверяем, обрабатывали ли мы это окно ранее
        Если ЭтоНовоеОкно(ТекущееОкно) Тогда
            ОбработатьСодержимоеОкна(ТекущееОкно);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Важный момент: объект ОкноКлиентскогоПриложения позволяет получить доступ к ОсновнаяФорма, через которую мы можем дотянуться до элементов управления и изменить их заголовки «на лету».

Способ 5. Технология UI Automation и Windows API (для продвинутых)

Выясним, что делать, если штатных средств 1С недостаточно. В операционной системе Windows существует интерфейс Microsoft UI Automation. С его помощью внешнее приложение (или внешняя компонента для 1С) может подписаться на события создания окон процесса 1cv8.exe.

Как это работает? При появлении нового системного окна Windows посылает уведомление. Внешняя компонента может перехватить это событие, найти дескриптор окна (HWND), извлечь текст из элементов управления через WM_GETTEXT и принудительно изменить его через WM_SETTEXT. Это позволяет переводить даже те сообщения об ошибках, которые жестко зашиты в ядро платформы 1С.

Рекомендации по реализации

Подводя итог, разберем наиболее рациональный алгоритм действий при разработке системы перехвата окон:

  1. Определите область перехвата. Если вам нужны только формы справочников и документов — используйте расширения с аннотацией &После("ПриСозданииНаСервере").
  2. Для системных сообщений используйте переопределение процедур БСП в общем модуле ОбщегоНазначенияКлиент.
  3. Для динамической локализации создайте РегистрСведений, где будут храниться пары «Исходный текст — Переведенный текст», чтобы не прописывать переводы жестко в коде.
  4. Используйте кэширование. Не стоит обходить все элементы формы каждый раз при открытии. Один раз рассчитав перевод для конкретной формы, сохраните его в соответствии (КэшПереводов), чтобы ускорить работу интерфейса.

Использование данных методов позволит вам создать гибкую систему управления интерфейсом, которая сможет адаптироваться под нужды пользователя без внесения масштабных изменений в основную конфигурацию.

← На главную