Всё, что вы хотели знать о написании скриптов для JFW, но не знали, кого спросить

(Переработанный и дополненный вариант)
Источник:www.tiflocomp.ru
Дата публикации:2004
Twitter Facebook Vkontakte

Часть II. Создаём сложные файлы скриптов

Управление ходом выполнения скрипта

Скрипты не всегда выполняются линейно, сверху вниз, где каждая строка выполняется по порядку и только один раз. Иногда некоторые утверждения выполняются много раз, а иногда некоторые утверждения вообще пропускаются. Типы операторов, которые управляют ходом выполнения скрипта обсуждаются ниже. Ход выполнения может быть трех типов:

  1. Последовательный - в этом способе группа утверждений работает по порядку, начиная с начала и продвигаясь к концу. Этот линейный ход выполнения является самым простым .
  2. Ветвление (условие) - это своего рода развилка, от которой ход выполнения пойдет по одному из двух или нескольких путей. Какой путь будет выбран, зависит от результата проверки условия.
  3. Циклический (итерации) - ход выполнения как бы по кругу проходит одну и ту же последовательность команд в скрипте. Это продолжается до тех пор, пока какое-либо условие является истинным (условие цикла).

В одном и том же скрипте ход выполнения может быть различным и содержать фрагменты кода с любым из перечисленных типов.

Последовательный

Все утверждения, с которыми мы работали до сих пор, являются последовательными утверждениями. Это означает, что каждое утверждение действует в свою очередь, начиная в верхней части скрипта и продвигаясь к оператору EndScript. Ниже приводится пример скрипта только с последовательными утверждениями:

Script SayTheAValue()
Var 	
Int A
Let A = 1
SayInteger (A)
EndScript
Ветвление (условие)

Структура оператора if-then предоставляет средство выбора одного пути или другого. Для структуры if нужны три ключевых слова: if, then и endif. Давайте начнем с очень простого оператора if-then.

If (x == 1) Then 	
SayString ("You are right")
EndIf

Если, и только если переменная A равняется 1, скрипт вызовет функцию SayString, и произнесёт слова "You are right" (Вы правы). А вот пример посложнее.

If GetWindowName (GetCurrentWindow ()) == "Main" Then
SayString("In the main window.")
EndIf

Функция GetWindowName и её параметр GetCurrentWindow, использованные в утверждении if, возвращает заголовок текущего окна. А происходит следующее. Если и только если имя текущего окна является Main, (главное), тогда выполняется функция SayString. В остальных случаях она игнорируется. Мы выбираем путь "Then" только в том случае, если условие If является истинным.

Хотя операторы If и Then по сути являются отдельными операторами, часто бывает принято помещать их на одной строке. Вышеприведенная группа утверждений может выглядеть следующим образом:

If GetWindowName (GetCurrentWindow ()) == "Main" Then
SayString("In the main window.")
EndIf

Отныне мы будем показывать наши утверждения If-Then именно в такой форме.

В структуре If-Then есть два дополнительных ключевых слова Else и Elif. Каждый из этих элементов предоставляет альтернативный путь, но делают они это немного по-разному. Элемент Else говорит скрипту, что он должен выполнять определенные вещи, если, и только если обнаружилось, что предшествующее ему условие If является ложным. Например:

If GetWindowName (GetCurrentWindow ()) == "Main" Then
SayString("In the main window.")
Else
SayString("Not in a known window.")
EndIf

Эта последовательность будет выдавать одно сообщение, если вы будете находиться в главном окне, и что-то другое, если нет. А вот пример тройного ветвления:

If GetWindowName (GetCurrentWindow ()) == "Main" Then
SayString("In the main window.")
Else
If GetWindowName (GetCurrentWindow ()) == "Alternate" Then
SayString("In the alternate window.")
EndIf
Else
SayString("Not in a known window.")
EndIf

Здесь мы выдаём одно сообщение, если находимся в главном окне, другое сообщение, если находимся в альтернативном окне, и мы выдаём третье сообщение, если не находимся ни в каком из первых двух окон.

Использование ключевого слова Elif - это более простой способ сформулировать ветвь, которая говорит: "делай что-то другое, если истинно другое условие". Вышеприведенную последовательность скрипта можно переформулировать, чтобы выполнялось в точности то же самое, используя Elif. Это показано ниже:

If GetWindowName (GetCurrentWindow ()) == "Main" Then
SayString("In the main window.")
ElIf GetWindowName (GetCurrentWindow ()) == "Alternate" Then
SayString("In the alternate window.") Else SayString("Not in a known window.")
EndIf

Здесь мы снова можем отправиться по альтернативным путям. Если окно называется Main, мы идем его путем. Если окно называется Alternate, мы идем его путем. В противном случае мы идем по пути Else. ключевое слово Elif занимает место Else, за которым следует утверждение If. Вы можете использовать столько Elif, сколько захотите.

Операторы If могут быть вложенными. Это означает, что оператор If может быть помещен внутри другого оператора If. Это позволяет вам проверять какое-то условие только в том случае, если существует другое условие. Второе условие If будет проверяться только в том случае, если истинно первое условие. Последовательность утверждений внутри второго блока If-Then будет,таким образом, выполнена, только если оба условия будут сочтены истинными. Не забудьте для каждого оператора If, который вы используете, добавлять ключевое слово Endif. Вот пример вложенных утверждений If-Then:

If GetWindowName (GetCurrentWindow ()) == "Main" Then
If GetWindowClass (GetCurrentWindow ()) == "Edit" Then
SayString("In the main edit window.")
Else
SayString ("In the main window")
EndIf ;Is this an edit window?
Else
SayString ("Not in a known window")
EndIf ;Is this the main window?

В этом примере сначала мы проверяем, находимся ли мы в главном (Main) окне.Если да, то мы проверяем, находимся ли мы в окне редактирования (Edit Window). Если да, то мы говорим, что находимся в главном окне редактирования (Main Edit Window). Если это не окно редактирования, то мы просто говорим, что мы в главном окне. Условие Edit будет проверяться только в том случае, если условие Main является истинным. Обратите внимание, что мы использовали комментарии, чтобы показать, для какого оператор If помещено ключевое слово Endif. Это очень полезно, чтобы избежать путаницы при использовании вложенных операторов If-Then.

Циклы

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

Цикл While - это последовательность действий, которая повторяется, или зацикливается, пока является истинным какое-либо условие, или пока не станет истинным конкретное условие. Цикл While состоит из двух частей - ключевого слова While, которое задает условия, которые должны будут проверяться, и ключевого слова EndWhile, которое завершает цикл.

Все утверждения между While и EndWhile будут выполняться повторно, пока будет истинным условие, приведенное в условии While. Вот пример.

Давайте возьмем довольно обычную проблему. Вы работаете в программе редакторе, которая нумерует строки пятью цифрами. Поэтому первая строка нумеруется как 00001. Jaws тратит массу времени, читая нули. Было бы здорово начать чтение с первой ненулевой позиции, не правда ли? Здесь самое место для цикла While. Рассмотрим следующий скрипт:

Script SayEditLine()
SaveCursor ()
JAWSCursor()
RouteJAWSToPC()
JAWSHome()
While (GetCharacter () == "0")
NextCharacter ()
EndWhile
SayFromCursor()
RestoreCursor ()
EndScript

Использование такого скрипта для чтения номера строки устранит для нас начальные нули. Вот как это делается. Первые четыре строки сохраняют позицию курсора, активизируют Jaws курсор и перемещают его к началу строки, на которой мы находимся. Затем цикл While просматривает каждый символ в начале строки по очереди и смотрит, не ноль ли это. Если ноль, то он просто переходит к следующему символу и тоже его проверяет. когда он находит символ, который не является нулем, условие для продолжения цикла больше не является истинным, и цикл While завершается. Затем JFW продолжает обрабатывать оставшуюся часть скрипта после цикла Whilt. Сюда входит чтение оставшейся части строки от курсора до конца строки. Это избавляет от всех нулей.

Здесь нужно сделать предупреждение относительно циклов While. Поскольку цикл выполняется до тех пор, пока условие не становится истинным или ложным, нужно быть осторожным и не создавать циклы с условием, которое никогда не будет удовлетворено. Если так сделать, цикл будет длиться вечно, бесконечный цикл. Результатом будет блокирование компьютера, пока программа не будет завершена вручную. Внимательно продумывайте условие, которое может завершать цикл, чтобы быть уверенным, что когда-то это условие будет выполнено. Если вы обнаружили, что компьютер заблокирован после того, как вы выполнили новый скрипт с циклом While, вероятнее всего, произошло именно это. Один из способов избежать эту проблему при разработке циклов While - включать некоторые условия, предназначенные для того, чтобы прерывать работу цикла после некоторого числа повторений. Пример такого цикла показан ниже.

While FirstVariable < SecondVariable
Let BreakOutVariable = BreakOutVariable+1 	
(Rest of loop would be here.)
If (BreakOutVariable > 100) Then
Return
EndIf
EndWhile

Этот цикл задуман таким образом, что он будет работать до тех пор, пока первая переменная не станет больше второй переменной. Давайте представим, что мы допустили логическую ошибку, и первая переменная никогда не будет больше второй переменной. Без дополнительных утверждений, призванных предотвратить такой оборот событий,цикл будет работать вечно. Однако, вторая строка добавляет 1 к переменной BreakOutVariable всякий раз, когда цикл повторяется. Когда значение BreakOutVariable превышает 100, утверждение If-Then в конце цикла выполнит возврат и завершит цикл. Если вы уверены, что цикл While работает как положено, вы можете удалить логику прерывания.

Домашнее задание # 5

Для этого домашнего задания давайте опять воспользуемся программой Фонограф. В прошлый раз, когда мы писали скрипт для этой программы, мы обратили внимание, что счётчик над кнопками показывает и время, которое прошло, и полное время звукового файла. Напишите скрипт, используя утверждения If-Then и утверждения Elif, который проверяет, что прошедшее время не является нулем. Если это так, пусть выдается сообщение "В начале записи". Если прошедшее время больше нуля, но меньше полного времени, пусть выдается сообщение "Проигрывание завершено только частично". Если прошедшее время равно полному времени, пусть он говорит "Проигрывание завершено" и щелкает кнопку "Искать начало" или обратную перемотку, чтобы вернуть счётчик к нулю. Затем пусть скрипт сделает паузу, чтобы дать приложению время перемотать обратно, а потом снова проверит счётчик, чтобы посмотреть, находится ли он в нулевой позиции. Если да, пусть он выдаст сообщение "Обратная перемотка завершена". Если счётчик не находится в нулевой позиции, пусть он выдаст сообщение "Обратная перемотка невозможна. Проверьте ваши батарейки". Также воспользуйтесь локальными переменными, чтобы хранить время в целом и прошедшее время.



Распространение материалов сайта означает, что распространитель принял условия лицензионного соглашения.
Идея и реализация: © Владимир Довыденков и Анатолий Камынин,  2004-2019