Когда Вы работаете с Visual Basic, вы используете разные готовые элементы - ComboBox, Таймер и т. д. Они расположены на панели инструментов.
Так вот, вы можете не только использовать встроенные элементы, но и делать свои. Именно они и называются ActiveX-элементы, и именно их мы и научимся делать.
ActiveX-элементы не зависят от языка программирования. Вы можете написать ActiveX на Visual C++ или на Visual Basic, и затем использовать в Delphi или в Internet Explorer. Все современные языки программирования поддерживают ActiveX. Всё это относится вообще-то к более обширной теме COM-технологий.
Запускаем Visual Basic. В появившемся диалоге New Project выбираем ActiveX Control (если диалог не появился при запуске Visual Basic'а, то выбирем меню File->New Project).
На экране появится UserControl1, у которого вы сразу для удобства уменьшите размеры
UserControl - это как бы форма, только не для программы, а для ActiveX-элемента. Именно на ней мы и будем создавать наш ActiveX - создавать его внешний вид. При этом мы можем пользоваться как готовыми другими элементами, так и рисовать с нуля. Потом этот UserControl с созданным ActiveX на нём мы будем располагать на обычных формах Visual Basic'а.
Обратите внимание на то, что в проекте у нас UserControl обозначен особым значком
В качестве первого ActiveX мы сделаем квадратик, для которого мы сможем задать цвет (красный или синий). Это будет свойство. Кроме того мы добавим для него метод, меняющий цвет на противоположный. И, наконец, при щелчке левой кнопкой мыши на нашем квадратике наступит наше событие MyClick. Его мы тоже сделаем, и тогда тот, кто будет использовать этот ActiveX, сможет в обработчике этого события написать любой код.
Сейчас мы добавим свойство к нашему ActveX-элементу.
Сначала определим внутреннюю переменную, ответственную за цвет. Но цвета нас всего два, так что лучше всего сначала ввести новый тип MyColor, и затем завести переменную такого типа:
Option Explicit
Public Enum MyColor
'перечисление
Red = 1
Blue = 2
End Enum
Private m_blnColor As MyColor
Переменную мы завели как Private. Снаружи она видна не будет. Но нам нужен доступ к ней. Для этого пишем слудующий код:
Public Property Let Color(NewColor As MyColor)
m_blnColor = NewColor
End Property
Public Property Get Color() As MyColor
Color = m_blnColor
End Property
Эти два метода уже у нас Public. Имя, под которым наше свойство будет видно снаружи, можно взять любое. Мы взяли Color. Первый из этих методов служит для записи свойства Color для нашего ActiveX-элемента, второе - для его чтения.
В принципе можно было и не возиться с методами Property Get и Set, а просто объявить переменную m_blnColor как Public. Но это было бы не очень хорошо. По правилам объектно-ориентированного программирования переменные внутри объекта болжны быть закрытыми, и доступ к ним должен быть через специальные методы. Как мы и сделали.
Теперь добавим тестовый проект. Почему? Потому что ActiveX-элемент не может существовать сам по себе. Он существует на чём-то (на форме, например). Поэтому то для испытаний нам и нужен тестовй проект.
Зайдите в меню File и выберите Add Project
В появившемся диалоге выберите Standard EXE.
Обратите внимание, что в окне проекта добавится еще один обычный проект
Сейчас мы сделаем наш тестовый проект главным. Это означает, что именно он будет запускаться при компиляции (т. е. при нажатии F5). Для этого щелкните на его имени правой кнопкрй мыши и в контекстном меню выберите Set as Start Up.
Теперь наш тестовый проект главный. Об этом говорит то, что он обозначен полужирным шрифтом.
Обратите внимание, что на панели элементов добавился наш элемент
Теперь щелкните на тестовой форме Form1, так, чтобы она расположилась сверху всех окон и затем двойным щелчком на нашем ActiveX'е на панели элементов расположите на форме наш новый элемент.
Выделите его на форме и обратите внимание, что в окне свойств есть наше свойство Color, причем для него можно выбрать только два значения
Сейчас мы с вами посмотрим, как Visual Basic позволяет работать с несколькими проектами. Сейчас у нас два проекта - в одном мы конструируем наш ActiveX, и в другом мы его испытываем. При этом мы постоянно вносим изменения в ActiveX-проект, и хотим, чтобы они отражались в тестовом проекте.
Давайте внесем некоторые изменения в код нашего ActiveX'а. Вспомним, что мы хотели, чтобы его цвет был красным или синим в зависимости от его свойства Color. Сейчас такое свойство есть, но оно ни как неотражается на внешнем виде элемента. Изменим это. Для сего внесите следующие изменения в код:
Public Property Let Color(NewColor As MyColor)
m_blnColor = NewColor
If NewColor = Red Then
UserControl.BackColor = vbRed
Else
UserControl.BackColor = vbBlue
End If
End Property
Здесь мы анализируем, что за цвет задан в качестве параметра, и устанавливаем его в качестве цвета для формы.
Смотрим теперь, как внесённый код отразится на нашем тестовом проекте. В окошке проекта делаем двойной щелчок на форме тестового проекта Form1.
Появляется наша тестовая форма. Но на ней наш элемент будет заштрихованным. Это означает, что сейчас мы с ним работать не можем.
Для того, чтобы изменить ситуацию, закройте окошко UserControl1 в проекте с разрабатываемым ActiveX-элементом. Теперь на тестовой форме наш ActiveX уже без штриховки.
Кстати, на панели элементов у нас было тоже самое - пиктограмма для нашего элемента сначала была серая
а затем стала нормальной
Таким образом для работы с тестовым проектом вы должны закрыть форму с разрабатываемым ActiveX-элементом.
Можете сейчас запустить тестовый проект, нажав F5. Должна появится форма с цветным прямоугольником на ней.
Добавим теперь к нашему ActiveX метод. Наш метод будет устанавливать цвет. Для добавления метода внесите следующий код в наш ActiveX-элемент (но не в код тестового проекта. Не перепутайте!):
Public Sub SetColor(NewColor As MyColor)
'устанавливаем новый цвет
m_blnColor = NewColor
'изменяем цвет элемента
If NewColor = Red Then
UserControl.BackColor = vbRed
Else
UserControl.BackColor = vbBlue
End If
End Sub
Мы объвили наш метод как Public. Т. е. он будет виден снаружи.
Давайте испытаем его в тестовом проекте. Сделайте тестовый проект активным, добавьте на него кнопку и в коде этой кнопки напишите следующий код:
Private Sub Command1_Click()
UserControl11.SetColor Blue
End Sub
Т. е. при нажатии на наше кнопку цвет элемента станет синим. Запустите тестовый проект и убедитесь, что при щелчке на кнопке ActiveX становится синим.
Обратите внимание, что наш метод появлялся в подсказке для нашего кода
Когда вы работаете с несколькими проектами, то Visual Basic создает файл группы проектов. У этого файла расширение *.vbg (Visual Basic Group)
Когда вы хотите открыть в Visual Basic группу проектов, то вы должны сделать в Проводнике Windows двойной щелчёк именно на файле группы (с расширением *.vbg).
Группу проектов вы используете когда вам надо одновременно работать с несколькими проектами. Например один с разрабатываемым ActiveX'ом, а другой тестовый, как у нас.
Посмотрим теперь, как мы можем добавить событие к нашему ActiveX'у.
Для этого, во-первых, мы должны в коде нашего ActiveX'а соответствующее событие объявить:
Option Explicit
...
Event MyClick()
Теперь нам надо указать, когда это событие возникает. Мы хотим чтобы оно возникало при щелчке на нашем ActiveX'е. Но его-то мы рисуем на UserControl. А у UserControl есть уже событие Click
Им-то мы и воспользуемся. Добавьте следующий код для ActiveX-элемента:
Private Sub UserControl_Click()
RaiseEvent MyClick
End Sub
Строка RaiseEvent MyClick говорит, что в этом месте должно возникнуть событие MyClick, которое мы ввели для нашего ActiveX'а. Обратите внимание, что при написании этого кода у нас возникла подсказка
Подсказка возникла, естественно, потому, что мы это событие в нашем ActiveX'е объявили.
Все, теперь у нашего ActiveX'а есть событие. Проверим это в тестовом проекте. Перейдите в код для тестового проекта и убедитесь, что событие MyClick присутствует
Напишите теперь для события MyClick тестового проекта следующий код:
Private Sub UserControl11_MyClick()
MsgBox "Возникло событие MyClick"
End Sub
Запустите тестовый проект (клавиша F5). При щелчке на нашем прямоугольнике возникает соответствующий MessageBox
И в обработчике для события MyClick можно написать всё, что угодно. Это уже не код ActiveX'а, а код программы, его использующей. Мы делаем это точно также, как и для, скажем, события Click для обычной кнопки - что хотим, то и пишем.
Настало время откомпилировать наш ActiveX-элемент. После компиляции мы получим файл с расширением *.ocx. Его уже можно распространять и по другим компьютерам. Так что воспользоваться нашим ActiveX'ом можно будет и в других программах.
Компиляцию делаем естественным образом. Заходим в меню File, далее выбираем Make имя_проекта.ocx
Проследите только, чтобы из двух проектов - основного и тестового - был активен именно основной (тот, в котором мы и конструируем наш ActiveX). Иначе указанного пункта меню в нем не будет.
После компиляции в указанной вами при этом папке появится файл с откомпилированнным ActiveX-элементом. По размеру он будет не слишком большой, но он будет требовать присутствия на компьютере файла MSVBVM60.DLL. Этот файл требуют все программы, скомпилированные с помощью Visual Basic (версии 6). Он довольно-таки большой (больше 1 Мб), но почти на всех компьютерах с Windows присутствует. Но его может и не быть. Тогда ваш ActiveX работать не будет.
Все бы сейчас с нашим ActiveX хорошо, но вот беда - он не сохраняет свои свойства. Например, вы в тестовом проекте можете задать свойство Color равным Blue. Цвет нашего прямоугольника станет синим. Но как только мы запустим тестовую программу, то он опять будет красным. Кроме того, при закрытии тестовой программы (т. е. при возврате в режим разработки) наш прямоугольник опять будет красным. Сейчас мы посмотрим, как с этим бороться.
Для этого у нас существует объект такого типа как PropertyBag. Он служит как бы промежуточным хранилищем между двумя экземплярами нашего ActiveX-элемента - экземпляром этапа разработки и экземпляром этапа выполнения (это разные экземпляры!). Добираемся мы до него через UserControl, точнее через его события WriteProperties и ReadProperties
Внесите в них следующий код:
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
m_blnColor = PropBag.ReadProperty("Color", Red)
If m_blnColor = Red Then
UserControl.BackColor = vbRed
Else
UserControl.BackColor = vbBlue
End If
End Sub
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "Color", m_blnColor, Red
End Sub
Прокомментируем его. Событие WriteProperties служит для записи свойств в объект типа PropertyBag. В качестве параметра в него передается объект PropBag типа PropertyBag. У этого объекта есть несколько методов. Один из них - WriteProperty - как раз и используется для записи некоторого свойства в PropertyBag. Это мы делаем в строке
PropBag.WriteProperty "Color", m_blnColor, Red
У этого метода два параметра: первый - имя параметра (Color), второй - записываемое значение и третий (необязательный) - значение по умолчанию.
Для чтения нам надо использовать событие ReadProperties нашего UserControl. Здесь все аналогично, только кроме чтения значения для цвета мы ещё пишем код для отображения цвета фона для нашего прямоугольника.
Сейчас вы можете менять в тестовом проекте значение свойства Color, и при запуске программы цвет будет отображаться именно выбранным вами значением. И даже если вы выйдите из VB, и потом опять откроете наш тестовый проект, то значение для свойства Color будет именно то, которое вы выбрали!
Когда вы размещаете некоторый стандартный элемент на форме, то части свойств присваивается значение по умолчанию (например, высота и ширина для кнопки). Для создаваемого нами элемента это не так (пока не так). Скажем, если мы разместим на тестовой форме наш ActiveX, то его свойству Color автоматически никакого значения не присвоится
Давайте изменим эту ситуацию. Для этого воспользуемся событием InitProperties для нашего ActiveX. Пишем в него следующий код:
Private Sub UserControl_InitProperties()
m_blnColor = Red
End Sub
Теперь при размешении на тестовой форме нашего ActiveX'а автоматически присвоится нужное свойство
При этом обратите внимание, что наш событие InitProperties воазникнет только один раз - а именно при размешении элемента на форме. При запуске программы, а также при повторном открытии проекта это событие возникать не будет. И это правильно - представьте себе, что оно возникало бы при каждом создании ActiveX'а (как вы помните, когда вы запускаете программу, то экземпляр ActiveX'а времени разработки умирает и создается новый экземпляр времени выполнения). Тогда, например, наш элемент всегда был бы красным, а это мы вовсе не хотим.
Есть и событие, которое возникает каждый раз при создании нового экземпляра ActiveX. Но об этом - в следующем уроке.
Если событие InitProperties для элемента ActiveX выполняеся только в момент первого создания элемента на форме, то событие Initialize имеет место каждый раз при создании экземпляра ActiveX-элемента. Говоря человеческим языком, это означает, что событие Initialize будет происходить по крайней мере в трех случаях:
Во-первых, в момент переноса ActiveX-элемента с панели элементов на форму.
Во-вторых, в момент запуска формы с ActiveX'ом.
И в-третьих, после закрытия тестовой формы и возврату к экземпляру ActiveX-элемента времени разработки.
Для того, чтобы посмотреть, как все это работает, добавьте в код нашего ActiveX следующие строки:
Private Sub UserControl_Initialize()
Beep
End Sub
Запустите тестовый проект. В момент появления формы на экране раздастся Beep. Закройте форму. Опять вы услышите Beep (так как экземпляр ActiveX времени выполнения умер и создался экземпляр времени разработки). Создайте на форме ещё один ActiveX-элемент. Опять будет Beep. Закройте нашу группу проектов и откройте её опять. И в этом случае опять будет Beep.
Таким образом, код, помещённый в событие Initialize будет выполняться каждый раз, когда наш ActiveX создаётся.
В этом уроке мы посмотрим, как использовать Control Interface Wizard. Эта утилита предназначена для построения заготовок для ActiveX-элементов. В этом уроке мы сделаем ActiveX, который будет запоминать, сколько раз на нем щелкнули. При первых трёх щелчках будет возникать событие Click, при дальшейших щелчках - NoClicks (последнее событие определено нами). Из свойств мы добавим свойство Clicks, которое будет считать число щелчков на нашем элементе. Это свойство на этапе времени выполнения будет доступно только для чтения. И, наконец, из методов мы добавим метод SetZero, который будет обнулять число щелчков. Таким образом мы с помощью мастера добавим и свойство, и метод и событие.
Запускаем Visual Basic. По умолчанию эта утилита не запущена. Для запуска выберите меню Add-Ins
В появившемся диалоге Add-Ins Manager выберите VB 6 ActiveX Ctrl Interface Wizard
Поставьте галочку рядом с Loaded/Unloaded. При желании можете поставить и галочку Load on Startup (если хотите, чтобы этот мастер загружался каждый раз вместе с Visual Basic)
После нажатия на OK в меню Add-Ins появится пункт ActiveX Control Interface Wizard
Выберите этот пункт меню. Появится мастер. Первый экран можете прочитать, а можете и не читать (ничего особо интересного там нет, так что в нем можно сразу поставить галочку Skip this screen in the future). Нажимаем Next. Появится экран мастера, в котором Вы должны задать, какие свойства, методы и события будут в вашем ActiveX элементе из стандартных
Часть из них уже по умолчанию включена в ваш ActiveX (они находятся в правом списке). Если вы хотите что-нибудь добавить или убрать, то понажимайте на кнопочки < и >. Нажимаем Next. Появляется следующее окно. В нем мы добавляем для нашего ActiveX нестандартные свойства, методы и события. Для их добавления нажмите на кнопку New
Появится окно Add Custom Member.
Давайте в нем добавим свойство Clicks, метод SetZero и событие NoClicks, после чего нажмите OK. В окне мастера должны появится введенные вами методы, свойства и события
Опять нажимаем на Next. В следующем окне мастера нам придется остановиться. В нем мы должны определить, какие из свойств, методов и событий нашего ActiveX будут проектироваться на стандартные свойства UserControl'а (того, который служит базой для нашего элемента ActiveX). В большинстве случаев рекомендуется действовать так - выделить в левом списке всё, кроме добавленных нами свойств, событий и методов, затем в ComboBox Control выбрать UserControl. Но мы в целях эксперимента будем действовать не так. Указанную процедуру мы применим только для элементов списка Click, MouseDown, MouseMove, MouseUp. Потом посмотрим, на что повлияет наш выбор. Итак, выделите слева указанные элементы списка и выберите справа UserControl
Нажмите Next. В следующем окне мастера нам надо задать различные параметры для свойств, методов и событий нашего ActiveX. Для свойства Clicks выберите тип Integer, значение по умолчанию 0, и определите, что во время выполнения это свойство доступно только для чтения
Для метода SetZero установите тип возвращаемого значения в Variant. Это будет означать, что метод этот будет процедурой (если тип возвращаемого значения не Variant, то это будет функцией)
После этого нажимаем на Finish, затем читаем Summary и переходим к следующему уроку. Там мы уже будем разбираться с тем, что нам мастер написал.
Продолжаем прошлый урок. Давайте посмотрим, что за код породил мастер.
Следующие строки говорят нам о том, что в нашем ActiveX-элементе будут события Click, KeyDown, KeyPress и KeyUp (именно их мы и указали в Control Interface Wizard):
...
Event Click()
'MappingInfo=UserControl,UserControl,-1,Click
Event KeyDown(KeyCode As Integer, Shift As Integer)
'MappingInfo=UserControl,UserControl,-1,KeyDown
Event KeyPress(KeyAscii As Integer)
'MappingInfo=UserControl,UserControl,-1,KeyPress
Event KeyUp(KeyCode As Integer, Shift As Integer)
'MappingInfo=UserControl,UserControl,-1,KeyUp
...
Вспомним, что указанные события нашего ActiveX мы отобразили на события UserControl. Это видно из сторок (и подобных им):
Private Sub UserControl_Click()
RaiseEvent Click
End Sub
Далее мы определили собственное событие NoClicks. Оно тоже имеется:
...
Event NoClicks()
...
Определённые на первом шаге мастера стандартные свойства BackColor, ForeColor, Enabled, Font и т. п. тоже присутствуют в нашем коде. Для каждого из них присутствует два метода - Property Get и Property Let (или Property Set для свойств-объектов типа Font), которые связывают наше свойство с соответствующей внутренней переменной. Например, для свойства BackColor мы имеем следующие строчки:
Public Property Get BackColor() As Long
BackColor = m_BackColor
End Property
Public Property Let BackColor(ByVal New_BackColor As Long)
m_BackColor = New_BackColor
PropertyChanged "BackColor"
End Property
а для Font - следующие:
Public Property Get Font() As Font
Set Font = m_Font
End Property
Public Property Set Font(ByVal New_Font As Font)
Set m_Font = New_Font
PropertyChanged "Font"
End Property
Кроме того мы определили свойство Clicks. Оно тоже присутствует в порожденном коде:
Public Property Get Clicks() As Integer
Clicks = m_Clicks
End Property
Public Property Let Clicks(ByVal New_Clicks As Integer)
If Ambient.UserMode Then Err.Raise 382
m_Clicks = New_Clicks
PropertyChanged "Clicks"
End Property
Обратите внимание на строчку:
...
If Ambient.UserMode Then Err.Raise 382
...
Она говорит о том, что если мы находимся в режиме работы программы, то при попытке изменить значение свойства возникает ошибка с номером 382 (property cannot be set at run time). Как вы помните, это свойство при запуске программы мы сделали Read-Only.
Теперь о нашем собственном методе SetZero. Для него Control Interface Wizard вставил только заготовку (естественно, ведь что за код там должен быть, знаем только мы сами):
Теперь мы будем вносить в наш код дополнения. И это естественно - мастер пособен лишь на написание заголовок для наших функций. А всю начинку нам надо писать самим.
Напомним, что мы хотели, что бы наш ActiveX действовал так - при трех щелчках возникает событие Click, а при последующщих - NoClick. Для этого давайте изменим порожденный мастером код для UserControl_Click на следующий:
Private Sub UserControl_Click()
m_Clicks = m_Clicks + 1
If m_Clicks <= 3 Then
RaiseEvent Click
Else
RaiseEvent NoClicks
End If
End Sub
Теперь у нас возникает или событие Click, или NoClick, в зависимости от того, сколько раз мы уже щелкнули (количество щелчков хранится в переменной m_Clicks). С этой частью все.
Теперь займемся методам SetZero. Он должен просто обнулять число щелчков. Для этого измените порожденный мастером код следующим образом:
Public Function SetZero() As Variant
m_Clicks = 0
End Function
Все, теперь можно наш проект компилировать и использовать в любом проекте. После компиляции создайте новый проект типа Standard EXE. В нем зайдите в меню Project и далее выберите пункт Components. В появившемся диалоговом окне Components нажмите на кнопку Browse
Появится окно Add ActiveX Control
С его помощью найдите на диске наш откомпилированный ActiveX (у него расширение *.ocx), после чего нажмите на кнопку Open и затем на OK. Наш ActiveX появится на панели элементов
Добавьте его на форму, измените ее фон и внесите следующий код:
Option Explicit
Dim k As Integer
Private Sub UserControl11_Click()
k = k + 1
Form1.Caption = k
End Sub
Private Sub UserControl11_NoClicks()
Form1.Caption = "No Clicks"
Beep
End Sub
Добавьте еще на форму кнопку и напишите для нее код:
Private Sub Command1_Click()
UserControl11.SetZero
k = 0
End Sub
Запустите программу. При первых трех щелчках в заголовке формы будет появляться номер щелчка, при последующих - надпись No Clicks
При нажатии на кнопку все приводится в начальное состояние, и событие Click опять возникает при первых трёх щелчках.
Измените код для Command1_Click на
Private Sub Command1_Click()
UserControl11.Clicks = 1
k = 0
End Sub
Теперь при запуске и последующем нажатии на кнопку возникнет ошибка 382 (так как свойство Clicks на этапе выполнения мы задали как свойство только для чтения)
Все работает, как и ожидалось.
В уроке 10 мы использовали такой объект PropertyBag. Сайчас мы посмотрим, что за ним скрывается. Создайте новый проект типа Standard EXE и разместите на нем кнопку. Измените её свойство Caption на My title
Сохраните проект на диске (для формы оставьте имя по умолчанию Form1.frm).
Теперь закройте наш проект. Найдите на диске файл Form1.frm и откройте его в Блокноте. Среди строчек его кода вы увидите строчки, относящиеся к нашей кнопке:
...
Begin VB.Form Form1
...
Begin VB.CommandButton Command1
Caption = "My title"
Height = 495
Left = 480
TabIndex = 0
Top = 240
Width = 1215
End
End
...
Видите, в одной из строк записалось значение для нашего свойства Caption. И все свойства для всех элементов формы тоже записываются в файле Form1.frm. Он то и является тем самым загадочным объектом PropertyBag.
Как известно, ActiveX - элементы можно располагать и на WEB-страницах. Посмотрим, что будет являтся PropertyBag в этом случае. Запустите редактор HomeSite (или какой-нибудь редактор WEB-страниц). В HomeSite перейдите на вкладку Script панели QuickBar и нажмите на кнопку для ActiveX-элементтов
В появившемся диалоге выберите Microsoft UpDown Control 6.0 и нажмите на OK
Вы получите приблизительно следующий код: ...
...
В строчках
...
width=80
height=30>
...
и сохраняются разные свойства для нашего ActiveX-элемента. Таким образом в этом случае объектом PropertyBag будет сама WEB-страница.
Property Page Wizard предназначен для создания окна со вкладками для элемента ActiveX. Это позволит группировать связанные свойства в одном месте. Для использования Property Page Wizard вы должны его подключить. Для этого заходим в меню Add-Ins и выбираем Add-Ins Manager. В появившемся диалоге Add-Ins Manager выбираем VB 6 Property Page Wizard
Далее отмечаем галочку Loaded/Unloaded и нажимаем OK. В меню Add-Ins появится пункт Property Page Wizard. Щелкаем на нем. Появляется первое окно "Property Page Wizard - Introduction". В нем можно сразу поставить галочку Skip this screen in the future (В будущем не показывать этот экран). Нажимаем на Next. Появится очередное окно мастера - "Property Page Wizard - Select the Property Pages". Именно в нем мы определяем, сколько вкладок будет в нашем окне свойств и как они будут называться. Для добавления очередной вкладки нажмите на кнопку Add
Добавьте две вкладки. Дайте им названия page1 и page2. Нажимаем на Next. Появляется окно мастера "Property Page Wizard - Add Properties". В его левой части будет список возможных свойств нашего элемента ActiveX, а в правой - добавленные на предыдущем шаге вкладки
Для добавления свойства на соответствующую вкладку щелкните на ней, затем выберите нужное свойство из левого списка и нажмите на кнопочку со стрелкой право. Свойство должно перейти на соответствующую вкладку
Таким образом переносим все необходимые свойства, после чего нажимаем на Next. В появившемся последнем окне мастера нажимаем на Finish. Работа мастера закончена!
Теперь посмотрим результат работы мастера. Для этого перейдите в тестовый проект (если он у вас есть) или просто используем уже откомпилированный элемент ActiveX в каком-нибудь проекте. Щелкаем на нашем элементе ActiveX правой кнопкой мыши и в контекстном меню выбираем Properties. Для нашего ActiveX-элемента появится окно свойств со вкладками
Именно это мы и хотели сделать с помощью Property Page Wizard.
Задача такая. Нам хотелось бы в каждый наш ActiveX прибавить окошко About, причем это окно должно появляться в окне свойств для нашего элемента ActiveX (как у многих ActiveX-элементов Microsoft). Делается это следующим образом: сначала прибавляем к нашему элементу ActiveX еще одну форму. Для этого в окне проекта щелкаем правой кнопкой мыши на нашем элементе ActiveX и выбираем в контекстном меню Add, затем Form
В появившемся диалоге "Add Form" выбираем Form и нажимаем на Open
Теперь в проекте нашего Active'а появилась новая форма (измените ее свойство Name на frmAbout)
Измените ее размеры и разместите некоторую информацию (использую label)
Сохраните проект. Новой форме дайте имя about.frm.
Добавьте в окно кода для нашего элемента ActiveX следующие строки:
Public Sub About()
frmAbout.Show vbModal
End Sub
Затем щелкните мышкой на только-что добавленной функции About, затем зайдите в меню Tools в редакторе VB и выберите там "Procedure Attributes". В появившемся окне Procedure Attributes убедитесь, что в combobox "Name" стоит именно About, и нажмите на кнопку Advanced, после чего выберите в combobox'е "Procedure ID" пункт AboutBox
Нажимаем OK. Теперь при размешении нашего ActiveX-элемента (например, в тестовом проекте) среди свойств элемента появится еще один - About
, при выборе которого и будет появляться сделанное нами окно About.
Как правило, для свойств, методов и событий ActiveX элемента имеются подсказки. их можно увидеть, например, в Object Browser
Делаются они следующим образом: сначала щелкаем на окне кода, затем в меню Tools выбираем Procedure Attributes
В появившемся диалоге Procedure Attributes в combobox'е Name выбираем нужную процедуру (или свойство), и в поле Description пишем нашу подсказку
После таких действий наша подсказка появятся с том числе и в Object Browser
Сначала о регистрации. Способов существует несколько.
Во-первых, если вы пишете ActiveX сами, то он регистрируется автоматически при компиляции.
Во-вторых, если вы откуда-то взяли элемент ActiveX (т. е. файл с расширением *.ocx), то для регистрации наберите в командной строке (возможно, придется указать полный путь)
regsvr32 имя_файла.ocx
Третья возможность - если ActiveX расположен на WEB-страничке, то он зарегистрируется сам при посещении это странички (если, конечно, у IE установлено соответствующее разрешение).
Для отмены регистрации можно воспользоваться той же утилитой regsvr32 с ключем /u:
Свойства элемента ActiveX разбиваются на разные категории. Вы это видите на вкладке Categorized окна свойств
Вы тоже можете рассортировать свойства вашего ActiveX. Для этого в меню Tools выбираем Procedure Attributes (перед этим щелкните на окне с кодом для нашего ActiveX)
Далее в появившемся диалоге Procedure Attribute щелкните на кнопке Advanced. В появившемся combobox'е Property Cathegory выбираем нужную категорию из списка или впечатываем свою (предварительно выбираем нужное свойство в combobox'е Name)
После таких действий наше свойство оказывается в нужной категории
В этом коротком уроке мы продолжим наши украшательства. Все элементы ActiveX, которые мы делали до сих пор, имели стандартную иконку на панели элементов
Для задания своей иконки сначала создайте ее. Это должен быть рисунок 16 на 15 пикселей (можно использовать форматы *.bmp, *.jpg, *.gif). После этого задайте этот файл в свойстве ToolboxBitmap для элемента ActiveX
После этого на панели элементов наш ActiveX будет иметь собственную иконку
Умение программно зарегистрировать элемент ActiveX может пригодиться, например, при написании собственного инсталлятора. Делается это приблизительно так. Внутри файла с ActiveX (как правило, это файл с расширением *.ocx) есть две функции - DllRegisterServer (для регистрации) и DllUnregisterServer (для отмены регистрации). Вот их то и надо вызвать. Делаем это аналогично вызову API-функции. Приведем пример. Пусть у нас в каталоге D:\_VB\AXs\URLlabel имеется файл URLLabel.ocx с элементом ActiveX. Создадим обычный проект для Visual Basic (типа Standard EXE), разместим на форме две кнопки (cmdReg и cmdUnReg). В окне кода напишем следующее:
Option Explicit
Private Declare Function RegTest Lib "URLLabel.ocx" Alias _
"DllRegisterServer" () As Long
Private Declare Function UnRegTest Lib "URLLabel.ocx" Alias _
"DllUnregisterServer" () As Long
Const ERROR_SUCCESS = 0
Dim regCode As Long
Private Sub cmdUnReg_Click()
On Error Resume Next
ChDrive "D:" ' Устанавливаем нужный
ChDir "D:\_VB\AXs\URLlabel" ' каталог текущим
regCode = UnRegTest() ' регистрация URLLabel.ocx
' анализ возможных ошибок
If Err <> 0 Then
MsgBox "Файл URLLabel.ocx не найден"
Else
If regCode <> ERROR_SUCCESS Then
MsgBox "Операция отмены регистрации не выполнена"
End If
End If
End Sub
Private Sub cmdReg_Click()
On Error Resume Next
ChDrive "D:"
ChDir "D:\_VB\AXs\URLlabel"
regCode = RegTest() ' регистрация URLLabel.ocx
If Err <> 0 Then
MsgBox "Файл URLLabel.ocx не найден"
Else
If regCode <> ERROR_SUCCESS Then
MsgBox "Операция регистрации не выполнена"
End If
End If
End Sub
Теперь при нажатии на соответствующие кнопки элемент будет регистрироваться или сниматься с регистрации.
Для проверки можете создать и откомпилировать тестовый проект VB, использующий ActiveX-элемент из файла URLLabel.ocx. Если первой программой вы зарегистрировали ActiveX, то тестовая программа будет запускаться без проблем
, а если вы сняли ActiveX с регистрации, то тестовая программа не запустится, и появится следующее окошко:
В предыдущих уроках мы с вами смотрели, как делать ActiveX-элементы. Их отличительная особенность в том, что они всегда должны существовать в некотором контейнере. Другая их особенность - они чаще всего видимы (имеют видимый интерфейс). Правда, их можно сделать невидимыми на этапе запуска программы (типа элемента таймер в VB), но они будут видимы по крайней мере на этапе разработки прогрммы.
Наряду с таким типом элементов ActiveX существуют и другие типы - ActiveX EXE и AxtiveX DLL. При их создании вы выбираете соответствующие иконки в окне New Project:
Они уже работают несколько по-другому. Для них не нужен контейнер. Внутри них могут содержаться свойства и методы. Другие программы могут создавать экземпляры ActiveX EXE или ActiveX DLL и, разумеется, могут их использовать - читать и изменять свойства, вызывать методы.
Отличие между ActiveX EXE и ActiveX DLL следующее - первые существуют в своем адресном пространстве, а вторые - внедряются в адресное пространство вызвавшей их программы. Это самое главное отличие меду ними. Из этого есть несколько следствий - например, ActiveX DLL работают быстрее ActiveX EXE. Есть и другие различия, которые мы будем рассматривать в наших уроках.
Еще два типа для ActiveX'ов - это ActiveX Document EXE и ActiveX Document DLL. Для их создания выбираем такие иконки
Что это такое и как это делать мы тоже посмотрим (но не в ближайших уроках).
Несколько ближайших уроков мы с вами посвятим созданию ActiveX DLL. Создайте пустой проект (типа ActiveX DLL, естественно)
Нажимаем на Open. Обратите внимание, что в Project Explorere'е у вас уже существует пустой класс Class1
Переименуйте его в окне свойств на CMyClass (для этого его надо предварительно выделить в Project Explorere'е). Измените также и имя нашего проекта с безликого Project1 на MyFirstDLL. Теперь все должно выглядеть так
Давайте теперь наш ActiveX DLL скомпилируем. Делаем как всегда - меню File, далее выбираем Make что-то там
В появившемся окне Make Project выберите нужную папку. Обратите внимание, что расширение для откомпилированного ActiveX DLL - это *.dll, а не *.ocx, как было у ActiveX элементов
Нажимаем на OK и переходим к следующему уроку.
Давайте добавим к нашему ActiveX DLL свойство MyString. В нем будет храниться некоторая строка. Никакого особенного смысла в этой строке нет - мы просто смотрим, как можно добавлять свойства для нашего ActiveX DLL.
Для этого добавьте следующий код:
Option Explicit
Private m_strMyString As String
Public Property Get MyString() As String
MyString = m_strMyString
End Property
Public Property Let MyString(NewString As String)
m_strMyString = NewString
End Property
Обратите внимание, что переменную m_strMyString мы объявили как Private. Это для того, чтобы к ней не было доступа извне. Досту возможен только через специальные методы класса - Property Get имя_свойства и Property Let имя_свойства. Они идут парами - одно для чтения и другое для записи. имя_свойства (в нашем примере это MyString) - это то имя, под которым наше свойство будет видно снаружи. Имя же m_strMyString никто снаружи не увидит.
Теперь добавим метод. Вы можете считать методом функцию нашего класса, объявленную с модификатором Public. Все, что вы объявляете как Public, будет видно снаружи. Давайте добавим метод, который задаст для нешей строки некоторое значение:
Public Sub SetString(NewString As String)
m_strMyString = NewString
End Sub
Откомпилируйте наш ActiveX DLL и переходите к следующему уроку.
Для испытания созданного нами ActiveX DLL создайте простой проект типа Standard EXE и добавьте на его форму простую кнопку. Далее заходим в меню Project и выбираем пункт References. Пользуясь кнопкой Browse, найдите откомпилированный на прошлом уроке файл, выделите его, нажмите на Open и на OK для закрытия окна References. Добавьте следующий код:
Option Explicit
Dim MyObject As New CMyClass
Private Sub Command1_Click()
'Устнавливаем значение свойства
MyObject.SetString "Привет из ActiveX DLL"
'Вызываем метод
MsgBox MyObject.MyString
End Sub
Обратите внимание, что после точки у вас будет появлятся подсказка с нашими свойствами и методами
Запускаем, нажимаем на кнопку.
Т. е. нашей тестовой программе удалось подсоединится к серверу ActiveX DLL.
У компонентов ActiveX DLL (как, впрочем, и у ActiveX EXE) кроме свойств и методов могут быть еще и события. Когда наш компонент генерирует некоторое событие, то программа, в которой он был создан, может как-то на это событие реагировать. Это не должно быть для вас чем-то новым - скажем у кнопки есть событие Click, а что там программист в этом событии напишет - так это его личное дело.
Для добавления события в элемент ActiveX добавьте строчку
Option Explicit
...
Event TwoChanges()
Синтаксис здесь такой - сначала пишем ключевое слово event, затем - имя вашего события (назвать его можно как угодно, у нас оно названо TwoChanges). При этом у события могут быть и параметры, которые, естественно, пишем в круглых скобках.
Мы назвали событие TwoChanges(), и сделаем так, чтобы оно возникало при втором изменении переменной m_strMyString в нашем классе.
Событие у нас объявлено, но теперь его набо откуда-то вызвать. Делается это так. Заводим переменную для счетчика и обнуляем ее в событии Initialize:
Option Explicit
...
Dim m_intCounter As Integer
Private Sub Class_Initialize()
m_intCounter = 0
End Sub
Увеличиваем значение счетчика при каждом изменении переменной m_strMyString:
Public Property Let MyString(NewString As String)
m_strMyString = NewString
m_intCounter = m_intCounter + 1
If m_intCounter = 2 Then RaiseEvent TwoChanges
End Property
Public Sub SetString(NewString As String)
m_strMyString = NewString
m_intCounter = m_intCounter + 1
If m_intCounter = 2 Then RaiseEvent TwoChanges
End Sub
Синтаксис здесь такой: для вызова события пишем RaiseEvent (это ключевое слово), после чего пишем имя вызываемого события (у нас это TwoChanges). У нас значение перемнной m_intCounter может изменяться в двух местах, поэтому и пишем наш код в двух местах. Правильнее надо бы его написать в отдельной функции, которую потом в двух местах вызвать. Но мы уж так написали, так пусть так и останется.
Компилируем и переходим к следующему уроку.
Сейчас мы проверим событие из прошлого урока. Для этого создайте новый проект типа Standard EXE и добавьте на форму обычную кнопку. Далее подсоединяем наш AvtiveX DLL. Для этого заходим в меню Project и выбираем пункт References
В появившемся окне References найдите в списке библиотек нашу (мы назвали ее MyFirstDLL). Если ее там нет, то вам придется воспользоваться кнопкой Browse. После подключения библиотеки добавьте следующий код:
Option Explicit
Dim WithEvents MyObject As CMyClass
Обратите внимание, что мы объявляем переменную MyObject с ключевым словом WithEvents. Также обратите внимание, что после этого в левом combobox'е для окна кода появится пункт MyObject
, а в правом combobox'е для окна кода появится пункт со всеми событиями для нашего объекта MyObject (если вы, разумеется, выбрали в левом combobox'е MyObject)
Добавьте в программу следующий код:
Private Sub Form_Load()
Set MyObject = New CMyClass
End Sub
Private Sub Command1_Click()
'Изменяем значение строки в MyObject
MyObject.SetString "Igor"
End Sub
Private Sub MyObject_TwoChanges()
'Обрабатываем событие TwoChanges
MsgBox "Произошло событие TwoChanges"
End Sub
Запускайте программу. Нажмите на кнопку два раза. При первом нажатии ничего не произойдет, при втором выскочит ожидаемый MessageBox
Таким образом при втором изменении строки наш ActiveX DLL вызвал событие TwoChanges.
Когда вы создаете элемент ActiveX, то при его модификации и перекомпиляции возможно возникновение проблем, связанных с различными его версиями. Одну из таких проблем мы сейчас и рассмотрим.
Создайте проект типа ActiveX DLL. В окно кода внесите только следующее объявление переменной:
Option Explicit
Public k As Integer
Мы не собираемся делать сложный класс, так что для пояснения проблемы хватит и этого. Измените также имя проекта на Compatibility и имя класса на CCompatibility (через окно свойств).
Зайдите теперь в меню Project, выберите пункт Compatibility Properties, и в появившемся диалоговом окне перейдите на вкладку Component
Обратите внимание, что в этом окне отмечена радиокнопка Project Compatibility
Закройте диалоговое окно, ничего в нем не меняя. Откомпилируйте наш ActiveX DLL. Создайте тестовый проект типа Standard EXE, добавьте ссылку на наш ActiveX DLL (если забыли, то смотрите урок 29).
В окно кода добавьте следующие строки:
Option Explicit
Dim objMyObject As New CCompatibility
Private Sub Form_Load()
MsgBox objMyObject.k
End Sub
После этого откомпилируйте тестовый проект (скажеи под именем test.exe) и запустите его. Как и ожидалось, при его запуске появится MessageBox с числом k (которое будет равно нулю).
Теперь давайте изменим наш ActiveX DLL. Добавьте еще одну переменную:
Option Explicit
...
Public n As Integer
Откомпилируйте снова наш ActiveX DLL (под тем же именем). После этого запустите из окна Проводника откомпилированный тестовый проект test.exe. Должно возникнуть сообщение об ошибке
Произошло следующее - в нашем тестовом exe-файле содержался некий уникальный идентификатор (так называемый GUID) для нашего старого ActiveX DLL. Когда мы создали новый вариант для нашего ActiveX DLL, то ему присвоился новый GUID, но в тестовом exe-файле остался старый! Отсюда и сообщение об ошибке.
Для того, чтобы избежать эту проблему, надо было отметить в окне Project Properties радиокнопку Binary Compatibility
Если отмечена она, то при перекомпиляции элемента ActiveX (а это может быть любой ActiveX - и ActiveX Control, и ActiveX DLL, и ActiveX EXE) его GUID сохраняется, и таким образом старые проекты, котороые используют наш ActiveX, смогут работать как и прежде. Проблем не будет.
У ActiveX'ов типа DLL и EXE существует свойство Persistable
Оно может принимать два значения - NotPersistable и Persistable. Если оно установлено в Persistable, то наш класс может сохранять свое состояние, если в NotPersistable - то не может. Обратите внимание, что если мы устанавливаем значение этого свойства в Persistable, то у класса в окне кода появляются новые события InitProperties, ReadProperties и WriteProperties
При перепечатке любого материала
с сайта, видимая ссылка на источник www.warayg.narod.ru
и все имена, ссылки авторов обязательны.