Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как написать Add-In или... большие мучения с маленькой программой.

© Михаил Эскин 2001 г
www.mik.h1.ru

Являясь расширяемой средой разработки программ, VB позволяет создавать приложения, используемые в нем самом. Для этого в нем существует т.н. интегрированная среда разработки, или проще IDE.

Вы, в своих приложениях, уже использовали такие надстройки (Add-In), например Class Builder Utility или Rtsource Editor. Программы, которые упрощают и облегчают работу программиста, избавляя его от написания часто повторяющегося однотипного кода. Когда Microsoft отдала "на откуп", сначала третьим фирмам, а затем и самим программистам создание надстроек, то в итоге - только выиграла. Нужно Вам специфическое приложение - создавайте его сами под себя. Что я, собственно говоря, и хочу продемонстрировать в данной статье.

Однако, прежде чем мы начнем, необходимо отметить некоторые сложности в создании надстроек:

  • Add-In это, в своей сущности, динамическая библиотека (DLL), написанная на VB. Поэтому, тестируемую надстройку надо запускать в одном приложении VB, а само тестирование проводить в другом.
  • По своей структуре, Add-In - это модуль класса и все, что мы объявим как Public, будет доступно нам в любой другой части приложения.
  • Наверно самое главное, мы должны будем написать два верных без ошибок :) кода: один для самой надстройки, а второй для того приложения, куда мы будем ее интегрировать.

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

Создадим новый проект, выбрав в диалоговом окне не Standard EXE, как это мы делаем обычно, а опцию Addin. Программа создаст Вам шаблон приложения, несколько отличный от того, к чему Вы привыкли, создавая стандартные программы. Да, здесь есть раздел Forms с "голой" формочкой, но, самое главное, появился новый раздел - Designers, с включенным в него объектом Connect.

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

  • Итак, две глобальные процедуры, руководящие открытием и скрытием основной формы надстройки (Show и Hide). Ничего сверхординарного, за исключением того, что используется скрытие формы, а не ее выгрузка, что создает определенные трудности. Выгрузка же производится только при отсоединении надстройки от проекта.
  • В разделе деклараций необходимо отметить несколько моментов:
    • В случае переименования отображаемой формы, не забудьте сделать соответствующую поправку в строке: Dim mfrmAddIn As New [НовоеИмяФормы]
    • Конечно же глобальная переменная VBInstance. Данная переменная объявлена как тип VBIDE.VBE и представляющая текущий экземпляр VB. Все дальнейшие обращения к к внутренней структуре текущего проекта осуществляются именно через данную переменную.
    • Переменная (Dim mcbMenuCommandBar As Office.CommandBarControl) открывает нам "доступ к телу" меню, позволяя не только считывать значения, но и манипулировать строками меню, как в своем приложении.
  • Следующие внутренние процедуры и функции руководят добавлением и удалением из меню VB имени нашей надстройки.

В большинстве случаев, того, что нам по умолчанию дает шаблон, вполне достаточно для работы. Однако это не значит, что мы не можем производить в нем изменения. Чуть позже мы вернемся к дизайнеру Connect для добавления некоторых своих процедур и корректирования существующих.

Итак, переименуем проект Name = SideMenu. Откроем Connect и внесем некоторые поправки, согласно представленного ниже рисунка.

Теперь наступило самое время научиться проводить тестирование нашей надстройки. Будем внимательны, ведь мы работаем непосредственно со средой VB!

  • Запустите еще один проект, теперь уже Standard Exe
  • Вернитесь в окно с нашей надстройкой и запустите ее на исполнение (F5)
  • Снова перейдите в тестировочный проект и выберите меню Add-Ins/Add-In Manager...



  • В открывшемся диалоговом окне найдите имя нашего проекта (в данном случае SideMenu) и установите опцию Loaded-Unloaded



  • Еще раз открываем меню Add-Ins и находим в подменю наше приложение. Открываем его.



  • На экране должно появиться наше рабочее диалоговое окно. Прекращение работы по нажатию соответствующей кнопки формы.

Для выхода из тестирования:

  • Выберем меню Add-Ins/Add-In Manager ... и отключим опцию Loaded/Unloaded с нашей надстройки. ОК.
  • Перейдем в рабочее окно VB с нашим приложением (надстройкой) и остановим его.

NB! Если выключить основное приложение, предварительно не выгрузив из тестировочного проекта ссылку на него, то там (в тестировочном проекте) останется меню нашего приложения (НЕРАБОТАЮЩЕЕ!). И при следующем тестировании ниже добавится идентичное меню (работающее).

Продолжим работу. Вернемся к форме frmAddIn. Расположим на ней элементы управления, примерно как на предложенном здесь рисунке.

По умолчанию в ней создается совсем немного кода: только для обработки нажатия клавиш. Займемся добавлением кода для добавления и удаления названий меню в листбокс (Name = lstMenu). Ничего принципиально сложного или нового в этих кодах нет. После проверки на допустимость добавляется или удаляется запись из листбокса. В событии Form_Load добавим информационный текст, выводимый на лейбле (Name = lblInfo).

Вернемся в Connect и добавим коды для обновления комбобокса (Name = cboForm) с перечнем форм. Все дело в том, что закрыв (но не выгрузив) наш плагин, мы только скрываем его (метод Hide). Поэтому, если была добавлена новая форма, то она в комбобоксе не отображается. Исправим это. Напишем процедуру AddInCombo, а затем вызовем ее в процедуре Show. Вначале объявим объектную переменную активного проекта и переменную количества компонентов (форм, модулей, модулей классов и т.п.) в этом проекте. Очистим комбобокс, а затем в цикле For...Next проверим эти компоненты. Если это форма - добавляем в комбобокс. В конце не забудьте освободить память, удалив временно созданные объекты.

Private Sub AddInCombo()

Dim thisProject As VBProject
Dim pComponents As Integer
Dim i As Integer

Set thisProject = VBInstance.ActiveVBProject
pComponents = thisProject.VBComponents.Count

mfrmAddIn.cboForm.Clear

For i = 1 To pComponents
    If thisProject.VBComponents.Item(i).Type = vbext_ct_VBForm Then
        mfrmAddIn.cboForm.AddItem thisProject.VBComponents.Item(i).Name
    End If
Next

On Error Resume Next
mfrmAddIn.cboForm.Text = mfrmAddIn.cboForm.List(0)

Set thisProject = Nothing

End Sub

Ну что ж, пора заняться основным кодом (то, что получается при нажатии кнопки ОК на форме frmAddIn).

Private Sub OKButton_Click()

Dim thisProject As VBProject
Dim thisForm As VBForm
Dim PanelMenu As VBControl
Dim ctrlMenu As VBControl
Dim mnuMenu As VBControl
Dim mnuSubMenu As VBControl
Dim thisCode As CodeModule
Dim i%, j%, NumOptExp%

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

If cboForm.ListCount = 0 Then
    MsgBox "Должна существовать хотя бы одна форма.", _
        vbInformation + vbOKOnly, "Ошибка!"
    Exit Sub
End If

If lstMenu.ListCount = 0 Then
    MsgBox "Необходимо создать, хотя бы одно меню.", _
        vbInformation + vbOKOnly, "Ошибка!"
    Exit Sub
End If

Screen.MousePointer = vbHourglass

If ErrName = False Then
    Exit Sub
End If

Далее инициализируем объекты текущего экземпляра VB: Проект и Текущую Форму (имя берется из комбобокса).

Set thisProject = VBInstance.ActiveVBProject
Set thisForm = thisProject.VBComponents.Item(cboForm.Text).Designer
Set PanelMenu = thisForm.ContainedVBControls.Add("PictureBox")

Дальнейшие действия представлены двумя блоками: добавление элементов управления на форму и добавление кода.

Для того чтобы добавить элемент на форму необходимо использовать метод (ни за что не догадаетесь об его имени :)) Add. После того как элемент добавлен, можно заняться установкой его свойств. Первым устанавливаемым элементом у нас будет PictureBox, который изобразит из себя панель меню, и явится контейнером для других ЭУ.

With PanelMenu
    .Properties("Name") = "picBack"
    .Properties("Align") = 3
    .Properties("AutoRedraw") = True
    .Properties("BorderStyle") = 0
    .Properties("ScaleMode") = 3
    .Properties("Width") = 375
End With

Для остальных элементов управления - принцип тот же самый. Единственное, что у нас добавится - это цикл For...Next, который повторяет данную операцию столько раз, сколько меню мы создаем.

For i = 0 To lstMenu.ListCount - 1
    Set ctrlMenu = PanelMenu.ContainedVBControls.Add("PictureBox")
    With ctrlMenu
        .Properties("Name") = lstMenu.List(i)
        .Properties("AutoRedraw") = True
        .Properties("BorderStyle") = 0
        .Properties("ScaleMode") = 3
        .Properties("Left") = 4
        .Properties("Height") = 33
        .Properties("Width") = 17
    End With

    Set mnuMenu = thisForm.ContainedVBControls.Add("Menu")
    With mnuMenu
        .Properties("Name") = lstMenu.List(i) & "1"
        .Properties("Caption") = lstMenu.List(i)
        .Properties("Visible") = False
    End With

    For j = 0 To 1
        Set mnuSubMenu = mnuMenu.ContainedVBControls.Add("Menu")
        With mnuSubMenu
            .Properties("Index") = j
            .Properties("Name") = "Sub" & lstMenu.List(i)
            .Properties("Caption") = "Sub" & lstMenu.List(i)
            .Properties("Visible") = True
        End With

    Next

Next

Получение доступа к кодам осуществляется идентично, т.к. модуль кода так же является объектом VB. Вначале необходимо найти "Option Explicit" (он может находиться не на первой строке) и после него вставить сформированный нами код. Выделим на поиск ... думаю 20 строк кода модуля достаточно.

Set thisCode = thisProject.VBComponents.Item(cboForm.Text).CodeModule
For i = 1 To 20
    If thisCode.Lines(i, 1) = "Option Explicit" Then
        NumOptExp = i + 1
        Exit For
    Else
        NumOptExp = 1
    End If
Next

Вставка кода осуществляется с помощью метода InsertLine, с параметрами: с какой строки начинать вставку текста (следующей после Option Explicit) и что именно вставлять.

thisCode.InsertLines NumOptExp, CodeText

Освобождаем память, уничтожая созданные в данной процедуре объекты. Set thisProject = Nothing Set thisForm = Nothing Set PanelMenu = Nothing Set ctrlMenu = Nothing Set mnuMenu = Nothing Set mnuSubMenu = Nothing Set thisCode = Nothing Screen.MousePointer = vbDefault

Выводим frmConfirm, с дополнительной поясняющей информацией и закрываем Connect.

frmConfirm.Show vbModal
Connect.Hide

End Sub

Я не буду подробно останавливаться на рассмотрении вставляемого кода (хотя он сам по себе достаточно интересен), так как это не является темой данной статьи. Отмечу лишь, что для формирования полноценного кода необходимо вначале в отдельном проекте создать то, что мы хотим в итоге получить. Отработать на предмет ошибок. Затем скопировать в свое приложение и заменить конкретные имена объектов на переменные. Подробный текст смотри в листинге.

В форме frmConfirm запишем выводимую информацию для пользователя. А кнопке запишем команду закрытия формы.

Протестируем наше приложение. Если забыли как это делается см. сюда.

Какую бы иконку нашему плагину мы не выставляли бы, в меню она не появляется. А хотелось бы. Выйдем из режима тестирования. Откроем редактор ресурсов и добавим битмап с картинкой нашей иконки размером 16 х 16 пиксель. Открытие редактора осуществляется так же через меню Add-Ins.

NB! Если Вы работаете в VB5, то такого редактора у Вас не будет. Придется идти на microsoft.com и искать там.

В Connect запишем необходимый код:

Function AddToAddInCommandBar(sCaption As String) As Office.CommandBarControl
...

cbMenuCommandBar.Caption = sCaption

'Код для картинки меню
cbMenuCommandBar.OnAction = "hello"
'copy the icon to the clipboard
Clipboard.SetData LoadResPicture(5000, 0)
'set the icon for the button
cbMenuCommandBar.PasteFace
'Конец вставляемого кода

Set AddToAddInCommandBar = cbMenuCommandBar
...

End Function

При повторном тестировании - все нормально.

У нас осталась только одна незадействованная кнопка - "О программе". Как-то Александр Климов, ведущий сайта "Русский_проект" сказал мне, что окно About, помимо общей текстовой информации, должно максимально отражать то, чему посвящена данная программа. Поэтому мы вместо кнопки "Выход" сделаем на окне frmAbout наше боковое меню. Сгенерируем код в тестировочном окне. Выйдем из режима тестирования и скопируем полученную форму в наш проект. В frmAddIn запишем код для кнопки cmdAbout.

Мы закончили создание Add-In'а для VB. Скомпилируем проект

NB! Если Вы переносите данный плагин (скомпилированный) на другой компьютер, не забудьте его зарегистрировать с помощью regsvr32.exe, или можно воспользоваться моей утилитой Reg.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
Аноним
Мне нравитсяМне не нравится
29 января 2005, 13:28:47
Вообще статья очень не плохая,толково все описано, жаль что не рассмотрен вопрос о вставлении кода в программу, сколько сам не ковырялся, не смог вставить строки в то место где курсор. Вообще, побольше бы таких статей, а то у начинающих как я, масса черных дыр.

Большое спасибо за помощь.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог