ActiveX

Урок 7

 Создание массивов в ActiveX Control'е

 

На этом уроке создаем комбинированный ActiveX Control. Напомню: это контрол, состоящий из уже готовых контролов. Особенностью сегодняшнего (это будет кнопка с выпадающим меню) будет наличие массивов в нем. Сделать это в форме не представляет особого труда, но создавая контрол, мы обязаны предусмотреть ряд ситуаций, которые в обычном проекте отрабатываются автоматически и поэтому не обращают на себя Вашего внимания.

Создадим новый проект  с названием ButtonMenu и присвоим имя для UserControl'a - ButtMenu. Разместим на нем кнопку (Name - cmdButtMenu, Caption - "ButtonMenu"). Вызовем Редактор меню Tools/Menu Editor... Введем 2 записи: для меню (Name = mnuGeneral, Caption = "mnuGeneral" - хотя это и не принципиально, имя здесь дано, чтобы не было пустой строки, Index = [Пусто], Checked = False, Enabled = True, Visible = False) и подменю (Name = mnuMenu, Caption = "#", Index = 0, Checked = False, Enabled = True, Visible = True).

Определимся со свойствами, методами и событиями.

Свойства

Имя

Описание

Тип

Значение по умолчанию

BackColor

Цвет кнопки

OLE_COLOR

&H8000000F

Caption

Надпись на кнопке

String

"ButtonMenu"

Font

Шрифт надписи

Font

MS Sans Serif, 8

 

Методы:

Имя

Принимаемые параметры

Описание

AddMenu

sCaption As String

Добавляет новые строки меню

 

События: Click, MouseDown, MouseMove, MouseUp

Введем эти свойства с помощью мастера.

 

NB! Если Вы программируете в VB5, сразу же исправьте ошибочные записи, сделанные мастером в UserControl_ReadProperties и UserControl_WriteProperties, соответственно:

Set cmdButtMenu.Font = PropBag.ReadProperty("Font", Ambient.Font) и

Call PropBag.WriteProperty("Font", cmdButtMenu.Font, Ambient.Font)

Другие свойства и событие введем позже, вручную в окно кодов. Это как раз тот случай, когда переделывать за мастером - себе накладней.

Создадим масштабируемость контрола.

Private Sub UserControl_Resize()

    cmdButtMenu.Move 0, 0, ScaleWidth, ScaleHeight

End Sub

Займемся подробнее методом AddMenu:

Public Sub AddMenu(sCaption As String)

    Dim iCount%

    'проверяем количество меню, имеющихся в настоящий момент у контрола

    iCount = mnuMenu.Count

    'загружаем данные и показываем меню. Отнимаем 1, т.к. индекы меню начинаются с 0.

    mnuMenu(iCount - 1).Caption = sCaption

    mnuMenu(iCount - 1).Visible = True

    'загрузка следующего меню, но невидимого. Данное действие пришлось :( использовать,

    ‘т.к. mnuMenu с индексом 0 у нас изначально грузится.

    Load mnuMenu(iCount)

    mnuMenu(iCount).Visible = False

End Sub

В принципе, желающие могут расширить этот метод примерно так:

Public Sub AddMenu(sCaption As String, Optional bChecked As Boolean, _

Optional bEnabled As Boolean, Optional bVisible As Boolean)

но тогда не забудте в теле метода прописать эти установки.

Теперь пару слов насчет метода RemoveMenu. Лично мне кажется, что данный метод будет использоваться крайне редко (это же не ListBox или ComboBox), а заниматься переиндексацией меню и отслеживать потом в командах… Поэтому я его не объявляю. Лучше я использую свойство Visible для данного меню. Но это ни в коем случае не ограничивает Вас – экспериментируйте!

Переходим к событиям: MouseDown, MouseMove, MouseUp –оставим без изменений, как их создал мастер. А вот в событие Click внесем поправку.

Private Sub cmdButtMenu_Click()

    RaiseEvent Click

    ‘ эту проверку вставляем на случай отсутствия меню, тогда наше mnuMenu(0) – уже

    ‘ загруженное, но пустое не будет появляться и контрол будет работать как обычная кнопка.

    If mnuMenu.Count > 1 Then

        ‘ на 60 твипов сдвигаем влево чисто с эстетическими побуждениями

        PopupMenu mnuGeneral, , 60, ScaleHeight

    End If

End Sub

Создадим новое событие, реагирующее на щелчок по меню – ClickMenu:

В разделе General объявим его: Event ClickMenu(Index As Integer), а ниже запишем:

Private Sub mnuMenu_Click(Index As Integer)

    RaiseEvent ClickMenu(Index)

End Sub

Напоследок займемся теми методами из-за которых, собственно говоря, и писалась эта статья. Это методы: MenuCaption, MenuChecked, MenuEnabled, MenuVisible. Полностью я их все расписывать не буду (для этого существует Листинг), а покажу на примере одного.

И в Property Get и в Property Let в скобках делаем ссылку на Index элемента. В остальном все то же самое.

Public Property Get MenuCaption(Index As Integer) As String

    MenuCaption = mnuMenu(Index).Caption

End Property

 

Public Property Let MenuCaption(Index As Integer, ByVal New_MenuCaption As String)

    mnuMenu(Index).Caption = New_MenuCaption

    PropertyChanged "MenuCaption"

End Property

А вот в UserControl_ReadProperties строка будет озвучиваться несколько по-иному (не забудьте вначале объявить переменную Index):

mnuMenu(Index).Caption = PropBag.ReadProperty("MenuCaption" & Index, vbNullString)

и в UserControl_WriteProperties соответственно:

Call PropBag.WriteProperty("MenuCaption" & Index, mnuMenu(Index).Caption, vbNullString)

Заметили хитрость? Здесь я считываю и записываю не в свойство MenuCaption, а в свойства MenuCaption0, MenuCaption1 и т.д. – столько, сколько у нас меню.

 

И теперь немного кода для тестировочного проекта – как это все работает.

 

Option Explicit

 

Private Sub Form_Load()

    ButtMenu1.AddMenu "Checked"

    ButtMenu1.AddMenu "Enabled"

    ButtMenu1.AddMenu "Visible"

    ButtMenu1.AddMenu "-"

    ButtMenu1.AddMenu "Восстановить"

    ButtMenu1.AddMenu "-"

    ButtMenu1.AddMenu "Выход"

End Sub

 

Private Sub Form_Click()

    ButtMenu1.Font.Bold = True

    ButtMenu1.Caption = "Новое имя"

End Sub

 

Private Sub ButtMenu1_ClickMenu(Index As Integer)

Select Case Index

Case 0

    ButtMenu1.MenuChecked(Index) = Not ButtMenu1.MenuChecked(Index)

Case 1

    ButtMenu1.MenuEnabled(Index) = False

Case 2

    ButtMenu1.MenuVisible(Index) = False

Case 4

    ButtMenu1.MenuEnabled(1) = True

    ButtMenu1.MenuVisible(2) = True

Case 6

    End

End Select

End Sub

 

За листингом сюда.

Ñêà÷àòü ïðèìåð

 Назад

 1999

Hosted by uCoz