Возможно ли задать моноширинный шрифт для окна MsgBox() ?

Автор eeigor, 23 февраля 2021, 21:01

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

eeigor

Не хочется создавать своё окно, поскольку здесь, в отличие от MS Forms, ещё этого не делал.
Понадобилось отобразить некоторый служебный текст с комментарием справа от него в каждой строке.
Чтобы комментарии шли с вертикальным выравниванием, требуется задать моноширинный шрифт. Это возможно?

Произвольный учебный пример:
^\w+      # фамилия (с начала строки)
|         # или
(?<=\s).  # инициал после пробела (look-behind)

Вот, хочется, чтобы #comment был выровнен по вертикали. Ради этого готов установить полностью моноширинный шрифт для всего сообщения.

Upd1:
В MS Office я это сделал бы средствами ОС Windows, но у меня Linux, и я понятия не имею, как это делается.

Upd2:
Может, кто-нибудь уже решал задачу по замене окна? Какой-нибудь пример для старта...
Ubuntu 18.04 LTS • LibreOffice 7.3.5.2 Community

Bigor

Была тема про msgbox. Вы в ней отмечались, но может имеет смысл еще раз глянуть
Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

eeigor

#2
Но ведь окно должно расширяться. Или должна быть прокрутка текста в поле... Это всё реализуемо?

Upd:
Часть информации перенесена в отдельную тему.
Ubuntu 18.04 LTS • LibreOffice 7.3.5.2 Community

economist

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

eeigor

#4
@economist, спасибо большое. Неужели это то самое?.. Ведь вопрос был задан больше "на удачу". Буду разбираться и экспериментировать. Но при беглом чтении уловил, что, вроде, это то, что нужно... Совершенно неожиданно!!


To display a MessageBox with formatted text you could use the Xmessagebox interface, plus an injected RichText control to replace the normal plain text control.

Function MessageBox( strText$, Optional iMessageBoxType%, Optional strDialogTitle, Optional lMessageBoxButtons, Optional aTextPortionStyleProperties(), Optional lTextFieldWidth, Optional lTextFieldHeight, Optional rTextFieldFont, Optional lDialogPositionX, Optional lDialogPositionY, Optional lDialogBackgroundColor, Optional aButtonLabels(), Optional rButtonFont, Optional dButtonZoom, Optional iButtonPointer%, Optional oParentWindow As Object )

Используется элемент управления RichText.
Ubuntu 18.04 LTS • LibreOffice 7.3.5.2 Community

economist

Диалоги с этим модулем стали красивыми, но все-таки не идеальными. Нужно еще написать обертку над функцией, для удобства вызова.

Еще вариант - выводить в LO диалоги на TKinter из Python :-) Или PySimpleGUI (и еще пяток библиотек есть). Выглядят они необычно, но часто именно это и нужно.

Еще по идее можно использовать диалоги ОС Windows из gdlib32.  
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

eeigor

#6
Ещё раз спасибо.
На скриншоте то самое окно MessageBox() из примера по ссылке (#3), но первый сегмент (My name is) выведен шрифтом Liberation Mono (я задал другой FontDescriptor). В любом случае это хороший пример кода для самостоятельного изучения и более чем нужно в качестве "примера для старта", как я и просил... Самому мне такого не написать, но код, в целом, понятен. Единственное ограничение, как я понял, это то, что надо самостоятельно задавать размеры текстового поля под конкретный текст. В MsgBox() окно расширяется само.

Вот оно "слабое место":
REM  [OPTIONAL] <lTextFieldWidth> : Long integer holding the desired Width for our RichTextField; [DEFAULT]=350 pixels.
REM  [OPTIONAL] <lTextFieldHeight>: Long integer holding the desired Height for our RichTextField; [DEFAULT]=100 pixels.
Ubuntu 18.04 LTS • LibreOffice 7.3.5.2 Community

sokol92

Проще попросить разработчиков добавить для диалогов соответствующий элемент управления. ;D

Для решения же исходной задачи достаточно нескольких строк текста. Rami приводил на форуме замечательные примеры.
Владимир.

eeigor

Ubuntu 18.04 LTS • LibreOffice 7.3.5.2 Community

sokol92

Например, эта тема. Кроме того, обязательна к прочтению и разбору текста соответствующих макросов глава 18 книги OOME_4_0.odt.
Владимир.

eeigor

#10
Цитата: eeigor от 23 февраля 2021, 21:01Не хочется создавать своё окно, поскольку здесь, в отличие от MS Forms, ещё этого не делал.
Видимо, придётся. Вообще, материала очень много. Хотелось бы, чтобы окно было расширяемым (об этом пишут здесь и тут).


Цитата: sokol92 от 25 февраля 2021, 20:08...глава 18 книги OOME_4_0.odt.
Или глава 17 в книге Питоньяка на русском. Кого заинтересует.

Цитата: sokol92 от 25 февраля 2021, 15:54Для решения же исходной задачи достаточно нескольких строк текста.
Конечно, не всё так радужно.
Разберусь если, тогда добавлю результат в эту тему (для сравнения).
Ubuntu 18.04 LTS • LibreOffice 7.3.5.2 Community

sokol92

Даже интересно стало - написал пример для расширяемого окна с моноширинным шрифтом.
Можно задать автоподбор ширины окна (по самой длинной строке текста) и высоты. На моих тестах подбор происходит аккуратно.
Для простоты используется статический диалог "Msgbox" из документа, хотя нетрудно его создать и динамически. Стартовый макрос - TestMyMsgBox.

Option Explicit
Option Compatible

' Макросы для отображения текста в диалоге.

' --------------------------------------------------------------------------------
' Возвращает объект для диалога.
' Параметры:
' oDoc документ (для диалогов приложения указывать при вызове GlobalScope).
' libName имя библиотеки.
' dlgName имя диалога.
Function GetDialog(Byval oDoc, ByVal libName As String, ByVal dlgName As String)
  Dim oDialog
  On Local Error GoTo ErrLabel
  With oDoc.DialogLibraries
    .loadLibrary(libname)
    oDialog=CreateUnoDialog(.getByName(libName).getByName(dlgName))
  End With
  GetDialog=oDialog 
ErrLabel:
End Function

' --------------------------------------------------------------------------------
' Вызывает диалог Msgbox из библиотеки Standard.
' oDoc документ (для диалогов приложения указывать при вызове GlobalScope).
' Параметры:
' message сообщение.
' title заголовок сообщения.
' width  ширина для Text (>0). 0: автоподбор ширины, -1: не менять.
' height высота для Text (>0). 0: автоподбор высоты, -1: не менять.
Sub MyMsgbox(Byval oDoc, ByVal message As String, ByVal Title As String, _
             Optional ByVal width As Long, Optional ByVal height)
  Dim oDialog, oDialogModel, oControl, size As New com.sun.star.awt.Size
  Dim nCols As Integer, nRows As Integer
  Dim arr, lMax As Long, v, oldVal As Long, i As Long, rows As Long
  Dim wMax As Long, hMax As Long    ' наибольшие ширина и высота для Text.
  If IsMissing(width) Then width=0
  If IsMissing(height) Then height=0
  With CreateUnoService("com.sun.star.awt.Toolkit").WorkArea
    size.width=.width : size.height=.height - 60
  End With 
  oDialog=GetDialog(oDoc, "Standard", "Msgbox")
 
  With oDialog
    oControl=.getControl("Text")
    oDialogModel=.getModel
    size=.convertSizeToLogic(size, 17)
    wMax=size.width
    hMax=size.height
   
    With .getControl("Text").getModel
      If width=0 Then   ' автоподбор ширины
        oldVal=.width
        width=.width
        wMax=wMax - oDialogModel.width + .width
        arr=Split(message, Chr(10))
        lMax=Len(Title)
        For Each v In arr
          If len(v)>lMax Then lMax=len(v)
        Next v
        oControl.getColumnsAndLines nCols, nRows 
        If lMax> nCols Then width=Fix(.width * Cdbl(Lmax) / nCols)
        If width>wMax Then width=wMax
        .width=width
        Do While width<=wmax-5
          oControl.getColumnsAndLines nCols, nRows
          If lMax<=nCols Then Exit Do
          width=width+5
          .width=width
        Loop 
        oDialogModel.width=oDialogModel.width + width - oldVal
      End If  ' автоподбора ширины
     
      width=.width
      If height=0 Then  ' автоподбор высоты
        oldVal=.height
        height=.height
        oControl.getColumnsAndLines nCols, nRows               
        hMax=hMax - oDialogModel.height + .height
        If Not IsArray(arr) Then arr=Split(message, Chr(10))
        rows=0   ' счетчик строк message с учетом переносов
        For Each v In arr
          rows=rows + WrapRows(v, nCols)
        Next v
       
        If rows>nrows Then height=Fix(.height * Cdbl(rows) / nRows)
        If height>hMax Then height=hMax
        .height=height
        Do While height<=hMax-5   ' не хватает
          oControl.getColumnsAndLines nCols, nRows
          If rows<=nRows Then Exit Do
          height=height+5
          .height=height
        Loop
       
        Do While height>=oldval + 5 ' убираем лишнее
          height=height-5
          .height=height
          oControl.getColumnsAndLines nCols, nRows
          If rows>nRows Then Exit Do
        Loop
        height=height+5 
        .height=height 
        oDialogModel.height=oDialogModel.height + height - oldVal
      End If  ' автоподбора высоты
     
      .Text=message
      .ReadOnly=True
    End With
   
    .setTitle title
    .Execute
  End With 
End Sub

' Возвращает число строк при переносе строки s по словам по ширине w
Function WrapRows(ByVal s As String, ByVal w As Long) As Long
  Dim i As Long
  WrapRows=1
  Do While Len(s)>w  ' i - позиция последнего пробела до позиции w
    WrapRows=WrapRows+1
    i=w
    Do While i>0
      If mid(s, i, 1)=" " Then Exit Do
      i=i-1
    Loop
    If i=0 Then i=w+1
    s=Mid(s, i+1)
  Loop   
End Function

' --------------------------------------------------------------------------------
' Тест для MyMsgbox
Sub TestMyMsgbox
  Dim oDoc, s As String
  oDoc=ThisComponent
  s=oDoc.BasicLibraries.getByName("Standard").getByName("ModDialog")
  MyMsgbox oDoc, s, "Модуль ModDialog"
  MyMsgbox oDoc, Left(s, 1000), "Модуль ModDialog (начало)"
  MyMsgbox oDoc, Left(s, 1000), "Модуль ModDialog (начало), ширина 100", 100
End Sub
Владимир.

eeigor

#12
@sokol92, материала достаточно. Мне надо просто изучить новую здесь для меня тему диалогов. Это потребует времени. Эта ветка была полезной для меня.
Спасибо за пример.
Ещё раз убеждаюсь, что здесь собралась хорошая компания  :)
Ubuntu 18.04 LTS • LibreOffice 7.3.5.2 Community