При разработке интерфейсов в платформе 1С:Предприятие 7.7 иногда возникает задача интерактивной обработки текста: например, определить слово, на котором установлен курсор, и переместить его левее или правее, либо вставить определенный шаблон в позицию каретки. Однако штатный элемент диалога Поле ввода платформы 7.7 не предоставляет встроенных методов и свойств для чтения или программной установки позиции курсора.
Разберем причины этого ограничения, а также детально рассмотрим способы его обхода с помощью внешних компонентов, ActiveX-элементов и функций Windows API.
Штатные поля ввода в 1С 7.7 построены на основе стандартных элементов управления Windows (Win32 EDIT), однако встроенный язык 1С 7.7 не имеет объектной модели для низкоуровневой работы с кареткой и дескрипторами окон (HWND). Кроме того, при нажатии на кнопку формы поле ввода теряет фокус, что приводит к сокрытию каретки.
Для решения задачи применяются альтернативные подходы, позволяющие получить полный контроль над текстом и курсором.
Наиболее удобный и надежный способ для 1С 7.7 — внедрение на форму внешнего элемента управления через специализированную компоненту работы с ActiveX. В качестве элемента ввода можно использовать стандартный Forms.TextBox.1 из библиотеки Microsoft Forms (MSForms).
У данного элемента управления есть встроенные свойства, позволяющие работать с курсором и выделением:
SelStart — числовой индекс текущей позиции каретки (отсчет начинается с 0). Если в поле есть выделение, свойство указывает на начало выделенного блока.SelLength — длина выделенного фрагмента текста (равна 0, если текст не выделен, а курсор просто установлен в определенную позицию).SelText — непосредственно выделенный фрагмент текста, доступный как для чтения, так и для перезаписи.Рассмотрим пример инициализации элемента Forms.TextBox.1 при открытии формы:
Процедура ПослеОткрытия()
АтрФормы = СоздатьОбъект("АктивИкс");
АтрФормы.УстановитьАтрибут(Форма, "тТекст");
тТекст = АтрФормы.СоздатьЭУ("Forms.TextBox.1");
тТекст.Text = "Пример текста для проверки позиции";
КонецПроцедуры
Теперь, когда пользователь устанавливает курсор в нужное место строки, по нажатию кнопки или событию формы мы можем мгновенно получить позицию символа:
Процедура ОбработатьПозицию()
ПозицияКурсора = тТекст.SelStart;
ТекстПоля = тТекст.Text;
Сообщить("Текущая позиция курсора: " + ПозицияКурсора);
КонецПроцедуры
Если интерфейс конфигурации не позволяет заменить штатные поля на ActiveX, можно обратиться напрямую к функциям Windows API через внешние библиотеки вызовов (например, DynamicWrapperX) или перехват оконных сообщений.
Стандартный элемент управления EDIT в Windows управляется через системные сообщения:
EM_GETSEL (код 0x00B0) дескриптору окна HWND поля ввода. Сообщение возвращает начальную и конечную позицию выделения. Если текст не выделен, оба значения равны и указывают на точное положение каретки в строке.EM_SETSEL (код 0x00B1) с указанием начального и конечного индекса. Передача одинаковых значений перемещает курсор в нужную точку без выделения текста.EM_CHARFROMPOS позволяет вычислить индекс символа по экранным координатам клика мыши.Еще один гибкий вариант — размещение на форме элемента WebBrowser с HTML-полем ввода (<input type="text"> или <textarea>). В модели DOM браузера доступны свойства selectionStart и selectionEnd, а логику перестановки слов можно реализовать как на JavaScript внутри страницы, так и передавая события обратно в модуль 1С.
Если задача заключается исключительно в конструировании порядка слов (например, составление наименования или адреса), часто удобнее пересмотреть логику ввода: