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

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

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

Структура внешнего вида приложений MS Windows

Вы, вероятно, слышали, как люди используют термины класс окна Window class) и дескриптор окна (handle) в дискуссиях о том, как внешне выглядят приложения в операционной системе MS Windows. Что же означают эти термины? В этом разделе мы объясним иерархию окон, идентификацию и структуру, так что вы сможете воспользоваться функциями скриптов, которые запрашивают и сравнивают эти объекты.

Вопрос первый: что такое окно? Ну, это кажется простым. Программы работают в окнах. Даже Jaws имеет свое окно. Это верно. Окно Jaws - это окно, но вас, возможно, удивит, когда вы узнаете, что любое поле ввода, кнопка или любой другой элемент управления также является окном. По крайней мере, он должен им быть. Как и все другие правила в компьютерных программах, это правило не всегда соблюдается. Программист может создать элементы управления, такие, как поля ввода данных, не делая их фактическими окнами. Доступ к таким программам осуществлять труднее всего, поскольку нет простого способа определить и озвучить различные элементы управления. Для таких программ написание скриптов является еще более необходимым, поскольку скрипты в файлах по умолчанию не будут корректно озвучивать такие окна. На некоторое время мы будем предполагать, что программист присваивает каждому элементу управления свое окно. Звучит, сложно, не правда ли? Давайте посмотрим, сможем ли мы с этим разобраться.

Иерархия

Что же в действительности означает слово "окно" в среде Windows? Большинство людей, конечно, понимает, что большая прямоугольная штука, которая всплывает на экране, когда они открывают новое приложение, является окном, и они, вероятно, считают окном текстовую область своего текстового редактора, но окно - это нечто гораздо большее. В большинстве приложений каждое окно диалога, кнопка меню, поле редактирования, окно списка и т.д., фактически является отдельным окном с одним или несколькими идентификационными номерами, которые можно использовать, чтобы ссылаться на них. Эти номера окон, которые могут присутствовать на экране в любое время, не являются чем-то случайным, с их помощью осуществляется взаимодействие со специальной иерархией, которая позволяет операционной системе Windows и программисту, который в ней работает, отслеживать все эти окна. Все это станет более понятным, если мы рассмотрим иерархию окон в системе. Наиболее часто используется метафора родителей и детей. Выглядит все это примерно так. Рабочий стол вашего компьютера является родительским окном для всех окон приложений. Это означает, что окно Jaws, окно вашего текстового редактора, и окно вашего интернет браузера являются детьми рабочего стола. Эти окна находятся уровнем ниже, чем рабочий стол, поэтому все они являются детьми рабочего стола и находятся на одном и том же логическом уровне.В этом смысле все они равны друг другу, и покда вы позже столкнетесь с терминами "Предыдущее окно" или "Следующее окно", то речь будет идти о перемещении между равными окнами на одном и том же уровне иерархии окон.

Ладно, давайте перейдем на следующий уровень. Текстовый редактор имеет несколько дочерних окон: текстовая область, линейка меню, панель инструментов и строка состояния. Все они являются детьми окна текстового редактора, расположенными на одном и том же логическом уровне. Начинает проясняться? Когда вы просите открыть файл в текстовом редакторе, появляется дочернее окно, так что вы можете поискать свой файл. Часто это окно диалога, но, по большому счету, это дочернее окно текстового редактора, своего родителя. Теперь рассмотрим диалог открытия файла в качестве родителя, и вы обнаружите, что поле имени файла является дочерним окном диалога. Таковыми же являются и все другие поля внутри диалога. Все они являются детьми родительского диалога и находятся на одном и том же логическом уровне.

Каждое окно является дочерним по отношению к окну, находящемуся на один уровень выше, которое его открыло или сгенерировало, и каждое окно является родителем в отношении окон, находящихся уровнем ниже, т.е. окон, которые открыло это окно.

Просто на тот случай, если у вас остались некоторые проблемы, чтобы визуально представить все это, давайте попробуем воспользоваться аналогией. Большинство людей знакомо со структурой дерева каталогов по опыту работы в DOS или в Проводнике Windows. На вашем диске, скажем, диске C, C:\ является родителем всех других директорий на диске. Все поддиректории, находящиеся на один уровень ниже C:\, являются детьми этого родителя и находятся на одинаковом логическом уровне. Таким образом, если у вас есть поддиректории с именами Eudora, JFW33, Myljcuments, Recycled и Windows, все они будут находиться на один уровень ниже от c:\. Все они являются прямыми детьми C:\ и все они находятся на один логический уровень ниже. Для целей структуры дерева каталогов и иерархии окон вы можете допустить, что находиться на одном и том же логическом уровне означает, что все члены были порождены или сгенерированы одним и тем же родителем. Вспомните, мы сказали, что команды "Предыдущее окно" и "Следующее окно" можно использовать для перехода к окнам на одном и том же логическом уровне? Так вот, в отношении дерева каталогов, это может означать перемещение к предыдущей директории или к следующей директории в дереве каталогов. Если мы откроем поддиректорию JFW33, мы увидим 4 новые поддиректории - Help, Cettings, Manuals и Tecnotes. Все эти 4 поддиректории находятся уровнем ниже JFW33, являются детьми JFW33 и все они находятся на одном логическом уровне, и находятся на два уровня ниже, чем c:\. Конечно, это может продолжаться до тех пор, пока мы не достигнем самого нижнего уровня конкретной ветви.

Структура окон "родитель-дитя" работает во многом аналогично структуре каталогов. Каждое приложение является веткой дерева, и им порождаются дочерние окна. Все окна уровнем ниже родительского приложения, являются детьми на одном и том же логическом уровне, уровнем ниже относительно родителя. Каждое из этих окон-детей может само порождать детей, и эти дети будут находиться на три уровня ниже родительского приложения. Попробуйте поперемещаться вверх и вниз по разным логическим уровням различных ветвей вашего дерева каталогов в Проводнике Windows, и вы лучше почувствуете эту иерархию родителей/детей.

Идентификация окон

Программист, создающий приложение, присваивает каждому окну некоторое количество идентификаторов. Эти идентификаторы позволяют недвусмысленно обращаться именно к запрашиваемому окну. Например, каждое окно имеет класс, тип, код типа, код подтипа, и управляющий идентификатор.

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

Классы окон, типы, коды типов и коды подтипов

Класс окна - это категория, которая обозначает некоторую информацию о том, чем является окно и что оно делает. Например, классом окна может быть Edit Field (поле редактирования), ListBox (окно списка), или Button (Кнопка). Это уже является ценной информацией об окне, поскольку мы знаем, что ListBox - это нечто совершенно отличное, и он будет иметь совершенно другие требования к чтению, нежели Button (Кнопка). Проблема состоит в том, что класс окна не всегда предоставляет достаточно подробную информацию для наших целей. Например, проверка класса окна возвратит одну и ту же информацию для кнопки, радиокнопки и блока проверки, поскольку все они принадлежат к классу Button. Очевидно, в некоторых случаях нам понадобится более подробная информация.

Другие категории окон, перечисленные ниже, можно использовать для получения этой информации. Кроме того, некоторые программисты используют пользовательские классы окон (custom window classes), имеющие странные и нераспознаваемые имена, которые Jaws не понимает. Нам понадобится некоторый способ, чтобы сообщить Jaws, как обращаться с этими пользовательскими классами окон, и об этом речь пойдет ниже.

Класс окна можно получить с помощью функции GetWindowClass.

тип окна (Window type) - как и в случае с классом окна, тип окна возвращает строку или имя, которое в отношении окна является описательным. Иногда эта категория может дать более конкретную информацию о некоторых окнах. Однако, запрос о типе окна возвратит ту же самую информацию об окне, что и запрос класса окна, если никакой более конкретной информации нет. Например, класс окна и тип окна Edit Field (поле редактирования) будут в точности одним и тем же. Однако, если доступна более конкретная информация, типом окна можно воспользоваться, чтобы разобраться с этим. Так, если класс окна кнопки, радиокнопки или блока проверки будет всегда "button", то типы окна всех этих трех окон будут сообщаться как "Button", "Radiobutton" и "Checkbox". Такая конкретная информация позволит нам сообщить Jaws, как поступать с каждым из этих типов. Если программист использовал пользовательские классы окон Custom window classes), то запрос типа окна возвратит строку, которая говорит, что тип окна неизвестен. Однако, когда пользовательский тип окна (custom window type) переклассифицирован на известный класс окна (см. ниже), тип окна вернет имя переклассифицированного окна и, таким образом, сообщит нам, что делает окно.

Единственная проблема с типом окон состоит в том, что строка, возвращаемая этой функцией, всегда по-английски, и поэтому не очень-то полезна для тех, кто использует Jaws на других языках. По этой причине был разработан код типа окна.

Тип окна можно получить с помощью функции GetWindowType.

Код типа окна (Window type code) - запрос кода типа окна возвращает число, а не строку. Это число переводится в понятную строку с помощью определений констант, которые можно найти в файле HJCONST.JSH. В этом файле вы увидите такие, например, строки:

WT_Button =1,
WT_Edit = 3,
WT_ListBox = 4,
WT_ScrollBar = 5

Префикс константы WT сообщает вам, что эта константа относится к типу окна. Хотя код типа окна не сообщает нам больше информации, чем тип окна, его преимущество заключается в том, что он является независимым. Поскольку для данных типов окон всегда возвращаются одни и те же номера, числа можно приравнять к строкам на любом из возможных языков. Код типа окна можно получить с помощью функции GetWindowTypeCode.

Код подтипа окна - как и в случае с типом окна, код подтипа окна также возвращает целое число. Коды подтипа окна также переводятся в строки с помощью тех же определений констант, что и для кода типа окна. Единственное различие состоит в том, что код подтипа окна предоставляет более подробную информацию, если она доступна. Если нет, обе функции возвратят одну и ту же информацию. Например, радиокнопка возвратит код типа окна 1, (WT_Button) но код подтипа 19 (WT_RadioButton). Кнопка "Пуск", находящаяся на панели задач, также вернет код типа 1 (WT_Button), но вернет код подтипа 32 (WT_StartButton). Аналогичным образом, GetWindowTypeCode вернет WT_TABCONTROL для панели задач, тогда как GetWindowSubtypeCode вернет WT_TASKBAR. Вам захочется использовать GetWindowTypeCode, когда вам не нужна более конкретная информация, которую возвращает GetWindowSubtypeCode. Коды подтипов окон также независимы с точки зрения языка. Их можно получить с помощью функции GetWindowSubtypeCode.

Причина, по которой эти категории окон так важны для пользователей Jaws состоит в том, что Jaws будет вести себя по-разному, в зависимости от того, к какой категории принадлежит окно, содержащее фокус. Например, если фокус находится в поле редактирования, Jaws отслеживает каретку, или курсор вставки. Если вы нажимаете клавишу "Стрелка вниз", Jaws озвучит строку текста, на которую переместилась ваша каретка. С другой стороны, если вы находитесь в списке или в меню, Jaws отслеживает выделение или курсорную рамку, когда используются клавиши-стрелки, чтобы перемещаться вверх и вниз по списку. Jaws знает, что надо делать, благодаря скриптам, ассоциированным с клавишами "Стрелка вверх" и "Стрелка вниз" в файле скриптов default.jss. Эти скрипты содержат логику, которая определяет, что делать, основываясь на категории окна, в котором находится фокус, когда вы используете одну из этих клавиш. Если вы внимательно изучите скрипты SayPriorLine и SayNextLine в файле default.jss, вы увидите, что решения, в отношении того, что говорить, принимаются, основываясь на кодах типа и подтипа окон, которые являются текущими, когда вызывается скрипт.

Как и в случае с типами окон, кодами типов, кодами подтипов окон, существует стандартный набор классов окон, которым пользуется большинство программистов, и Jaws скрипты по умолчанию содержат необходимую логику, чтобы обеспечить нормальное озвучивание таких стандартных классов в большинстве случаев. Однако, классы окон не всегда настолько стандартны, как другие категории. Если вам когда-либо пришлось воспользоваться диалогом классов окон в диспетчере конфигурации, чтобы переназначить пользовательский или неизвестный класс окон, вы знаете, что иногда программист создает пользовательские классы окон, о которых мы должны информировать Jaws. Поскольку эти пользовательские классы по определению являются нестандартными, Jaws не имеет никакого понятия, что с ними делать. Поэтому мы должны воспользоваться диспетчером конфигурации, чтобы приравнять неизвестный класс к одному из известных классов, чтобы Jaws знал, как себя вести, когда ему встретится такое окно. Этот процесс называется переклассификацией или переназначением класса окна. Если вы никогда не пользовались этой процедурой, воспользуйтесь или комбинацией клавиш Insert+7, или комбинацией клавиш Insert+F2, после чего нажмите W, а затем Enter, чтобы вызвать диалог переназначения класса окон (Window Class Reassign), и поизучайте различные элементы управления, чтобы познакомиться с ними.

После того, как вы переклассифицировали окно, приравняв его к стандартному классу, оно должно озвучиваться как положено. Иногда вам придется попробовать не один класс, чтобы понять, какой работает наилучшим образом.

Идентификаторы элементов управления и дескрипторы (handles) окон

Идентификатор элемента управления или контрольный идентификатор (Control ID) - это произвольное число, которое служит в качестве идентификатора, который программист использует для того, чтобы пометить каждое окно в своей программе. Этот идентификатор можно узнать с помощью функции GetControlID. Идентификатор элемента управления, в отличие от класса окон, никакого специального значения не имеет, но им можно воспользоваться, чтобы обратиться к конкретному окну. В идеальном случае, никакие два окна в программе не должны иметь одинаковых контрольных идентификаторов, но иногда все же такое происходит. Если вы знаете, как получить доступ к контрольному идентификатору, и если он является уникальным в приложении, для которого вы пишете скрипты, то вы можете заставить Jaws проделать некоторые вещи, если он обнаружит, что фокус вашей системы находится в окне с определенным идентификатором.

Один пример, где это чрезвычайно важно, это приложения, где кнопки обозначены рисунками, а не текстовыми ярлыками. В обычном случае Jaws озвучит текстовый ярлык кнопки, когда вы переместитесь на нее клавишей Tab, но если ярлыком является рисунок, то текста для озвучивания просто нет. С помощью определения контрольных идентификаторов различных графических кнопок, можно написать скрипт, который будет озвучивать название кнопки, когда фокус переместится на кнопку с конкретным контрольным идентификатором.

Конечно, нет никакой гарантии, что два окна в различных программах не будут иметь один и тот же контрольный идентификатор. Поэтому, чтобы предотвратить путаницу, система присваивает уникальный идентификатор, который называется дескриптором окна (a window handle), каждому окну, к которому она осуществляет доступ во время данной конкретной сессии. Дескрипторы окон являются числами,но они не являются неизменными значениями, в отличие от контрольных идентификаторов. Пока дескриптор назначен конкретному окну, им можно пользоваться, чтобы ссылаться на это окно и идентифицировать его. Когда дескриптор будет назначен, он остается активным, пока существует окно. Однако, когда окно уничтожается, оно освобождает дескриптор. Если окно повторно вызывается позже, оно, вероятнее всего, получит другой дескриптор.

Поскольку система назначает дескрипторы, пока окна используются, Дескриптор, назначенный окну сегодня, может быть не тем же самым, каким он будет завтра. Хорошей аналогией для дескриптора будет пронумерованный распределитель билетов, используемый во многих булочных и магазинах деликатесов. Когда вы входите, вы берете номерок у распределителя, и этот номерок становится вашим дескриптором на сей день. Сегодня ваш номер может быть 31, и когда кассир скажет 31, вы будете знать, что это ваша очередь. Если вы придете в другой день, у вас, вероятнее всего, будет другой номер, но он по-прежнему будет вашим дескриптором, хотя он и не тот, каким он был в предыдущий раз. Смысл заключается в том, что это система идентификации, которая сообщает служащему, кто следующий в очереди.

Используйте дескриптор окна, чтобы выделить его среди других окон в системе в данное конкретное время. дескриптор окна можно получить с помощью встроенных функций GetCurrentWindow () и GetFocus (). Одним из способов проделать это будет, например, воспользоваться функцией GetCurrentWindow () в качестве параметра для функции SayInteger (). Таким образом, SayInteger (GetCurrentWindow ()) сообщит дескриптор окна, содержащего активный курсор.

Есть некоторые встроенные скрипты по умолчанию, которыми вы можете воспользоваться, чтобы запросить эти и другие типы информации из приложения. Мы научим вас, как пользоваться ими в разделе "Изучаем приложение с помощью функций утилит".

А пока что попробуйте следующее: нажмите клавиши Insert и Ctrl, и не отпуская, нажмите клавишу F1. Вы должны услышать, как будет сообщен контрольный идентификатор, класс окна и дескриптор окна, в котором вы в данный момент находитесь. Походите по разным окнам и по разным приложениям, чтобы составить некоторое представление о том виде информации, которую можно получить с помощью этой комбинации клавиш.

Строительные блоки языка скриптов

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

Сначала мы изучим, как собирается отдельный скрипт, а затем мы узнаем все другие виды утверждений в этом языке. В разделе "Техника написания скриптов" мы узнаем, как объединять вместе законченные файлы скриптов и как их компилировать и использовать.

Скрипт

Как мы уже сказали прежде, скриптом называется небольшая компьютерная программа, которая контролирует деятельность Jaws. Скрипты можно (но н можно и не закреплять) закрепить за клавишами.

Скрипт должен иметь следующие части, в точности соблюдая нижеприведенный порядок: сначала идет ключевое слово, начинающее скрипт. Это просто слово "Script", после чего идет пробел.

На этой же строке, после слова "Script", приводится его имя. Обычно это несколько слов, объединенных вместе и описывающих действие скрипта, как, например, CloseDocumentWindow (ЗакрытьОкноДокумента). Обратите внимание, что каждое из объединенных слов начинается с заглавной буквы, чтобы Jaws мог правильно прочитать название. После имени записывается (), чтобы завершить начальное утверждение скрипта. Все это автоматически добавляется диспетчером скриптов, когда вы создаете скрипт.

Далее следуют объявления всех локальных переменных, после чего идут все функции, арифметические операции и операторы, управляющие ходом выполнения скрипта.

Это может быть и чем-то очень простым, например озвучивание строки, как мы делали в нашем первом скрипте, и чем-то более сложным.

Оператор окончания скрипта, EndScript, всегда является последней строкой скрипта. Она также автоматически добавляется диспетчером скриптов, когда вы создаете скрипт.

Диспетчер скриптов корректно создаст базовую структуру скрипта, когда вы выберете "New Script" в меню "Script", или воспользуетесь клавишей-ускорителем CTRL+E. Вы всегда должны создавать скрипты таким образом, поскольку диспетчер скриптов также запросит у вас соответствующее описание скрипта и позволит вам назначить комбинацию клавиш для вызова скрипта.

Функция

Самая большая разница между скриптом и функцией состоит в том, что функция не может быть связана с комбинацией клавиш. Она либо будет вызываться из скрипта, либо из другой функции, либо будет запускаться системным событием. Важно напомнить вам о некоторых жаргонных словечках, которые мы обсудили прежде. Это слово "Функция" имеет несколько слегка различных значений, и важно иметь их в виду для последующей дискуссии.

Мы близки к тому, чтобы поговорить о функциях, которые могут быть созданы вами, и под этим мы будем подразумевать скрипт, который вы напишете, и который не будет закреплен за клавишей. Это функция, определяемая пользователем (User-defined function), имея в виду, что она написана вами, пользователями. Также имеются функции, уже присутствующие в файлах скриптов, и которые вы можете модифицировать, и эти функции были написаны авторами скриптов из Henter-Joyce. Это тоже функции, определяемые пользователем, но их определяли другие пользователи, а не вы. И наконец, имеются встроенные функции, которые являются строительными блоками языка Jaws. Вы, пользователи, не можете модифицировать встроенные функции, как вы можете модифицировать свои собственные функции, или функции, написанные другими людьми. Вы можете использовать любой из этих трех типов функций, как строительные блоки, когда будете писать скрипты или новые функции, но встроенные функции жестко закодированы в Jaws, и поэтому дальнейшее обсуждение их не затрагивает. (Встроенные функции будут обсуждаться позже).

Пользовательская функция должна иметь следующие части, в точности соблюдая следующий порядок:

  • тип возвращаемого значения (Handle, int, Object, String или Void)
  • Начальное ключевое слово "Function", после которого следует пробел.
  • На той же строке, где написано слово "function", записывается имя функции. Обычно это несколько слов, объединенных вместе, которые описывают действие этой функции, например, SayFocusedWindow (НазватьОкноСФокусом). Обратите внимание, что каждое из объединенных слов начинается с заглавной буквы. Таким способом Jaws может правильно прочитать название, как если бы это были отдельные слова.
  • После имени функции следуют круглые скобки - (), завершающие заголовок функции.

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

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

С другой стороны, кроме завершения любых других задач, функция также может передать целое число, строку, объект или дескриптор (handle), обратно в вызывающий скрипт. Если именно это она и делает, вы должны увидеть слово String, Object, или Handle перед словом Function на первой строке.

Специальные имена функций событий, такие, как AutoStartEvent или NewTextEvent сообщают вам, что функция запускается автоматически, когда в приложении происходят определенные события. Эти функции обычно не вызываются другими скриптами или функциями.

Между скобками ( и ) могут находиться параметры, которые используются для того, чтобы передать информацию функции, которая понадобится ей, чтобы выполнить свою задачу. Позже мы все это обсудим более подробно.

После заголовка функции следуют объявления всех локальных переменных, после чего идут все функции, арифметические операции и операторы контроля выполнения скрипта.

Оператор окончания функции, EndFunction, всегда является последней строкой функции. Диспетчер скриптов автоматически создаст базовую структуру функции, когда вы выберете New Script из меню Script. Вы всегда должны создавать функции таким образом, поскольку диспетчер скриптов также запросит соответствующее описание функции и позволит вам указать параметры функции и тип возвращаемого значения.

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

Но есть также много различий. Если мы описываем особенности, которые имеют отношение только к скрипту или только к функции, мы обязательно укажем на это. В противном случае правило применяется равным образом и к скриптам, и к функциям.

Типы утверждений

Ниже приводится список типов утверждений, из которых состоят скрипты. Каждое утверждение подобно части речи в языке скриптов Jaws, и выполняет специфические задачи и его использование подчиняется определенным правилам.

Комментарии

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

Включения (Include)

Оператор включения (Include) сообщает компилятору, что наряду с этим файлом он должен включить содержание другого файла, так, как если бы эта информация была набрана в главный файл на том месте, где находится оператор include. Следовательно, вся информация во включенном файле доступна для главного файла от точки включения и до конца главного файла. Это означает, что все включенные файлы будут скомпилированы наряду с главным файлом, в один большой .jsb файл. Файлы включения - это отдельные файлы с общими пунктами, которые могут оказаться полезными для нескольких файлов скриптов, или которые вы можете пожелать хранить по отдельности из соображений ясности или удобства.

Есть два типа файлов включения: файлы заголовков (Header files) обозначены с помощью расширения .JSH и содержат или объявления переменных, или объявления констант.

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

В версиях Jaws до 3.0 иногда было необходимо разбивать файлы макросов на куски, чтобы избежать превышения максимально допустимого размера. В отношении файлов скриптов такой проблемы нет, поскольку они могут быть настолько большими, насколько это необходимо.

Оператор include требует указания имени включаемого файла, заключенное в кавычки следующим образом:

Include "HJGLOBAL.JSH"

Если вы забудете поставить кавычки, синтаксис будет неверным, и вы получите сообщение об ошибке, когда попытаетесь скомпилировать файл. Также предполагается, что файл, который нужно включить, содержится внутри директории расположения скрипта (Например, поддиректории ENU в поддиректории \SETTINGS в директории, где находится Jaws).

Ниже приводится список стандартных include файлов, поставляемых с Jaws и включенных в default.jss:

  • HJGLOBAL.JSH - содержит глобальные переменные JFW.
  • HJCONST.JSH - содержит глобальные константы JFW по умолчанию.
  • DEFAULT.JSM - содержит стандартные сообщения, на которые ссылается default.jss.

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

Если файл default.jsm содержит сообщения, полезные только для default.jss, HJGLOBAL.JSH и HJCONST.JSH используются в любом файле скриптов, который ссылается на глобальные переменные Jaws и его константы.

Домашнее задание 4

Представьте, что вы начинаете строить файл скриптов для приложения, которое называется JAWSWINS.EXE. Вы хотите использовать операторы включения (include) для файла заголовка констант и переменных, файл сообщений для сообщений и два файла Jaws, HJCONST.JSH и HJGLOBAL.JSH. Напишите операторы включения, необходимые для этой цели.

Переменные

Переменная, как мы уже говорили ранее, и как подразумевает ее название, это некая сущность, которая имеет некоторое значение, и это значение может изменяться во время выполнения кода. (Термин "Выполнение" используется программистами для описания работы кода, т.е. компьютерной программы, такой, как скрипт. Здесь мы используем его, чтобы познакомить вас с термином). Переменные должны быть "объявлены", или заданы, они должны иметь имя и тип, прежде чем их можно будет использовать. Каждая переменная должна иметь свое имя, которое будет отличать ее от других функций и имен, использованных в коде. Будьте внимательны, и не используйте имена, которые уже присвоены функциям, глобальным переменным и константам, поскольку это может вызвать проблемы при компиляции или выполнении.

Ниже приводится описание типов переменных, допустимых в языке скриптов Jaws:

Integer - переменная, предназначенная для хранения целочисленного значения. (Integer - это целое число, не содержащее десятичную точку). Переменная объявляется так:

Int MyIntegerVariable

Обратите внимание, что после типа (int) следует уникальное имя, присвоенное этой переменной (MyIntegerVariable).

Переменная типа integer хранит целочисленные значения. Мы используем переменную таким образом, чтобы ее значение могло изменяться под действием, которое имеет место, пока наш файл скриптов является активным, и так, чтобы мы могли обратиться к этому числу по имени в наших скриптах.

К использованию переменной integer применяются следующие правила:

  1. Переменная integer должна быть объявлена прежде, чем ее можно будет использовать.
  2. Ее значение по умолчанию, то есть, значение до того, как ей присвоено какое-либо значение, всегда равно нулю.

String - хранит строку символов. String - это группа символов, включая буквы, цифры, знаки препинания и пробелы. Эта переменная объявляется так:

String MyStringVariable

Мы используем переменную для представления нашей строки, потому что строка, которую она содержит, может изменяться всилу действий, которые имеют место, пока наш скрипт файлов является активным, и таким образом мы можем обратиться к текущей строке по имени в наших скриптах.

К использованию переменной типа string применяются следующие правила:

  1. Переменная string должна быть объявлена прежде, чем ее можно будет использовать.
  2. Ее значение по умолчанию всегда "null" или никаких символов.

Когда вы присваиваете значение переменной String, вы должны помещать строку в двойные кавычки. Например, корректным будет следующий синтаксис:

Let StringVariable = "Hello"

Обратите внимание, что в версиях Jaws ранее 3 вы должны были помещать пробел между кавычками, когда вы проверяете на нулевое значение. Теперь все изменилось. Null показывается двумя кавычками, без пробела между ними.

Handle - хранит дескриптор окна. Дескриптор окна (Window handle) - это уникальный номер, который система присваивает каждому окну в активном приложении. Переменная объявляется так:

Handle MyHandleVariable

Вы, вероятно, помните из нашего предыдущего описания идентификаторов окон, что дескриптор окна присваивается системой и является уникальной для конкретного окна. Хотя handle также является целым числом и им, следовательно, можно манипулировать как всеми остальными целочисленными значениями, использование переменной handle зарезервировано единственно для идентификации дескриптора окна. В большинстве случаев мы будем использовать ее, чтобы идентифицировать конкретное окно, информация из которого нам нужна.

К использованию переменной handle применяются следующие правила:

  1. Переменная типа Handle должна быть объявлена, прежде чем ее можно будет использовать.
  2. Ее значение по умолчанию равно нулю.

Object - это переменная, предназначенная для хранения объекта. Объект, для целей языка скриптов Jaws, обращается к типам объектов, представленных в некоторых приложениях Microsoft, таких, как Office 97 suite. Переменная объявляется так:

Object MyObjectVariable

Переменная типа object используется для хранения объекта, который был возвращен в Jaws скрипт или функцию. Ее роль заключается в том, чтобы получать определенные виды информации из некоторых приложений Microsoft, которую обычно очень трудно или невозможно получить, просто озвучивая экран. К использованию переменной object применяются следующие правила:

  1. Переменная типа object должна быть объявлена прежде, чем ее можно будет использовать.
  2. Ее значение по умолчанию всегда Null или Empty (пусто).

Переменные могут быть локальными, что означает, что они могут использоваться в скрипте, в котором они объявлены, и глобальными, что означает, что они могут использоваться в любом скрипте в файле скриптов, где они определены. Глобальные переменные могут быть объявлены в начале файла скриптов, с помощью заголовка globals. Поместите эту группу сразу же после операторов include. Глобальные переменные также могут быть объявлены в include файле, как это сделано в случае с файлом скриптов по умолчанию и его заголовочным файлом HJGLOBAL.JSH. Если этот файл включен, глобальные переменные, объявленные в этом файле, можно использовать в любом скрипте по умолчанию. Вам следует создать заголовочный файл для переменных, которые вы намерены использовать в нескольких файлах скриптов. Если вы объявляете глобальную переменную, которую вы намерены использовать только с одним приложением, то будет лучше объявить эту переменную прямо в файле скриптов, а не в файле заголовков, и включить имя приложения в в имя переменной. Это послужит тем, что сообщит пользователю, что это глобальная переменная, предназначенная для использования только в этом приложении. Пользователь также должен понимать, что коль скоро переменная создана и ей присвоено какое-то значение, это значение остается в памяти, даже после того, как приложение, которое ее использовало, было закрыто. Если приложение открыто снова во время одной и той же компьютерной сессии, глобальные переменные из файла скриптов для этого приложения будут иметь те же значения, которые они имели перед тем, как программа была закрыта.

Единственный способ очистить глобальные переменные - выгрузить, а потом снова загрузить Jaws.

Локальные переменные объявляются в скрипте в первом утверждении после начального оператора скрипта. Они имеют заголовок Var.

Вот как выглядит каждый класс переменных в примере, взятом из стандартного файла скриптов.

Следующие операторы объявления взяты из WINWORD.JSS, файла скриптов для Microsoft Word For Windows. Обратите внимание, что большая часть имен глобальных переменных начинается со слова Global, так чтобы их легко можно было отличить от локальной переменной. Соглашения о присвоении имен будут подробно обсуждаться позже, когда мы будем обсуждать технику написания скриптов.

 Globals
String GlobalWinwordVersion,
Int GlobalCurrentControl,
Handle GlobalRealWindow,
String GlobalRealWindowName,
Int WinWordFirstTime,
; to say auto start message only first time Handle WinWordContextHandle,
; read word in context Int WinwordFontCode ; when font buttons are pushed

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

Следующее утверждение объявления локальной переменной взято из функции HotKeyHelp97 () в WINWORD.JSS, файла скриптов для Microsoft Word For Windows. Как показано ниже, объявления переменной появляются сразу же после заголовка функции:

 Function HotKeyHelp97 ()
var 	
handle WinHandle, 	
Int verbosity

Здесь также все строки, за исключением последней, заканчиваются запятой.

Константы

Как мы уже сказали прежде, константы - это способ использовать легко запоминающиеся имена для сохранения труднозапоминающихся строк символов или чисел. Константы можно представить в виде некоторого числа или группы букв или слов, которым дали, или присвоили, новое имя. Это делается по чисто мнемоническим соображениям, поскольку гораздо легче запомнить имя, чем число или длинный ряд чимволов или слов. Нет никаких ограничений на то, сколько имен констант вы присвоите числу. Например, в стандартном файле констант Jaws, и константам TRUE, и ON, присваивается значение 1. Это означает то, что вы можете написать утверждение скрипта, чтобы проверить, соответствует ли условие TRUE, On или 1. Все они рассматриваются как имеющие одно значение, коль скоро константы были объявлены. Мы настоятельно рекомендуем вам пользоваться константами, поскольку гораздо труднее запомнить, что когда что-либо истинно, его состояние равно 1, но легко понять разницу между TRUE и FALSE (истиной и ложью). Кроме того, когда кто-то другой читает ваш файл скриптов, ему будет гораздо легче понять, что вы хотели сделать, если они увидят хорошо поименованные константы, а не числа. И наконец, если вам нужно изменить значение числа, которое используется в нескольких местах, вы можете изменить их все сразу, если вы использовали константу для представления этого числа, просто изменив значение объявления константы.

Константы объявляются в начале файла скриптов с помощью заголовка группы Const, следующим образом:

 Const 	
True = 1, 	
False = 0, 	
On = 1, 	
Off = 0

Пожалуйста, обратите внимание, что все строки, за исключением последней, заканчиваются запятыми. Авторы скриптов иногда определяют свои собственные константы для файла скриптов, но они часто используют те, которые уже объявлены в HJCONST.JSH. Если это так, они не должны забывать включить этот файл заголовков. Мы рассмотрим значения констант в этом файле в разделе "Техника написания скриптов".



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