четверг, 14 февраля 2013 г.

Динамическое меню (продолжение)

Оказывается, что формировать ленту на лету не только можно, но и чрезвычайно полезно.
Я решил, по примеру Антона Кокина сделать свое меню для работы с закладками, только в версии для Word2007.
Сказано — сделано.
Вот что получилось:

При добавлении закладки в документ меню обновляется и имя закладки появляется внизу списка. Щелчок на имени приводит к переходу на эту закладку. В подменю «Управление закладками» появляются пункты, позволяющие удалить нужную закладку. Например, вот так:

Для того, чтобы все это работало, следует выполнить несколько простых шагов:

  1. Создать динамическое меню в схеме документа при помощи RibbonXMLEditor

  2. В этом меню определить макрос, который отвечает за наполнение меню содержимым

  3. Написать сам макрос в документе, или, что намного лучше, в шаблоне.

Следует заметить, что динамическое меню получает свое содержимое при первом щелчке на нем, что может вызывать определенные задержки при большом количестве закладок или на слабой машине. А я-то думал, почему так долго открываются стандартные меню-галереи? А ведь они обновляются при открытии.

В шаблоне, где мы делаем все манипуляции с ленточным интерфейсом, пишем код макроса DynMenuGetBookmarks_GetContent. Код этот довольно сложен для восприятия с первого раза, но, разобравшись, он не представляет трудностей.
Sub DynMenuGetBookmarks_GetContent(control As IRibbonControl,ByRef content)
 '
 'Формирование меню с закладками документа
 '
 Dim sXML As String
 Dim i As Integer
 Set bm = ActiveDocument.Bookmarks
 sXML = "" & vbCr
 '--------------------------
 'Кнопка «Обновить»
 '--------------------------
 sXML = sXML & _
 "" & vbCr
 '--------------------------
 'Разделитель
 '--------------------------
 sXML = sXML & _
 "" & vbCr
 '--------------------------
 'Кнопки с именами закладок
 '--------------------------
 If bm.count = 0 Then
  sXML = sXML & _
  ""
 'возвращаем значение в компонент
End Sub

Как видно первой создается кнопка «Обновить» и для нее назначается макрос RefreshDynMenu_OnAction, который обновляет меню.
Sub RefreshDynMenu_OnAction(control As IRibbonControl)
'Обновление динамического меню'
  CustomRibbon.Invalidate
End Sub

При удалении закладки меню обновляется автоматически, но не без нашего участия. Чтобы эта автоматика работала, мы при создании меню «Управление закладками» создаем кнопки, которые отвечают за удаление той или иной закладки. Имя закладки пишем в свойство tag. Удаление закладки происходит при выполнении макроса delbm_onAction
Public Sub delbm_onAction(control As IRibbonControl)
'
'Удаление закладки при выборе ее в соответствующем меню
'
  bm.Item(control.Tag).Delete
  CustomRibbon.Invalidate
End Sub

Также при выполнении макроса GoToBookmark осуществляется переход к выбранной закладке.
<
Sub GoToBookmark(control As IRibbonControl)
'
'Переход к закладке
'
  On Error Resume Next
  Selection.GoTo What:=wdGoToBookmark, Name:=control.Tag
  If Err.Number <> 0 Then
    MsgBox "Не удалось перейти к закладке «" & control.Tag & "»", vbOKOnly
  End If
End Sub
>
Для добавления закладки вызывается стандартный диалог работы с закладками
Public Sub menu_AddBookmark_onAction(control As IRibbonControl)
'
'Появление окна для добавления закладки в документ
'
  Dialogs(wdDialogInsertBookmark).Show
  CustomRibbon.Invalidate
End Sub

При любых действиях с закладками вызывается метод CustomRibbon.Invalidate, который обновляет содержимое ленты.
С закладками получилось все довольно просто. Теперь другая задача стоит: как сформировать динамическое меню из доступных для выполнения макросов, которые можно запустить через стандартное диалоговое окно по Alt+F8? Сразу скажу, что в черновом варианте эту задачу я уже решил. Подробности далее в публикациях.

1 комментарий :

Антон Кокин комментирует...

Александр, хорошо было бы, если бы вы выложили к этим заметкам и свои файлы, чтобы можно было увидеть вживую результат.