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

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

11 Июль 2020, 12:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Сообщений: 94


« Стартовое сообщение: 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(), но, в результате, получается одномерный массив (что мне и надо!), но строковый. А так как значения свойств не одного типа, то необходим дополнительный анализ полученного массива.

Спасибо.
Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 956


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #1: 10 Май 2020, 18:14 »

В своём макросе думаю использовать Диалог, но показалось интересным создавать его программным способом.
Может быть интересно, но в редакторе диалогов получается быстрей и проще. В большинстве случаев нет нужды создавать диалоги с помощью кода.


Вот и первый вопрос: есть ли возможность (свойства или методы), что бы при повторном запуске диалога, курсор находился в этом же поле (форм.ввода)?
Снова применяю свойство "TabIndex" (в примере: oButtonModel.Model.TabIndex = 1) - это не приводит к нужному результату - шаг табуляции на кнопке "ПРИМЕНИТЬ".
Свойство "TabIndex" здесь не причём, оно служит для установления порядка перемещения фокуса клавишей "TAB", при этом оно само по себе не меняется.
После нажатия на кнопку "ПРИМЕНИТЬ" происходят два действия: первым делом перемещается фокус на эту кнопку, затем закрывается диалог, но объект диалога никуда не пропадает, его снова можно запустить методом oDlg.Execute() в том виде, в каком он был на момент закрытия, т.е. фокус будет на кнопке "ПРИМЕНИТЬ". Переместить фокус можно методом oDlg.getControl("ForField1").setFocus()


Поэтому появилась идея несколько уменьшить программный код и собирать массив свойств (подобный strElemAll() в примере) из нескольких массивов.
Уменьшить программный код это очень хорошо, но путь который вы выбрали приведёт к усложнению кода (он и без этого сложный). Свойства нужно устанавливать методом setPropertyValues()
Записан

Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #2: 10 Май 2020, 21:15 »

Свойство "TabIndex" здесь не причём, оно служит для установления порядка перемещения фокуса клавишей "TAB", при этом оно само по себе не меняется.
После нажатия на кнопку "ПРИМЕНИТЬ" происходят два действия: первым делом перемещается фокус на эту кнопку, затем закрывается диалог, но объект диалога никуда не пропадает, его снова можно запустить методом oDlg.Execute() в том виде, в каком он был на момент закрытия, т.е. фокус будет на кнопке "ПРИМЕНИТЬ". Переместить фокус можно методом oDlg.getControl("ForField1").setFocus()
Цитата: Tigrik от Вчера в 21:43
Уменьшить программный код это очень хорошо, но путь который вы выбрали приведёт к усложнению кода (он и без этого сложный). Свойства нужно устанавливать методом setPropertyValues()

Rami, спасибо большое за помощь.
У меня же была в голове, как сейчас модно говорить, мыслеформа - присмотреться к фокусу, но, почему то, подумал, что это связано с обработкой событий и мышкой, когда наводишь на определенное место диалога.
Всё отлично работает!

Скорее всего, я не совсем грамотно объяснил свои поиски "сборки" массивов.
В любом случае, я использовал и буду использовать метод setPropertyValues(). В данный момент, весь массив свойств для конкретного элемента управления определяется в одном месте (как это показано в примере). Для некоторых элементов упр. некоторые свойства одинаковые, то есть их можно завести в отдельные массивы. И, уже перед самым циклом задания моделей элементов, окончательно "собрать" массив свойств из нескольких массивов (если это будет необходимо).
Как я уже говорил, можно "собрать" строку (там как и положено чередуются название свойств и их значения, допустим, через запятую - Join() так может делать) из разных массивов, а затем "расщепить" (Split()) в строковый массив, а элементы массива, которые являются значениями свойств (каждый второй, так как первый - имя свойства), преобразовать в численное значение. Но некоторая "загвоздка" в том, что есть и строковые значения свойств. Правда, их немного и это не так трудно анализировать, но, сначала, я решил подумать: можно ли обойтись без этих преобразований.
На небольшом примере будет более наглядно.
   Dim a, b, c
   a = Array("Name", "But_OK")
   b = Array("Align", 1, "Label", "ОТМЕНИТЬ")
Как сделать, что бы одномерный массив с состоял из массивов а и в, т.е. с = {"Name", "But_OK", "Align", 1, "Label", "ОТМЕНИТЬ"}?
Конечно, это можно сделать в цикле, непосредственно задавая каждому элементу массива соотвествующее значение. Но если таких действий много, то это, наоборот, по моему мнению, перегружает код.
Может быть, можно применить что то из категории сложение матриц, но я, к сожалению, пока, с этим не сталкивался?

Спасибо.
Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 956


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #3: 11 Май 2020, 12:10 »

Если нужно объединить два массива, то создайте функцию которая будет получать эти массивы, определять размерность массивов, создавать новый массив соответствующей размерности и наполнять его данными в цикле. Но всё это "шайтан арба".
Записан

Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #4: 11 Май 2020, 19:53 »

Если нужно объединить два массива, то создайте функцию которая будет получать эти массивы, определять размерность массивов, создавать новый массив соответствующей размерности и наполнять его данными в цикле. Но всё это "шайтан арба".

У меня, пока, ещё мало знаний, навыков и опыта в программировании макросов в ЛО, поэтому и спрашивал про массивы.
Может быть, есть какое-нибудь простое решение, а не то, что получилось у меня:
Код:
Sub Proba_SumArray
   Dim Arr01, Arr02, Arr03, ArrPlus
Arr01 = Array("Type", "com.sun.star.awt.UnoControlButtonModel")
Arr02 = Array("Name", "But_OK", "PushButtonType", com.sun.star.awt.PushButtonType.OK)
Arr03 = Array("Align", 1, "Label", "ПРИМЕНИТЬ")
ArrPlus = Join_Arrays(Array(Arr01, Arr02, Arr03))
End Sub

Function Join_Arrays(arBeg()) As Object
 Dim i%, j%, k%
  For i = LBound(arBeg()) To UBound(arBeg()) : j = j + UBound(arBeg(i)) + 1 : Next
 Dim arSum(j - 1)
For j = LBound(arBeg()) To UBound(arBeg())
For i = LBound(arBeg(j)) To UBound(arBeg(j)) : arSum(k + i) = arBeg(j)(i) : Next
k = k + UBound(arBeg(j)) + 1
Next
Join_Arrays = arSum()
End Function
Конечно, функция не очень большая, но, возможно, есть лучший вариант!?
Да, для "сложения" двух массивов, код функции меньше, но решил, в данном случае, не "мелочиться" - пусть будет обработка больше двух массивов.

Скорее всего, буду применять этот вариант, так как для обработки строкового массива логики (следовательно, кода) намного больше.
Записан
Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #5: 11 Июнь 2020, 00:32 »

Подскажите, пожалуйста!

В продолжение темы программируемых диалогов, так как необходим, именно, этот вариант.
Вроде получилось "прицепить" обработчик событий к кнопкам, но не закрывается сам диалог.
Уже два дня перебираю различные способы решить эту проблему.
Может быть, .dispose(), но куда его определить?
Или где-то что-то напутал?
Код:
Sub Dlg_Button()
 Dim oDlgModel, oDlg, oModel
oDlgModel = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
oDlgModel.setPropertyValue("PositionX", 333) : oDlgModel.setPropertyValue("PositionY", 185)
oDlgModel.setPropertyValue("Width", 160) : oDlgModel.setPropertyValue("Height", 60)
oDlgModel.setPropertyValue("Title", "Кнопки в диалоге")
oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
oDlg.setModel(oDlgModel)
 For i% = 1 to 2
oModel = oDlgModel.createInstance("com.sun.star.awt.UnoControlButtonModel")
oModel.setPropertyValue("PositionX", Clng(70*i-50)) : oModel.setPropertyValue("PositionY", 20)
oModel.setPropertyValue("Width", 50) : oModel.setPropertyValue("Height", 20)
oModel.setPropertyValue("PushButtonType", 0) : oModel.setPropertyValue("Label", "Кнопка № "&i)
oDlgModel.insertByName("ComButton" & i, oModel)
oDlg.getControl("ComButton"&i).addActionListener(CreateUnoListener("Button_", "com.sun.star.awt.XActionListener"))
 Next
oDlg.createPeer(CreateUnoService("com.sun.star.awt.Toolkit"), null)
If oDlg.execute() = 0 Then Print "Выход без кнопки!" : Exit Sub
Print "Нажата какая-то кнопка!"
End Sub


Sub Button_actionPerformed(ActionEvent)
Print "Нажата кнопка: "  & ActionEvent.Source.Model.Label
' .dispose()
End Sub

Спасибо.
« Последнее редактирование: 11 Июнь 2020, 00:34 от Tigrik » Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 956


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #6: 11 Июнь 2020, 07:25 »

Может быть, .dispose(), но куда его определить?
.dispose() уничтожает диалог, а не закрывает, потом вы ещё что-то хотите делать с уже не существующим диалогом.

Закрывать диалог нужно методом oDlg.endExecute(), а чтобы переменная oDlg была видна в других макросах этого модуля, нужно объявлять её в модуле, а не в макросе.
Код:
Dim oDlg                          'эта переменная видна всем макросам этого модуля
Sub Dlg_Button()
Dim oDlgModel, oModel, oLis, i%   'эти переменные видны только в этом макросе
oDlgModel = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
oDlgModel.setPropertyValue("PositionX", 333) : oDlgModel.setPropertyValue("PositionY", 185)
oDlgModel.setPropertyValue("Width", 160) : oDlgModel.setPropertyValue("Height", 60)
oDlgModel.setPropertyValue("Title", "Кнопки в диалоге")
oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
oDlg.setModel(oDlgModel)
oLis = CreateUnoListener("Button_", "com.sun.star.awt.XActionListener")
For i = 1 to 2
oModel = oDlgModel.createInstance("com.sun.star.awt.UnoControlButtonModel")
oModel.setPropertyValue("PositionX", Clng(70*i-50)) : oModel.setPropertyValue("PositionY", 20)
oModel.setPropertyValue("Width", 50) : oModel.setPropertyValue("Height", 20)
oModel.setPropertyValue("PushButtonType", 0) : oModel.setPropertyValue("Label", "Кнопка № "&i)
oDlgModel.insertByName("ComButton" & i, oModel)
oDlg.getControl("ComButton"&i).addActionListener(oLis)
Next
oDlg.createPeer(CreateUnoService("com.sun.star.awt.Toolkit"), null)
If oDlg.execute() = 0 Then Print "Выход без кнопки!" : Exit Sub
Print "Нажата какая-то кнопка!"
End Sub


Sub Button_actionPerformed(ActionEvent)
    Print "Нажата кнопка: "  & ActionEvent.Source.Model.Label
    oDlg.endExecute()
End Sub
Записан

Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #7: 11 Июнь 2020, 14:25 »

.dispose() уничтожает диалог, а не закрывает, потом вы ещё что-то хотите делать с уже не существующим диалогом.

Закрывать диалог нужно методом oDlg.endExecute(), а чтобы переменная oDlg была видна в других макросах этого модуля, нужно объявлять её в модуле, а не в макросе.
Благодарю Rami.
Самое интересное, что я два дня ходил вокруг да около этого метода, но прочитав, что он скрывает диалог и даже не стал его пробовать.
Диалог закрывается, но... Но, почему-то, перестал работать выход из окна диалога по "Закрыть" (х, который вверху справа).
Это так и должно быть или баг?
Проверить это условие можно и по-другому (как в примере), тем более, всё равно необходимо возвращать результат в основную процедуру.
Код:
Dim oDlg '  Объект Диалог
Dim DlgRez '  Результат действия Диалога
Sub Dlg_Button()
 Dim oDlgModel, oModel
oDlgModel = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
oDlgModel.setPropertyValue("PositionX", 333) : oDlgModel.setPropertyValue("PositionY", 185)
oDlgModel.setPropertyValue("Width", 160) : oDlgModel.setPropertyValue("Height", 60)
oDlgModel.setPropertyValue("Title", "Кнопки в диалоге")
oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
oDlg.setModel(oDlgModel)
 For i% = 1 to 2
oModel = oDlgModel.createInstance("com.sun.star.awt.UnoControlButtonModel")
oModel.setPropertyValue("PositionX", Clng(70*i-50)) : oModel.setPropertyValue("PositionY", 20)
oModel.setPropertyValue("Width", 50) : oModel.setPropertyValue("Height", 20)
oModel.setPropertyValue("PushButtonType", 0) : oModel.setPropertyValue("Label", "Кнопка № "&i)
oModel.setPropertyValue("TabIndex", i)
oDlgModel.insertByName("ComButton" & i, oModel)
oDlg.getControl("ComButton"&i).addActionListener(CreateUnoListener("Button_", "com.sun.star.awt.XActionListener"))
 Next
oDlg.createPeer(CreateUnoService("com.sun.star.awt.Toolkit"), null)
DlgRez = 0
oDlg.execute()
'If oDlg.execute() = 0 Then Print "Выход без кнопки!" : Exit Sub '   Почему-то не работает!?
If DlgRez Then Print "Нажата кнопка № " & DlgRez Else Print "Выход без кнопки!"
End Sub


Sub Button_actionPerformed(ActionEvent)
DlgRez = ActionEvent.Source.Model.TabIndex
Print "TabIndex: "  & DlgRez
oDlg.endExecute()
' oDlg.dispose() '  Диалог больше не нужен - можно удалять. Но вылетает приложение!!!
End Sub
Есть один небольшой вопрос: можно ли передавать параметры через обработчики событий.
Например, из основной процедуры в процедуру Button_actionPerformed(ActionEvent) объект Диалог (в данном примере - oDlg), а из процедуры Button_actionPerformed(ActionEvent) вернуть в основную процедуру DlgRez?
С большой вероятностью, думаю, что нельзя. Жаль, но ладно!

Если нельзя, тогда ещё один подвопрос: если в макросе нужно будет использовать ещё различные диалоги, можно ли безбоязненно применять этот указатель oDlg, после того как уничтожится диалог методом .dispose()?
Когда его лучше применять: до начала записи Диалога или сразу же после завершения Диалога? Или без разницы?
Но, самое главное, КАК ПРАВИЛЬНО его применять?
oDlg.dispose() - вылетает приложение!
« Последнее редактирование: 11 Июнь 2020, 14:32 от Tigrik » Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 956


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #8: 11 Июнь 2020, 17:46 »

из основной процедуры в процедуру Button_actionPerformed(ActionEvent) объект Диалог (в данном примере - oDlg)
В Button_actionPerformed передаётся объект вызвавший событие (кнопка), а у кнопки есть родительский объект (диалог), так что можно получить объект диалога из ActionEvent, но проще объявить переменную в модуле.

из процедуры Button_actionPerformed(ActionEvent) вернуть в основную процедуру DlgRez?
Смотрите в примере методы .endDialog() и .execute() и пояснения к ним.

можно ли безбоязненно применять этот указатель oDlg, после того как уничтожится диалог методом .dispose()?
Зачем уничтожать диалог? Если очемь хочется, можно обнулить переменную oDlg.

Код:
Dim oDlg, x, n 'Объект Диалог
Sub Dlg_Button()
Dim oDlgModel, oModel, oLis, i%
Dim DlgRez 'Результат действия Диалога
oDlgModel = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
oDlgModel.setPropertyValue("PositionX", 333) : oDlgModel.setPropertyValue("PositionY", 185)
oDlgModel.setPropertyValue("Width", 160) : oDlgModel.setPropertyValue("Height", 60)
oDlgModel.setPropertyValue("Title", "Кнопки в диалоге")
oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
oDlg.setModel(oDlgModel)
oLis = CreateUnoListener("Button_", "com.sun.star.awt.XActionListener")  'Listener создаём один раз
For i% = 1 to 2
oModel = oDlgModel.createInstance("com.sun.star.awt.UnoControlButtonModel")
oModel.setPropertyValue("PositionX", Clng(70*i-50)) : oModel.setPropertyValue("PositionY", 20)
oModel.setPropertyValue("Width", 50) : oModel.setPropertyValue("Height", 20)
oModel.setPropertyValue("PushButtonType", 0) : oModel.setPropertyValue("Label", "Кнопка № "&i)
oModel.setPropertyValue("TabIndex", i)
oDlgModel.insertByName("ComButton" & i, oModel)
oDlg.getControl("ComButton" & i).addActionListener(oLis)
Next
oDlg.createPeer(CreateUnoService("com.sun.star.awt.Toolkit"), null)
DlgRez = oDlg.execute()         'возвращает значение переданное в метод oDlg.endDialog(nTabIndex)
'If oDlg.execute() = 0 Then Print "Выход без кнопки!" : Exit Sub 'Почему-то не работает!?
If DlgRez Then Print "Нажата кнопка № " & DlgRez Else Print "Выход без кнопки!"
End Sub


Sub Button_actionPerformed(ActionEvent)
Dim nTabIndex%
nTabIndex = ActionEvent.Source.Model.TabIndex
Print "TabIndex: "  & nTabIndex
oDlg.endDialog(nTabIndex)          'передаём значение методу oDlg.execute()
' oDlg = Nothing 'раскомментировать, если хочется обнулить объект
End Sub
Записан

Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #9: 11 Июнь 2020, 18:46 »

В Button_actionPerformed передаётся объект вызвавший событие (кнопка), а у кнопки есть родительский объект (диалог), так что можно получить объект диалога из ActionEvent, но проще объявить переменную в модуле.

Смотрите в примере методы .endDialog() и .execute() и пояснения к ним.

Зачем уничтожать диалог? Если очемь хочется, можно обнулить переменную oDlg.

Rami, огромное спасибо за помощь!

Конечно, мне и не нужно удалять сам объект, я, просто, не знал о таком способе. Это может пригодится, если подобную процедуру нужно будет вызывать из разных мест макроса, а объект oDlg снова будет использоваться. Честно говоря, для себя, я не уверен, что "использованный" oDlg не внесет "погрешности" во вновь создаваемый Диалог. Поэтому, думаю, что обнуление объекта будет самое оно. Возможно я не правильно рассуждаю!?

Возвращение результата - просто СУПЕР.

---
Не понял для чего нужны переменные "x" и "n", которые объявлены перед основной процедурой вместе с oDlg?
Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 956


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #10: 11 Июнь 2020, 19:26 »

Честно говоря, для себя, я не уверен, что "использованный" oDlg не внесет "погрешности" во вновь создаваемый Диалог.
Не внесёт, новое присвоение oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog") заменяет старый диалог со всеми "прибамбасами" на новый пустой.


Не понял для чего нужны переменные "x" и "n", которые объявлены перед основной процедурой вместе с oDlg?
Это чтобы сбить с толку шпионов Афро (использовал эти переменные для проверки некоторых промежуточных параметров, да забыл удалить)
Записан

Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #11: 11 Июнь 2020, 19:36 »

Не внесёт, новое присвоение oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog") заменяет старый диалог со всеми "прибамбасами" на новый пустой.
Понял, отлично, тогда, конечно, ничего не буду постороннего "лепить".

Ещё раз, огромное спасибо. Я, даже, и не знаю, где бы я нашел такую информацию, которую получил от Вас.
Записан
Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #12: 11 Июнь 2020, 20:28 »

Не внесёт, новое присвоение oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog") заменяет старый диалог со всеми "прибамбасами" на новый пустой.
Всё стеснялся забывал спросить, но что бы не множить темы, спрошу здесь, так как вопрос по контексту.
После объявления переменной (не будем трогать объекты - простые переменные, в том числе, и массивы переменных) в LibreOffice Basic, они автоматически будут не просто пустые, а с нулевыми значениями (нули - при численных переменных, пустая строка - при символьных)?
Или им нужно будет присваивать это значение, что бы не было ошибок?
Скорее всего, этот вопрос "детский", но осваиваю Basic не по учебникам (если учебником не считать книгу Питоньяка - очень полезная, для меня, книга).
Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 956


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #13: 11 Июнь 2020, 23:03 »

После объявления переменной (не будем трогать объекты - простые переменные, в том числе, и массивы переменных) в LibreOffice Basic, они автоматически будут не просто пустые, а с нулевыми значениями (нули - при численных переменных, пустая строка - при символьных)?
Или им нужно будет присваивать это значение, что бы не было ошибок?
Достаточно объявить тип.
Записан

Tigrik
Форумчанин
***
Offline Offline

Сообщений: 94


« Ответ #14: 13 Июнь 2020, 15:02 »

Мой вопрос, некоторое отношение, имеет и к программируемым диалогам, поэтому задам вопрос в этой теме.

Давно уже пытаюсь найти наиболее правильный и удобный метод по определению истинного размера монитора.
Скорее всего в объекте Windows, но, не совсем, уверен. Тот метод, что используется в коде дает точные размеры монитора, но для работы диалога необходым коэффициенты - скорее всего, размеры диалогов используют свои коэффициенты (твипы, или подобное, не разобрался).
Подскажите, пожалуйста.
Небольшой код прилагается.
Код:
Sub Dlg_Display()
 Dim oWindow, oDlg, oDlgModel
 Dim WW&, WH&, disKoefW, disKoefH
oWindow = CreateUnoService("com.sun.star.awt.Toolkit")
WW = oWindow.ActiveTopWindow.Info.Width
WH = oWindow.ActiveTopWindow.Info.Height
disKoefW = 1.78 : disKoefH = 1.63
oDlgModel = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
oDlgModel.setPropertyValue("PositionX", 0) : oDlgModel.setPropertyValue("PositionY", 0)
oDlgModel.setPropertyValue("Width", Clng(WW/disKoefW)) : oDlgModel.setPropertyValue("Height", Clng(WH/disKoefH))
oDlgModel.setPropertyValue("Title", "Диалог - Большое Окно")
oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
oDlg.setModel(oDlgModel)
oDlg.createPeer(oWindow, null)
oDlg.execute()
End Sub
Пробным методом подобрал коэффициенты для своего монитора - диалог закрывает все окно монитора, кроме "Панели задач".
Записан
Страниц: 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!