Visual2000 · Архив статей Колесова & Павловой
Андрей Колесов, Ольга Павлова
Загрузить программные приложения (20 Кб, ACTIVEX.zip)
© 1997, Андрей Колесов, Ольга ПавловаОдним из важнейших новшеств 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). Задача заключается в том, чтобы по щелчку кнопки в одном поле (LuckyNumber) выводилось некоторое случайное число, а в другом (Fortune) — научно обоснованный прогноз развития ситуации. Алгоритм предсказания весьма прост: если случайное число больше 50-ти, то будет легкий день, в противном случае — трудный.
Рис. 1. Форма приложения "Прогноз дня"
Теперь дважды щелкните командную кнопку и в открывшемся окне кода для события Click введите следующий код:
Number = Int(Rnd() * 100) ' случайное число LuckyNumber.Text = Number If Number > 50 Then Fortune.Text = "Сегодня будет легкий день" Else Fortune.Text = "Сегодня будет трудный день" End If
Чтобы убедиться в его работоспособности нашего приложения, запустим его на выполнение и станем щелкать кнопку, наблюдая за выдаваемыми предсказаниями.
Обнаружив, что придуманный нами алгоритм может представлять ценность не только для данного приложения, попробуем трансформировать его расчетную часть в автономный, повторно используемый компонент. Для этого в меню 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
Запустим созданное приложение на выполнение, щелкнем кнопку "Дать прогноз" и... получим сообщение об ошибке: "Неопределен тип данных" в строке "Dim oFortune As TellFort". (Непонятно, почему эта ошибка определяется только в момент обращения к этому оператору. Ведь еще в версиях для DOS подобные ситуации выявлялись еще на этапе предварительной компиляции проекта, т.е. в момент запуска его на выполнение.)
Проблема понятна: созданная нами группа Group1 состоит из двух несвязанных между собой приложений — Project1 и Fortune. Первое из них является в данном случае тестовым контейнером, а второе — нужным нам компонентом ActiveX.
Сделаем эту связку. Для этого щелкните правой кнопкой мыши форму Form1 в окне Project Explorer Window и выберете команду View Object из контекстного меню. В меню Project выберите команду References. В появившемся одноименном диалоговом окне установите флажок Fortune и затем щелкните кнопку OK (рис.2).
Рис. 2. В окне Reference указываются ActiveX объекты, доступные для данного приложения.
Запускаем наше приложение еще раз. Явных сообщений об ошибках нет, но легко увидеть, что алгоритм работает неверно — прогноз не очень хорошо согласуется с получаемым случайным числом. В чем была допущена ошибка? Этот вопрос мы предлагаем читателям в качестве домашнего задания. Однако если в модуле 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
Мы написали работающий код, но не создали самого компонента. Выберем меню 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 компонента.
Теперь мы хотим создать отдельный повторно используемый компонент. Поэтому сначала выделим его название в окне 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.
Теперь сделаем так — откроем в среде VB 5.0 проект (существующий!) с названием Prоject1 (а не Group1, который включает оба проекта). Запускаем его на выполнение — и опять получаем сообщение: "Неопределен тип данных". Еще раз повторяем операцию: в меню Project выбираем команду References, затем в появившемся одноименном диалоговом окне устанавливаем флажок Fortune, нажимаем кнопку OK. ВСЕ РАБОТАЕТ!
Теперь создаем автономный модуль Project1.EXE. Выходим из среды Visual Basic. Запускаем на выполнение Project1 — предсказания выдаются согласно разработанному алгоритму.
Поздравляем всех, кто дошел в нашем примере до этого места! Мы создали очень нужный в повседневной жизни компонент, который может предсказывать перспективу на текущий день. Его можно легко встроить в любое Windows приложение — остается только найти клиентов, которые захотят его купить у нас или хотя бы забрать его бесплатно.