Как скриптуются приложения. Акт второй.
АрхивПрограммазм (архив)- 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/.
Обсуждение статьи - в форуме "Обсудим "СофтТерру"