Программируемый Диалог

Автор Tigrik, 9 мая 2020, 21:43

0 Пользователи и 1 гость просматривают эту тему.

Tigrik

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

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

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

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


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


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

Tigrik

Цитата: rami от 10 мая 2020, 18:14Свойство "TabIndex" здесь не причём, оно служит для установления порядка перемещения фокуса клавишей "TAB", при этом оно само по себе не меняется.
После нажатия на кнопку "ПРИМЕНИТЬ" происходят два действия: первым делом перемещается фокус на эту кнопку, затем закрывается диалог, но объект диалога никуда не пропадает, его снова можно запустить методом oDlg.Execute() в том виде, в каком он был на момент закрытия, т.е. фокус будет на кнопке "ПРИМЕНИТЬ". Переместить фокус можно методом oDlg.getControl("ForField1").setFocus()
Цитата: rami от 10 мая 2020, 18:14Цитата: 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

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

Tigrik

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

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

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

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

В продолжение темы программируемых диалогов, так как необходим, именно, этот вариант.
Вроде получилось "прицепить" обработчик событий к кнопкам, но не закрывается сам диалог.
Уже два дня перебираю различные способы решить эту проблему.
Может быть, .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


Спасибо.

rami

Цитата: Tigrik от 11 июня 2020, 00:32Может быть, .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

#7
Цитата: rami от 11 июня 2020, 07: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() - вылетает приложение!

rami

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

Цитата: Tigrik от 11 июня 2020, 14:25из процедуры Button_actionPerformed(ActionEvent) вернуть в основную процедуру DlgRez?
Смотрите в примере методы .endDialog() и .execute() и пояснения к ним.

Цитата: Tigrik от 11 июня 2020, 14:25можно ли безбоязненно применять этот указатель 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

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

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

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

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

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

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

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

rami

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


Цитата: Tigrik от 11 июня 2020, 18:46Не понял для чего нужны переменные "x" и "n", которые объявлены перед основной процедурой вместе с oDlg?
Это чтобы сбить с толку шпионов O0 (использовал эти переменные для проверки некоторых промежуточных параметров, да забыл удалить)

Tigrik

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

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

Tigrik

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

rami

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

Tigrik

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

Давно уже пытаюсь найти наиболее правильный и удобный метод по определению истинного размера монитора.
Скорее всего в объекте 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

Пробным методом подобрал коэффициенты для своего монитора - диалог закрывает все окно монитора, кроме "Панели задач".