| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() |
Как создать ActiveX Control - 7
В данной статье описывается создание массивов в ActivX 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). Определимся со свойствами, методами и событиями. Свойства
Методы:
События: 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
За листингом сюда. [Назад][Содержание][Вперед] |
|
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
|