Visual2000 · Архив статей Колесова & Павловой

Создание ActiveX сервера в VB 5.0

Андрей Колесов, Ольга Павлова

Загрузить программные приложения (20 Кб, ACTIVEX.zip)

© 1997, Андрей Колесов, Ольга Павлова
Авторский вариант. Статья была опубликована c незначительной литературной правкой в журнале "КомпьютерПресс" № 12/97, c. 134-136.


Одним из важнейших новшеств...

Одним из важнейших новшеств VB 4.0, появившегося два года назад, была возможность создания повторно используемых автономных компонентов (ранее вспомогательные процедуры на VB можно было применять в различных приложениях только на уровне исходного текста). Эти компоненты реализованы в виде OLE-серверов двух типов: in-process и out-of-process. Первый представляет собой DLL-библиотеку, второй — EXE-модуль. Однако оба компонента на самом деле не являются "настоящими" DLL и EXE — оба сервера используют механизм доступа ActiveX (по старой терминологии — OLE Automation), в том числе для определения их свойств, методов и синтаксиса. Out-of-process сервер может эффективно применяться в архитектуре клиент/сервер, в то время как in-process сервер обладает преимуществом в быстродействии, так как использует локальные вызовы, а не более медленный механизм удаленных обращений к процедурам.

В VB 5.0 возможности создания ActiveX серверов были существенно расширены. В частности, они могут использовать как настоящий машинный код, так и псевдокод. Для иллюстрации технологии их разработки создадим компонент, который рассчитывает предсказание на день. Практическая ценность такого примера невелика, однако сама процедура его создания может быть весьма показательной.

В начало статьи

ШАГ 1. Создание приложения

Создадим форму с командной кнопкой и двумя текстовыми полями (рис. 1). Задача заключается в том, чтобы по щелчку кнопки в одном поле (LuckyNumber) выводилось некоторое случайное число, а в другом (Fortune) — научно обоснованный прогноз развития ситуации. Алгоритм предсказания весьма прост: если случайное число больше 50-ти, то будет легкий день, в противном случае — трудный.

Рис. 1. Форма приложения "Прогноз дня"

Теперь дважды щелкните командную кнопку и в открывшемся окне кода для события Click введите следующий код:

Number = Int(Rnd() * 100) ' случайное число
LuckyNumber.Text = Number
If Number > 50 Then
  Fortune.Text = "Сегодня будет легкий день"
Else
  Fortune.Text = "Сегодня будет трудный день"
End If

Чтобы убедиться в его работоспособности нашего приложения, запустим его на выполнение и станем щелкать кнопку, наблюдая за выдаваемыми предсказаниями.

В начало статьи

ШАГ 2. Написание компонента ActiveX

Обнаружив, что придуманный нами алгоритм может представлять ценность не только для данного приложения, попробуем трансформировать его расчетную часть в автономный, повторно используемый компонент. Для этого в меню File выберете команду Add Project, в появившемся окне выделите элемент ActiveX DLL и затем щелкните кнопку Open. Теперь у нас есть два открытых проекта, первый из которых мы будем использовать в качестве теста-контейнера, а второй — компонента ActiveX.

Щелкните правой клавишей мыши проект Project2 в окне Project Explorer Window и в появившемся контекстном меню выберете команду Project2 Properties. На экран выведется диалоговое окно Project2 — Project Properties, в котором в поле Project Name изменим название проекта на Fortune и затем щелкнем кнопку OK. После этого в окне Project Explorer Window щелкните правой кнопкой мыши модуль класса Class1, входящий в проект Fortune, и в контекстном меню выберете команду Properties. В одноименном окне измените имя модуля в поле Name с Class1 на TellFort.

Дважды щелкните название TellFort и введите в появившемся окне содержимое повторно используемых процедур (можно скопировать ранее сформированный код):

Public Property Get LuckyNumber()
   LuckyNumber = Int(Rnd() * 100)
End Property
Public Property Get Fortune()
   If LuckyNumber > 50 Then
      Fortune = "Сегодня будет легкий день"
   Else
      Fortune = "Сегодня будет трудный день"
   End If
End Property

В процедуре контейнера Command1_Click удалите введенный ранее код и введите такой:

Dim oFortune As TellFort
Set oFortune = New TellFort
LuckyNumber.Text = oFortune.LuckyNumber
Fortune.Text = oFortune.Fortune
set oFortune = Nothing

В начало статьи

ШАГ 3. Отладка — подключение компонента ActiveX

Запустим созданное приложение на выполнение, щелкнем кнопку "Дать прогноз" и... получим сообщение об ошибке: "Неопределен тип данных" в строке "Dim oFortune As TellFort". (Непонятно, почему эта ошибка определяется только в момент обращения к этому оператору. Ведь еще в версиях для DOS подобные ситуации выявлялись еще на этапе предварительной компиляции проекта, т.е. в момент запуска его на выполнение.)

Проблема понятна: созданная нами группа Group1 состоит из двух несвязанных между собой приложений — Project1 и Fortune. Первое из них является в данном случае тестовым контейнером, а второе — нужным нам компонентом ActiveX.

Сделаем эту связку. Для этого щелкните правой кнопкой мыши форму Form1 в окне Project Explorer Window и выберете команду View Object из контекстного меню. В меню Project выберите команду References. В появившемся одноименном диалоговом окне установите флажок Fortune и затем щелкните кнопку OK (рис.2).

Рис. 2. В окне Reference указываются ActiveX объекты, доступные для данного приложения.

В начало статьи

ШАГ 4. Отладка кода

Запускаем наше приложение еще раз. Явных сообщений об ошибках нет, но легко увидеть, что алгоритм работает неверно — прогноз не очень хорошо согласуется с получаемым случайным числом. В чем была допущена ошибка? Этот вопрос мы предлагаем читателям в качестве домашнего задания. Однако если в модуле TellFort записать такой код (найдете четыре отличия по сравнению с ранее приведенном кодом), то все будет работать правильно:

Dim LuckyNum%
Public Property Get LuckyNumber()
   LuckyNum% = Int(Rnd() * 100)
   LuckyNumber = LuckyNum%
End Property
Public Property Get Fortune()
   If LuckyNum% > 50 Then
      Fortune = "Сегодня будет легкий день"
   Else
      Fortune = "Сегодня будет трудный день"
   End If
End Property

В начало статьи

ШАГ 5. Создание автономного модуля

Мы написали работающий код, но не создали самого компонента. Выберем меню File и увидим с списке команд создания (Make) две операции — создание группы Group1 и отдельного ее компонента (в зависимости от выделенного перед этим проекта — Project1 или Fortune).

Для начала создадим приложение для всей группы. В результате мы получим EXE-модуль с названием Project1.EXE. Запустив его на выполнение, мы опять обнаружим, что он работает не так как нам хотелось бы: случайное число и предсказание вообще никак не меняются в окне. Нам не совсем удалось выяснит причину этого, но все начинает работать правильно (рис. 3) после записи кода тестового контейнера в таком виде:

Dim oFortune As TellFort
Private Sub Command1_Click()
  Set oFortune = New TellFort
  LuckyNumber.Text = oFortune.LuckyNumber
  Fortune.Text = oFortune.Fortune
  'set oFortune = Nothing
End Sub

ПРИМЕЧАНИЕ. Как подсказал нам читатель Борис Маркевич, в этой проблемы виноваты мы сами — перед использованием функции Rnd нужно выполнить инициализацию генератора случайных величин. Для этого нужно в модуле класса TellFort записать такой код:

Private Sub Class_Initialize()
  Randomize  'инициализация генератора случайных величин
End Sub

Рис. 3. Так работает созданной нами приложение. В нижней части экрана в окне виден код ActiveX компонента.

В начало статьи

ШАГ 6. Создание компонента ActiveX

Теперь мы хотим создать отдельный повторно используемый компонент. Поэтому сначала выделим его название в окне Project, потом выберем в меню File команду Make Fortune.DLL. Появится окно Make Project. Если вам что-то нужно уточнить в режиме создания компонента (например псевдокод или машинный код), нажмите сначала Options.

Вы создали компонент Fortune.DLL. А если Вы передумали и решили создать EXE-модуль? Для этого необязательно начинать с самого начала, выбирая соответствующий тип компонента. Можно просто в меню Project щелкнуть правой кнопкой мыши название модуля Fortune и выбрать в меню команду Properties. В появившемся окне указать вкладку General и в списке Project Type выбрать нужный тип компонента (рис. 4). Затем нажимаем кнопку OK и создаем модуль Fortune.DLL или Fortune.EXE соответственно.

Рис. 4. В окне Project Properties можно изменить в любой момент тип создаваемого компонента, а также параметры его создания.

Однако здесь нужно обратить внимание на такой момент. Отладка ActiveX компонента в среде VB (когда загружены два проекта - контейнер и сам компонент, см. шаг.4) возможна только в режиме ActiveX DLL. Соответственно логика разработки ActiveX компонента выглядит следующим образом: сначала мы выбирает тип компонента DLL и только после его отладки, перед созданием автономного модуля определяем его окончательный тип — DLL или EXE.

В начало статьи

ШАГ 7. Проверка работы автономного компонента

Теперь сделаем так — откроем в среде VB 5.0 проект (существующий!) с названием Prоject1 (а не Group1, который включает оба проекта). Запускаем его на выполнение — и опять получаем сообщение: "Неопределен тип данных". Еще раз повторяем операцию: в меню Project выбираем команду References, затем в появившемся одноименном диалоговом окне устанавливаем флажок Fortune, нажимаем кнопку OK. ВСЕ РАБОТАЕТ!

Теперь создаем автономный модуль Project1.EXE. Выходим из среды Visual Basic. Запускаем на выполнение Project1 — предсказания выдаются согласно разработанному алгоритму.

В начало статьи

Поздравляем всех...

Поздравляем всех, кто дошел в нашем примере до этого места! Мы создали очень нужный в повседневной жизни компонент, который может предсказывать перспективу на текущий день. Его можно легко встроить в любое Windows приложение — остается только найти клиентов, которые захотят его купить у нас или хотя бы забрать его бесплатно.

В начало статьи