Архивы: по дате | по разделам | по авторам

Как скриптуются приложения. Акт второй.

АрхивПрограммазм (архив)
автор : Николай Куртов   26.12.2000

- VBScript подкючить... JScript подключить... И на VB ??? Не могу я так!

=+=+=+=

В прошлой статье я обещал рассказать о более простом способе подключения обработчика скриптов в приложения. Особенно актуален этот вопрос для начинающих программистов, или же если ваши решения созданы на Visual Basic. Спустя некоторое время после выпуска Scripting Engine, дела изменились и Microsoft предоставила разработчикам Script ActiveX Control. Помимо переноса функциональности в удобную для Visual Basic компонентную оболочку, были также реализованы некоторые ценные для организации кода и данных скрипта функции. Неслучайно, во второй статье этой темы, все примеры я буду приводить на Visual Basic.

Скрипт-компонент можно добавить совершенно стандартным методом VB: из диалогового окна Components. Если же такого пункта в списке нет, то достаточно найти его на диске при помощи Browse.

Поместив скрипт-компонент на какую-нибудь форму программы (от сего места будем звать его ScriptControl1), вы обнаружите, что сам компонентик-то не так уж и много свойств имеет: AllowUI, Language и Timeout.

Свойство AllowUI позволяет определить, может ли скрипт показывать свои диалоговые окна, такие как сообщения об ошибках, различные MsgBox и InputBox.

Свойство Language по умолчанию установлено в VBScript, но с равным успехом может содержать имя JScript.

Свойство TimeOut задает максимальный интервал, после которого скрипт будет принудительно завершен. Это полезно в том случае, если скрипт "нечаянно" зациклился.

Теперь можно обратиться к внутренностям компонента, при этом обнаружив некоторые функции, позволяющие уже что-то запускать, без мучительной подготовки: Eval и ExecuteStatment. Как нетрудно догадаться, первая вычисляет выражение, введенное в виде строки, а вторая выполняет завершенный оператор.

Private Sub Command1_Click()
 a = ScriptControl1.Eval("2*6+4")
 ScriptControl1.ExecuteStatement "MsgBox " & Str(a)
End Sub

Вычисляться могут любые выражения: в целых числах, строковые, логические, возврат функций. Результат возвращается в виде VARIANT переменной, которая, как известно, может содержать все.

Вряд ли взявшись за освоение Script Control, можно удовлетвориться единственной обрабатываемой строчкой. Метод AddCode позволяет добавить несколько строчек, которые потом можно запустить методом Run. Если функция принимает на вход параметры, то эти параметры можно также передать через Run.

Private Sub Command1_Click()
 aCode = "Const Hello = ""Hello,"" " & vbCrLf _
    & "Sub ShowMyName(Name)" & vbCrLf _
    & " MsgBox Hello & Name" & vbCrLf _
    & "End Sub"
         
 ' Вызов метода Reset необходим для исключения ошибки
 ' переопределения кода
 ScriptControl1.Reset
 ScriptControl1.AddCode aCode
 ScriptControl1.Run "ShowMyName", "Nickolay"
End Sub

Код, который передается в качестве параметра методу AddCode должен быть корректным и содержать одну или несколько процедур или функций. В случае, если код, добавляемый при помощи AddCode некорректен, компонент выбрасывает исключение. Задача разработчика - перехватить эту ошибку и дать пользователю понять, что задача пользователя - писать скрипты грамотнее.

 On Error Resume Next
 ScriptControl1.AddCode code
 If Err Then
     ' Здесь у нас синтаксическая ошибка
     MsgBox Err.Number & ": " & Err.Description, , _
         "Проверь синтаксис!"
 Else
     ScriptControl1.Run "SubName"
     If Err Then
         ' А здесь - runtime ошибка
         MsgBox Err.Number & ": " & Err.Description,,_
             "Ооопс:"
     End If

Вообще говоря, у Script Control имеется свойство Error и одноименное событие Error, которое вызывается в случае ошибки. В случае ошибок времени выполнения лучше всего воспользоваться именно этим свойством, поскольку оно несет больше информации об ошибке, чем стандартный вариант с Err.

Что касается внутренних объектов программы, то их экспортирование в пространство имен скрипта гораздо проще, чем в Visual C++. Метод AddObject позволяет расширять количество доступных скрипту объектов. Для этого нужно создать Class Module и объявить внутри него необходимые функции и public свойства.

' Динамически создайте новый класс, и
' поместите его под нужным именем в
' пространство имен скрипта
'
 Dim TheClass As New YourClassModule
 ScriptControl1.AddObject "Object1", TheClass

Теперь внутри скрипта можно совершенно спокойно обращаться к объявленному Object1.

MsgBox Object1.MySuperStatus

Таким образом, можно организовать некий proxy-объект для доступа к элементам управления в свой программе. Например, можно в YourClassModule создать функцию, добавляющую какую либо строчку в список, toolbar или меню.

 ' В модуле YourClassModule
 Public Sub AddItem(ByVal text As String) 
     Form1.List1.AddItem text
 End Sub

Следует учитывать, что если нужно передать какую либо внутреннюю переменную скрипта на обработку в ваш ClassModule, то работать придется только с переменными типа Variant.

' В модуле YourClassModule
 Public Sub MakeProperCase(text As Variant) 
     text = StrConv(text, vbProperCase)
 End Sub

Возможности становятся поистине безграничными, если выдавать через свойства YourClassModule какие-нибудь внутренние компоненты. Напрмер, Form.

' В модуле YourClassModule
Property Get ActiveForm() As Object
   Set ActiveForm = Screen.ActiveForm
End Property

Итак, путей для творческого поиска предостаточно, но прежде всего  рекомендую обратиться за полной документацией, а заодно и за последней версией Script Control на  http://msdn.microsoft.com/scripting/.

Обсуждение статьи - в форуме "Обсудим "СофтТерру"

© ООО "Компьютерра-Онлайн", 1997-2024
При цитировании и использовании любых материалов ссылка на "Компьютерру" обязательна.