Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

18 Май 2021, 17:16 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Вы можете задать вопрос по LibreOffice или Apache OpenOffice без регистрации, используя форму
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1 2 »   Вниз
  Печать  
Автор Тема: Программируемый Диалог  (Прочитано 4425 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #54552: 9 Май 2020, 21:43 »

Здравствуйте!
В своём макросе думаю использовать Диалог, но показалось интересным создавать его программным способом.
Сам принцип и основные действия понятны (кроме обработчика событий - ещё, пока, не совсем разобрался с этим, так как в моём макросе это не применяется), но есть два вопроса, на которые я не могу найти ответов.

Для наглядности, собрал небольшой макрос с дополнительными процедурами, где с помощью диалога запрашивается значение (форматированный ввод данных).
Код:
REM  *****  BASIC  *****
Global Const MinSize = 10
Global Const MaxSize = 100

Sub Macros_Dialog As Boolean
  Dim oDlgModel '   Модель диалога
  Dim oModel '   Модель для элемента управления
  Dim strElemAll(1 To 4) '   Массив строк со свойствами для всех элементов управления
  Dim DlgWidth&, DlgHeight&, DeltaY&, i%
  DlgWidth = 200   : DlgHeight = 150  :   DeltaY = (DlgHeight-50)/4
'  Создается массив свойств элементов управления
strElemAll(1) = Array("Type", "com.sun.star.awt.UnoControlFixedTextModel", "Name", "Label1",_
"PositionX", Clng((DlgWidth-170)/2), "PositionY", Clng(DeltaY), "Width", 170, "Height", 10, _
"Label", "Введите значения от " & MinSize & " до " & MaxSize, "Align", 1, "VerticalAlign", 1 )
strElemAll(2) = Array("Type", "com.sun.star.awt.UnoControlFormattedFieldModel", "Name", "ForField1",_
"PositionX", Clng((DlgWidth-30)/2), "PositionY", Clng(DeltaY*2+10), "Width", 30, "Height", 20, _
"TabIndex", 1, "Tabstop", True, _
"EffectiveValue", MinSize, "EffectiveMin", MinSize - 1, "EffectiveMax", MaxSize + 1, "FormatKey", 1235 )
strElemAll(3) = Array("Type", "com.sun.star.awt.UnoControlButtonModel", "Name", "But_OK",_
"PositionX", Clng((DlgWidth-120)/3), "PositionY", Clng(DeltaY*3+30), "Width", 60, "Height", 20, _
"Label", "ПРИМЕНИТЬ", "PushButtonType", com.sun.star.awt.PushButtonType.OK, _
"TabIndex", 2, "Tabstop", True, "Align", 1, "VerticalAlign", 1 )
strElemAll(4) = Array("Type", "com.sun.star.awt.UnoControlButtonModel", "Name", "But_CANCEL",_
"PositionX", Clng((DlgWidth-120)/3*2+60), "PositionY", Clng(DeltaY*3+30), "Width", 60, "Height", 20, _
"Label", "ОТМЕНИТЬ", "PushButtonType", com.sun.star.awt.PushButtonType.CANCEL, _
"TabIndex", 3, "Tabstop", True, "Align", 1, "VerticalAlign", 1 )
' Создание модели диалога и эл.управления
oDlgModel = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
setProperties_PP(oDlgModel, Array("", , "PositionX", 250, "PositionY", 150, "Width", DlgWidth, "Height", DlgHeight, _
"Title", "Создание Диалога с помощью макроса"))
For i = LBound(strElemAll()) To UBound(strElemAll())
createInsertControl_PP(oDlgModel, strElemAll(i))
Next
' Создается диалог и окно
oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
oDlg.setModel(oDlgModel)
  Dim oWindow
oWindow = CreateUnoService("com.sun.star.awt.Toolkit")
oDlg.createPeer(oWindow, null)
' Выполняется сам диалог с проверкой вводимого значения
  Dim oButtonModel, sTempValue$, ExitWhile%
ExitWhile = 0
Do While ExitWhile < 1
If oDlg.execute() <> 1 Then Macros_Dialog = FALSE : Exit Sub
oButtonModel = oDlg.getControl("ForField1")
sTempValue = oButtonModel.Text
If Dlg_CheckValuePP(sTempValue) = FALSE Then
oButtonModel.Model.TabIndex = 1
oButtonModel.Text = ""
Else
ExitWhile = 1
End If
Loop
Macros_Dialog = TRUE
End Sub
'   Проверка вводимого значения
Sub Dlg_CheckValuePP(sValueText#) As Boolean
If Val(sValueText) < MinSize OR Val(sValueText) > MaxSize Then
MsgBox "Значение выходит за границы диапазона!" & chr(10) & "Повторите ввод данных", 0, "Контроль диапазона"
Dlg_CheckValuePP = FALSE
Else Dlg_CheckValuePP = TRUE
End If
End Sub
'   Создание моделей эл.управления диалога
Sub createInsertControl_PP(oDlgModel, props())
  Dim oModel
oModel = oDlgModel.createInstance(props(1))
setProperties_PP(oModel, props())
oDlgModel.insertByName(props(3), oModel)
End Sub
'   Установка свойств эл.управления и диалога
Sub setProperties_PP(oModel, props())
  Dim i%
For i = 2 To UBound(props()) Step 2
oModel.setPropertyValue(props(i), props(i + 1))
Next
End Sub
Формируется массив свойств для элементов управления диалога, в частности, для поля форм.ввода данных ставится свойство "TabIndex" со значение 1, т.е. при запуске диалога, там устанавливается курсор.
Если вводимое значение выходит за диапазон разрешенных значений, то диалог запускается повторно.
Вот и первый вопрос: есть ли возможность (свойства или методы), что бы при повторном запуске диалога, курсор находился в этом же поле (форм.ввода)?
Снова применяю свойство "TabIndex" (в примере: oButtonModel.Model.TabIndex = 1) - это не приводит к нужному результату - шаг табуляции на кнопке "ПРИМЕНИТЬ".

В примере только одно вводимое поле, в моём макросе их три, и все они проверяются. И диалог перезапускается каждый раз, когда эти значения не соответствуют критериям.
А есть ли способ (и это второй вопрос), когда можно обрабатывать эти поля диалога, но не закрывать его пока все значения не будут в нужном диапазоне?
Возможно, что с помощью обработчика событий, но как это сделать, пока, так и не понял. Если кто знает, то подскажите, пожалуйста, как это можно сделать.

---
Есть ещё один вопрос, который не касается, непосредственно, диалога и эл.управления, но, что называется, рядом.
В этом простом примере всего 4 элемента управления, а в моём макросе их 26, но некоторые свойства у каких-то элементов могут повторяться. Поэтому появилась идея несколько уменьшить программный код и собирать массив свойств (подобный strElemAll() в примере) из нескольких массивов.
Но не получается соединить несколько массивов (которые создаются с помощью Array()) в один одномерный массив. Прошу помощи по этой проблеме.
Да, можно использовать Join() и Split(), но, в результате, получается одномерный массив (что мне и надо!), но строковый. А так как значения свойств не одного типа, то необходим дополнительный анализ полученного массива.

Спасибо.
Записан
Страниц: 1 2 »   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!