
              3. Экран и клавиатура

A.  Обзор

ОPCRT - это расширенный  аналог       стандартного модуля CRT
Turbo Pascal. Будучи      полностью   совместимым    с  CRT ,
модуль ОPCRT предлагает широкий набор усовершенствований.  Вы
найдете  всевозможные  процедуры  для  перемещения  курсора и
изменения его формы, считывания символов и строк с    экрана,
процедуры  для   прямой  записи   в  видеопамять   с  высокой
скоростью, процедуры для сохранения и восстановления    окон,
процедуры для включения и выключения 43-строчного режима  EGA
и 50-строчного VGA без чистки экрана, процедуры для работы  с
клавиатурой и  так  далее.    ОPCRT  также   позволяет    вам
вести запись на любую страницу видеопамяти цветного адаптера,
таже процедурой Writeln; и поддерживает многоэадачные режимы,
типа  DesqView или OmniView.

OPCOLOR просто определяет наборы констант, таких как   "White
On Black" или "BlackOnLtGray", которые могут быть использова-
ны в определенных видеоатрибутах. OPMOUSE предоставляет   об-
ширный набор программ низкого   уровня, облегчающих   решение
проблемы поддержки "мыши" вашей программой. Вы можете исполь-
зовать многочисленные программы считывания с  кнопок    мыши,
считывания позиции курсора мыши, стирания и    восстановления
курсора мыши, и так далее. Эти программы служат   основой для
поддержки мыши на высоком  уровне,  описанной   в   OPWINDOW,
ОPENTRY, OPMENU и других программах, позволяющих работать с
окнами.
Hаконец,  OPCMCD  предлагает  средства  по  переводу  нажатий
клавиш на  клавиатуре  и  кнопок мыши в абстрактные "команды"
(перемещение курсора вверх, вниз, выход и т.д.) В  дополнение
к определению стандартного   набора     кодов   команд, OPCMD
определяет два объектных   типа:   CommandProcessor,  который
используется для перевода нажатий  клавиш  в  команды   путем
просмотра   заданной   пользователем    таблицы   команд;   и
СommandPacker, который используется для   распаковки  данных,
заложенных в таблице команд,   делая  их  более  удобными для
изменения. CommandProcessor используется повсеместно в Object
Рrofessional, обеспечивая возможность легкого переопределения
клавиш. CoмmandPacker  упрощает   написание   инсталляционных
программ, таких как DPINST.




    B.OPCRT: усиленный модуль CRT.

Как указывалось в начале  этой    главы,    OPCRT    является
более  усиленной   версией  CRT.   Если  вы   не  используете
какие-нибудь из  его расширений, ваша программа  почти всегда
будет вести себя  также, как если  бы вы использовали  вместо
этого  CRT, однако  существует  несколько  тонких,  но важных
pазличий.

(1)   OPCRT   поддерживает   все   видеостраницы   на цветных
графических  адаптерах,  а  не  только  страницу  0.  Если вы
переключаете видеостраницы, вызывая  SetVisibePage, вы можете
продолжать использовать  Read, Write,  Goto XY  и так  далее.
СRT не позволит вам это сделать.

(2) В отличии от CRT,  OPCRT в очень большой степени  зависит
от глобальных переменных, которые он определяет: CurrentPage,
СurrentMode, ScreenWidth,  ScreenHeight,    CurrentDisplay  и
VideoSegment.  В  то  время  как  СRT   постоянно   вычисляет
начальный  адрес  для  видеопамяти, OPCRT  этого  не  делает,
а берет его из переменной  VideoSegment, предполагая, что оно
правильное.   Это   предположение позволяет экономить  время,
и  позволяет  многим  программам   работать  с   виртуальными
экранами, что было бы  невозможно   другим способом; но   это
также означает, что вообще  говоря вы   должны   использовать
процедуры из OPCRT  для  изменения   видеорежимов,  изменения
страниц  памяти  и установки 43/50  страничного режима . Если
Вы используете другую  процедуру для выполнения этих функций,
например, графическую, то   вам   необходимо  тогда   вызвать
GetCrtMode  (переустанавливающую   СurrentMode,  ScreenWidth,
ScreenHeight,  CurrentPage,   CurrentDisplay,  VideoSegment),
если  вызвать процедуру  ReinitCRT. Кроме того, если вы пишете
ТSR, то вам необходимо вызвать одну из двух процедур на входе
Вашей резидентной программы (обычно ReinitCRT).

(3) Все процедуры для  клавиатурного ввода записаны с  учетом
ТSR. Если вам нужно написать TSR, который использует  обычные
процедуры ввода модуля CRT (ReadKey, Read, ReadLn),    то вам
придется часто выключать другие  TSR (например, SideKick   не
может появиться на входе вашего TSR во время ожидания   вами
нажатия клавиши). OPCRT позволяет вам избежать этой проблемы.

(4)  OPCRT   работает с глобальной   переменной  Buflen, опи-
санной в Turbo 3, но отсутствующей в дальнейших       версиях
Турбо Паскаля , которая позволяет  вам  ограничивать    длину
строки, считываемой с  помощью Read и  Readln. Например  если
Вам  требуется ограничить  строку MyString   до  10 символов,
добавьте в вашу программу следующие строки :
BufLen:=10;
Readln  (MyString);
По умолчанию BufLen paвна 126, и она переустанавливается   на
это значение после каждого оператора Read и Readln.

(5) При инициализации OPCRT автоматически распознает  наличие
дисплейных адаптеров Compaqs и Zenith (не все модели, а  лишь
некоторые), не требующих предотвращения появления "снега"  на
экране, и соответственно устанавливает переменную  CheckSnow.
Это позволяет кардинально улучшить качество изображения    на
этих машинах.

(6) OPCRT поддерживает многозадачные режимы, типа DesqView  и
ОmniView.

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

               Процедуры и функции

               Совместимость с CRT

Хотя OPCRT обеспечивает высокую степень совместимости  с CRT,
между ними нет полной взаимозаменяемости  так же, как    и  с
известными стандартными   модулями   GRAPH3   и  TURBO3. Если
вы попытаетесь использовать  какой-либо  из  этих  модулей в
программе, которая  также  использует и OPCRT, возникнут кон-
фликты.
Чтобы предотвратить "борьбу" между двумя модулями за управле-
ние экраном, OPCRT содержит код, который проверяет присутствие
в программе модуля CRT и совершает аварийный останов програм-
мы при его обнаружении. При старте программы производится на-
чальная проверка; позже, в ходе работы программы, также произ-
водятся проверки "присутствия" CRT (на случай того, если CRT
был инициализирован после OPCRT).  Эти проверки производятся
при вызове определенных ключевых процедур.
Лучшим разрешением проблемы "конфликтов" между модулями являет-
ся отказ от использования GRAPH3 или TURBO3. Эти модули были
pазработаны фирмой Borland для облегчения адаптации программ,
написанных для более ранних версий компиляторов. Советуем вам
в процессе адаптации Вашей программы исключить из нее все, что
требует использования GRAPH3 и TURBO3, путем   использования
модуля GRAPH вместо первого, и удаления процедур, требующих
наличия последующего.
Если этот вариант неприемлем, существует альтернативное реше-
ние. В OPDEFINE.INC вы можете найти следующую строку:
(.$DEFINE UseCrt}
Если вы удалите точку перед знаком '$' и откомпилируете OPCRT
заново, то он станет полностью совместимым с CRT. Все вызовы
программ, содержащихся в CRT, будут заменены вызовами соответ-
ствующих им программ OPCRT, и все глобальные переменные, объяв-
ленные в обоих модулях, будут объединены и доступны. Таким
образом, переменная из OPCRT будет объявлена точь в точь так же,
как переменная с таким же именем из CRT. Например: "TexAttr:
Вyte absolute Crt.TextAttr". Этот способ имеет ряд недостатков,
в основном с точки зрения экономии памяти, но он является
вполне приемлемым, если не остается лучшего выбора. /Особо
благодарим Лейн Феррис; и специалистов Software Science.Inc.,
их Группу Разработки, за помощь в реализации этого метода/.
  Подобная проблема возникнет, конечно, если вы попытаетесь
использовать OPCRT совместно с нестандартным модулем, таким как
USES CRT. Решить эту проблему проще, чем в случае с TURBO3 и
GRAPH3, так как вы будете иметь исходный код модуля, и можете
просто заменить CRT на OPCRT в определении USES. Но у вас
могут появиться многочисленные затруднения при использовании
модулей типа .TPU для распространения или продажи. Эти пробле-
мы вы также сможете решить, используя директиву UseCrt в
ОPDEFINE.INC
Как проверено на практике, модуль, из-за которого возникает
большинство проблем в этой связи, - это модуль TACCESS из
Turbo Database Toolbox. Устранить проблему можно просто, заме-
тив строку USES в TACCESS.PAS. В случае, если вы не знаете,
к каким модулям обращается ваш USE CRT, можете использовать
утилиту GREP фирмы Borland, которая установит все файлы, тре-
бующие "CRT". Рекомендуем использовать следующую командную
строку:
       GREP -r- -w+ "CRT" *.pas
опция "-w+" особенно удобна, так как она устраняет большинство
обращений "OPCRT".

                    Видеоатрибуты

Одно из понятий, которое вам следует абсолютно точно уяснить
для себя, если вы используете OPCRT и зависящие от него модули,
является понятия видеоатрибута. В случае работы в текстовом
pежиме, видеопамять РС делится на серии рядов (обычно 25) и
колонок (обычно 80). Для каждой из этих экранных позиций сущес-
твует 2 байта данных: один содержит описание символа, второй -
его цветовые характеристики. Этот байт цветовых характеристик
известен под названием "видеоатрибут" и выглядит побитно  сле-
дующим образом:

---------------------------------
  7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - номера бит
---------------------------------
  |   |   |   |   |   |___|___|_______________цвет символа
  |   |   |   |   |___________________________бит интенсивности
  |   |   |   |                               /только символа/
  |   |___|___|_______________________________цвет фона
  |___________________________________________интенсивность фона
                                             /или бит мерцания/

Таким образом, значение видеоатрибута можно вычислить по формуле:

              (BackgroundColor * 16) + ForegroundColor

Hапример, чтобы вычислить видеоатрибут Желтого на Красном, нужно
умножить значение цвета фона (Red = 4) на 16 и прибавить значение
цвета символа (Yellow = 14):

              (Red * 16) + Yellow = (4 * 16) + 14 = 64+14=78=$4E

Hиже приведены некоторые цветовые комбинации и соответствующие им
видеоатрибуты:

   Символ         Фон      Мерцание  Биты    16-ричное  10-тичное
                                            значение   значение

LightGray  (07)  Black (00)    No    00000111    07         7
White      (15)  Black (00)    No    00001111    0F        15
Yellow     (14)  Blue  (01)    No    00011110    1E        30
LightGreen (10)  Red   (04)    No    01001010    4A        74
White      (15)  Brown (06)    Yes   11101111    EF       239

Если вы не хотите заниматься вычислением видеоатрибутов в уме,
или  просто желаете сэкономить  время, мы рекомендуем вам заг-
рузить DESKPOP во время сеанса работы.
Карта цветов в DESKPOP позволит вам быстро обнаружить нужный
атрибут  путем просмотра всех цветовых комбинаций.
Вы также можете использовать цветовые константы, описанные  в
модуле   OPCOLOR,  рассматриваемые  в  следующем     разделе.
Это позволит  вам  использовать   мнемонические  имена   типа
"WhiteOnBlack"  или  "BlackOnLtGray"    для   соответствующих
видеоатрибутов.
   Одно замечание по поводу видеоатрибутов.    Из   диаграммы
наверху вы можете заметить, что бит 7 назван "битом мерцания"
(или "Интенсивностью фона"). Действительно, любой видеоатрибут
со значением, большим 127 (двоичным 01111111, шестнадцатиричным
7F), дает мерцающий текст. Однако, если вы запретите мерцание,
используя программу  SetBlink из OPCRT,   "бит мерцания" будет
восприниматься дисплейным адаптером как бит интенсивности цвета
фона. Чтобы увидеть   последствия  отключения  мерцания, можно
загрузить карту цветов в  DESKPOP,  нажать  <Ctrl PgDn>, чтобы
оказаться в конце карты, и  нажать <Ctrl B>,  чтобы  выключить
мерцание. Как вы видите, число немерцающих цветовых  сочетаний
увеличилось вдвое, со 128 до 256.

               Row и Col вместо координат X,Y.

  Другой аспект, который вы должны уяснить, работая с  OPCRT,
это то,  что большинство  программ,  работающих  с   позициями
экрана, использует в качестве координат ряды и колонки (Raws и
сolumns), а не  X и Y (т.е. колонки и ряды).   Этому факту нет
логического обоснования, просто так  сложилось    исторически.
есть несколько исключений    из  этого  правила,  в основном в
программах, содержащихся как в CRT, так  и  в  OPCRT, но общая
идеология следующая:
1. Любая программа, определяющая позицию курсора    (например,
Goto XY), работает в терминах X,Y.
2. Любая программа, определяющая место  размещения  текста  на
экране (например, FastWrite), оперирует терминами Row, Column.
3. Любая программа, определяющая координаты  окна   (например,
Window),  действует в терминах  Xlow, Ylow, XHigh, YHigh.
   Если вы запомните эти три основных вида   координат,    вам
несложно будет    разобраться,  какие   координаты       будет
использовать конкретная программа.

                Поддержка расширенной клавиатуры

  В отличие от CRT, OPCRT способен поддерживать   расширенную
клавиатуру;    например,  программы  считывания  с  клавиатуры
(ReadKey, ReadKeyWord,  KeyPressed и т.д.) способны работать с
клавишами <F11> и <F12>, которых нет на стандартной клавиатуре
РС АТ. По умолчанию эта поддержка не производится, но ее можно
активизировать, добавив в начало программы  строку:

        UseEnhancedKbd: = EnhancedKbdInstalled;

UseEnhancedKbd - это глобальная переменная, влияющая на работу
pазличных программ, работающих с клавиатурой.  Если  она имеет
значение False, то  эти  программы   используют    стандартные
функции BIOS, применимые   по   всем  машинам   и  всем  типам
клавиатур; если же значение True, то эти программы  используют
специальные   функции   BIOS,  работающие  только  при наличии
pасширенной клавиатуры.
Функция EnhancedKbdInstalled пытается определить,  установлена
ли расширенная  клавиатура  или  нет.  Однако,  эта проверка не
является полным доказательством наличия расширенной клавиатуры.
Она работает идеально для машин   PS/2s;  и,  насколько    нам
известно, никогда не сообщит о наличии расширенной клавиатуры,
если таковой нет; но иногда возникают сбои, когда эта  функция
пытается определить наличие  расширенной клавиатуры,  если она
действительно есть. Избежать  затруднений  в  этом  вопросе мы
советуем,  предлагая применять маленькую программку EKFIX.COM,
включая ее в ваши   программы,  если вы  этого   желаете.  Эта
утилита просто изменяет один бит в нижних адресах памяти; бит,
означающий наличие расширенной клавиатуры   (бит  4  в байте с
адресом $40:$96). После этого появляется сообщение о состоянии
этого бита: оn  (доступна расширенная  клавиатура)  или    off
(недоступна).
Замечание: перед  использованием переменной UseEnhancedKbd для
поддержки  расширенной клавиатуры, мы настоятельно рекомендуем
вам ознакомиться с   документацией  модуля OPENHKBD. Во многих
случаях использование OPENHKBD   является наилучшим вариантом,
так как это позволяет   обычной  клавиатуре    в  значительной
степени эмулировать работу расширенной.


             Описания, встречающиеся как в ОPCRT,
                         так и в CRT.

   В   общем   следующие  константы, переменные  и процедуры,
функционально идентичны  тем, что  имеются в  стандартном CRT
модуле Turbo. Заслуживают упоминания только следующие  особые
моменты.

1.  Хотя  процедура  TextMode    переустанавливает  некоторые
важные   глобальные   переменные   (те   же  самые,   которые
переустанавливает GetCRTMode) она не переустанавливает все из
них. Вот  почему  после  переключения  видеорежимов  вам  для
правильной  установки  глобальных  параметров  лучше  вызвать
ReinitCRT. TextMode также отличается от стандартной, тем, что
позволяет работать с ней в графическом режиме (однако следует
помнить,  что  поддержка  графического  режима  ограничена  в
ОPCRT).

2.  DirectVideo имеет такое  же значение как и в  модуле CRT.
Она определяет как будет Write/Writeln,  GotoXY и Read/Readln
выводить текст на экран и  перемещать курсор. Она однако   не
действует на нестандартные процедуры   OPCRT  такие       как
FastWrite и FlexWrite, которые всегда  осуществляют    запись
прямо в видеопамять.

3. Процедура ClrScr может заполнить окно или     весь   экран
какими-либо символами, а не только пробелами. Например, чтобы
заполнить экран звездочками, нужно установить TextChar в '*',
и затем вызвать ClrScr. После очистки экрана ТextChar   будет
автоматически установлен в ' '.

                    Константы

 BW40 = 0;
 C040 = 1;
 С40=С040;
 BW80 = 2;                { Константы видеорежимов }
 C080 = 3;
 C80=C80;
 Mono = 7;
 Font8x8 = 256;

Black = 0;
Blue = 1;
Green = 2;
Cyan = 3;
Red = 4;
Magenta = 5;
Brown = 6;
LightGray = 7;
DarkGray = 8;                   { Цветовые константы }
LightBlue = 9;
LightGreen = 10;
LightCyan = 11;
LightRed = 12;
LightMagenta = 13;
Yellow = 14;
White = 15;
Blink = 128;

                    Переменные

CheckBreak : Boolean;      {Разрешает прерывания по Ctrl-Break}
CheckEOF : Boolean;        {Разрешает прерывания по Ctrl-Z}
CheckSnow : Boolean;       {Установлена в True для предотвра-
                            щения появления "снега" при
                            адаптере CGA}
DirectVideo : Boolean;     {Писать прямо на экран?}
LastMode : Word;           {Текущий видеорежим в младшем байте,
                           флаг 8х8 - в старшем}

              Процедуры и функции

  Процедура AssignCrt (Var F : Text);
  Перенаправляет ввод/вывод через OPCRT, а не через DOS.
  Процедура СtrEol;
  Удаляет оставшуюся часть текущей строки экрана, начиная
  с позиции курсора.
  Процедура ClrScr;
  Чистит текущее окно.
  Процедура Delay (Ms : Word);
  Задержка на Ms миллисекунд.
  Процедура Delline;
  Cтирает текущую строку экрана.
  Процедура GotoXY (X,Y : Byte);
  Сдвигает курсор в колонку X и ряд Y относительно Window.
  Процедура HighVideo;
  Устанавливает биты интенсивности в TextAttr.
  Процедура InsLine;
  Вставляет новую строку начиная с позиции курсора.
  Процедура LowVideo;
  Очищает биты интенсивности в TextAttr.
  Функция KeyPressed : Boolean;
  Возвращает True в случае нажатия клавиши.
  Процедура NormVideo;
  Устанавливает видеоатрибуты в TextAttr при старте программы
  (Не путать с НighVideo!).
  Процедура NoSound;
  Выключает звук.
  Функция ReadKey : Char;
  Считывает символ с клавиатуры.
  Процедура Sound (Hz : Word);
  Генерирует звук заданной частоты.
  Процедура TextBackground (Color : Byte);
  Устанавливает цвет фона экрана.
  Процедура TextColor (Color : Byte);
  Установка цвета символа.
  Процедура TextMode (Mode : word);
  Устанавливает текущий видеорежим.
  Функция WhereX : Byte;
  Возвращает текущее значение координаты X (т.е. колонку),
  относительно Window.
  Функция WhereY : Byte;
  Возвращает текущее значение координаты Y (т.е. ряд),
  относительно Window.
  Процедура Window (XLow,YLow,Xhigh,YHigh : Byte);
  Устанавливает текущие координаты окна.


              Описания, встречающиеся только в ОРCRT

                      Типы

  ColorChoice = (UseDefault, ForceColor, ForceMono);
     Тип DefColorChoice, влияющий на результат работы функции
  UseColor (вызываемой всегда, когда необходимо выбрать цвет-
  ной или монохромный режим). По умолчанию   установлен     в
  UseDefault, это значит, что выбран текущий видеорежим и/или
  текущий тип дисплея. ForceColor означает выбор цветовых ат-
  рибутов, ForceMono - монохромных.

  ColorMapTable = array[0..255] of Byte;
     Таблица видеоатрибутов цвета для монохромных или  черно-
  -белых мониторов.

  CursorType = (cuNormal,cuFat,cuBlock,cuHidden,cuUnknown);
     Стандартные типы курсоров для OPCRT.  CuNormal  oзначает
  "тонкий" курсор, обычно 2 пиксела высотой, зто размер  кур-
  сора для PC по   умолчанию.  CuFat - это  "жирный"  курсор,
  обычно 3 пиксела высотой. CuBlock означает "блочный"   кур-
  сор, максимально возможной высоты (8-14 пикселов). CuHidden
  делает курсор невидимым. CuUnknown используется для опреде-
  ления нестандартных форм курсора.

  DisplayType = (MonoHerc,CGA,MCGA,EGA,VGA,PGC);
     OPCRT работает с шестью  типами   дисплейных  адаптеров.
  MonoHerc означает, что имеется обычный монохромный адаптер
  или монохромная графическая плата стандарта Hercules.  PGC
  устанавливается для IBM Professional  Graphics  Controller
  Card.

  FlexAttrs = array[0..3] of Byte;
     Это массив атрибутов,    используемый   для   процедуры
  FlexWrite.

  FrameCharType = FrTL..FrRR;
  FrameArray = array[FrameCharType] of Char;
     Массив символов, используемый для рисования  рамок   за
  пределами окна.

  HercCardType = (HercNone,HercPlain,HercPlus,HercLnColor);
     Используется для классификации   различных  графических
  плат Hercules. HercPlain означает стандартную  графическую
  плату Hercules или совместимую с ней. HercPlus  обозначает
  плату Hercules  Graphics   Card   Plus   (c  возможностями
  RamFont). HercLnColor показывает наличие платы HerculesLn-
  Color Card. HercNone означает плату, не являющуюся ни одной
  из трех перечисленных.

  WindowCoordinates =
  record
  XL,YL,XH,YH : Byte
  end;
     Запись используется для сохранения/восстановления коор-
  динат окна.



                        Константы

АutoMapMono = $FF;

Если эта константа используется в функции MapMono (в качестве
второго параметра), или в любой программе, вызывающей MapMono,
то это значит, что  видеоатрибут  для  монохромного   дисплея
будет выбран автоматически из таблицы перевода ColorMap.  Чи-
тайте также о ColorSet в следующем разделе.

ВiosScroll : Boolean = True;

Если  эта константа установлена в FALSE,  то     используется
специальная процедура для скроллинга, которая убирает  "снег"
и  мерцание на цветных графических адаптерах.  Она  действует
не  только  для  процедур Write и  Writeln, а также   и   для
процедур   ScrollWindowUp  и    ScrollWindowDown.   Процедура
скроллинга BIOS часто работает быстрее при адаптере СGA,   но
менее  приятна для глаз.

СolorMap : ColorMapTable = (...);

Это - таблица переводов цветовых атрибутов в монохромные. Она
используется   функциями   MapColor,   MapMono  и  в   методе
РackedWindow.MapColors.

DefaultPasswordChar = ^G;

Этот символ используется для представления текста при  работе
строкового или текстового редактора в "режиме пароля". Исполь-
зуется в ОPEDIT и в  OPENTRY;  не   используется   собственно
модулем OPCRT.

DefaultPadChar = ' ';

Этот символ используется для "забоя" строк, отредактированных
строковым или текстовым редактором. Используется в OPEDIT и в
ОPENTRY; не используется собственно модулем OPCRT.

DefaultColorSet : ColorSet = (...);

Это цвета по умолчанию для   всех     экранно-ориентированных
объектов. Читайте также о ColorSet в следующем разделе.

DefColorChoice : ColorChoice = UseDefault;

Влияет на результат работы функции UseColor. Cмотрите описание
типа ColorChoice (выше); и функции UseColor.

DetectMultitasking : Boolean = False;

Если DetectMultitasking = True,   OPCRT  будет  выполнять  все
необходимые операции по   проверке,  работает  ли  программа в
многозадачном режиме   типа   DesqView  или  OmniView  (бывший
ТaskView). Если  многозадачный  режим   действительно    есть,
МultitaskingOn устанавливается в Тrue, и все выводы на   экран
(Write,  WriteLn,  FastWrite  и т.д.)  будут   направлены   на
виртуальный экран , поддерживаемый системой, а не на физический
экран. Так как значение по умолчанию DetectMultitasking =False
то, если вы хотите работать  с  программой   как   с "фоновым"
заданием, вам нужно добавить в программу две строки :
                  DetectMultitasking := True;
                  ReinitCrt;
Таким образом, большинство программ, использующих OPCRT, могут
pаботать как фоновые задания внутри окна (единственное извест-
ное нам исключение  составляют   программы,       использующие
ненулевую страницу видеопамяти). Они также могут    рассматри-
ваться (в "TopView aware") в терминах, используемых DesqView и
ОmniView. Заметим, что сам  по  себе   OPCRT   не поддерживает
ТopView, как не поддерживает Microsoft Windows и Double DOS.
Важное замечание : не устанавливайте DetectMultitasking в True
в TSR. Функция, вызываемая для определения наличия многозадач-
ного режима, может создать вам проблемы, если будет выполнять-
ся внутри части, обозначенной  как  "Writing  directly  to the
screen". Поэтому DetectMultitasking   и   устанавливается   по
умолчанию в False. Если вы уверены, что не  будете писать TSR,
можете изменить ее на True и заново откомпилировать OPCRT.

DisplayOverride : ShortInt := -1;

Tак как выявление типа дисплейного адаптера - довольно тонкое
искусство, эта переменная  дает   возможность  переопределить
адаптер. Если она установлена в -1, это означает  автоопреде-
ление. Если же вы хотите,   чтобы   OPCRT   переопределил тип
адаптера, допустим, воспринимал   бы   EGA как CGA, вы можете
придать DisplayOverride определенное значение для подходящего
DisplayType :
            "DisplayOverride := Ord(CGA);"
и затем запустить ReinitCrt. Более общий случай использования
этой константы - это "приказать" OPCRT распознать тип адапте-
pа (к примеру, EGA или VGA) в случаях, когда  автоопределение
не может правильно это установить. Эта необходимость, правда,
возникает редко.

frTL = 0;
frBL = 1;
frTR = 2;
frBR = 3;
frTT = 4;
frBB = 5;
frLL = 6;
frRR = 7;

Эти константы являются элементами массива FrameArray:

frTL - верхний левый угол, frBL - нижний левый угол,   frTR -
- верхний правый угол, frBR - нижний правый угол,      frTT -
- верхняя граница,  frBB - нижняя граница,  frLL -      левая
граница, frRR -  правая граница.

FrameChars : FrameArray = '...(символы для построения рамки)';

используется  для хранения символов для процедуры FrameWindow,
которая  рисует  рамки  вокруг  окон.  Может  быть   изменено
процедурой SetFrameChars.

HercExceptionReg: Byte = $27;

Этот параметр делает возможным использование OPCRT как базиса
для более развитого  набора   команд   для работы с новейшими
графическими платами Hercules.  Он  необходим,  потому    что
pегистр расширения    в RamFont является только регистром для
записи. HercExceptionReg запоминает последний байт, записанный
в этот порт, что теоретически   дает возможность использовать
независимо три функции, управляемые  регистром расширения, не
зная содержимого остальных бит.

InsertCursor   : CursorType : cuFat;
OverTypeCursor : CursorType : cuNormal;
CtrlCharCursor : CursorType : cuBlock;

Эти три константы используются модулями OPSEDIT, OPFEDIT    и
ОPDEMO    для   определения формы  курсора в течении работы в
pежимах вставки   и переопределения,   и   во  время ожидания
управляющего символа,  который должен вводиться после команды
СtrlChar. Значения по    умолчанию равны стандартному курсору
в режиме переопределения,   жирному курсору в режиме вставки,
и блочному курсору при ожидании управляющего символа.

ТextChar : Char = ' ';

Вместе с TextAttr этот символ используется  в ClrScr, ClrEol,
ScrollWindowUp и  ScrollWindowDown  во  время   очистки   или
скроллинга окна. Так же как и переменная Buflen, он принимает
свое значение по умолчанию (' '),  после того как очистка или
скроллинг экрана  завершены.

UseEnhancedKBD : Boolean = False;

Если этот параметр установлен в True, все   обращения  модуля
ОPCRT (ReadKey, ReadKeyWord,   KeyPressed  и  т.д.)     будут
использовать   специально  усовершенствованные  функции BIOS,
позволяющие распознавать   клавиши  расширенной   клавиатуры,
такие как <F11> или <F12>. Смотрите также  раздел  "Поддержка
pасширенной клавиатуры",    описанный    выше,   и   описание
ЕnhancedKbdInstalled далее.


                   Переменные

Вuflen : Word;

Максимальная длина строки для процедур Read/ReadLn,
допустимые значения от 1 до 126; и после каждой процедуры
Read/ReadLn BufLen принимает значение 126.

CtrlBreakFlag : Boolean;

Устанавливается  в  TRUE  когда  нажат  CTRL-BREAK.   Исполь-
зуется только для  внутренних  целей.

СurrentDisplay : DisplayType;

Тип  текущего  адаптера.  Если  установлено  два адаптера, то
переменная    показывает    тип    текущего.    См.     также
ЕnhancedDisplay.

СurrentMode : Byte absolute LastMode;

Текущий видеорежим.

СurrentPage : Byte;

Текущая видеостраница.

ЕnhancedDisplay : DisplayType;

Эта переменная имеет смысл только тогда, когда установлена  в
МCGA, EGA или VGA. Она используется для обнаружения  ситуации,
когда установлены два адаптера, например монохромный  адаптер
и EGA  как графический  монитор. В  данном случае  переменная
будет установлена в EGA,  а  CurrentDisplay  в  MonoHerc. Эта
информация   обычно   требуется   в  резидентных  (в  памяти)
программах, которые желают поддерживать 43 или 50 линий  (при
использовании   шрифтов   8х8)   в  адаптерах   EGA   и  VGA.
Смотрите SMACS.PAS в качестве  примера.  Если  MСGA, EGA  или
VGA  не  установлены, переменная EnhancedDisplay устанавлива-
ется в MONOHERC.

InTextMode : Boolean;

Уcтанавливается  в FALSE   при  графическом  режиме (заметим,
что графический режим Hercules не обнаруживается).

МultiTaskingOn : Boolean;

Эта переменная устанавливается в   True, если    DetectMulti-
tasking  имеет значение True, и определен многозадачный режим
(DesgView, TackView/OmniView).

OneMS : Word;

Эта переменная содержит значение счетчика, используемого Delay
при генерации задержки на 1ms.

SaveCtrlC : Boolean;

Используется для хранения состояния   опции   DOS      "break
сhecking". OPCRT выключает проверку по Ctrl-C во время начала
pаботы программы, и возвращает  ее в первоначальное состояние
после завершения    программы.  Смотрите  описание GetBreak и
SetBreak в руководстве  по Турбо Паскалю.

ScreenHeigth : Word;

Текущий размер изображения в высоту в строках (обычно 25).

ScreenWidth : Word;

Tекущая ширина изображения.

VirtualHeigth : Word;

Oбычно значение  этой переменной равно значению ScreenHeight,
но иногда оно изменяется с помощью OPWINDOW,  что   позволяет
определенным  программам работать с виртуальным экраном. Смо-
трите документацию  по OPWINDOW.

VirtualSegment : Word;

Обычно значение  этой переменной равно значению VideoSegment,
но иногда оно изменяется с помощью OPWINDOW,  что   позволяет
FastWrite и другим программам работать с виртуальным экраном.
Cмотрите документацию  по OPWINDOW.

VirtualWidth : Word;

Обычно значение  этой переменной равно значению  ScreenWidth,
но иногда оно изменяется с помощью OPWINDOW,  что   позволяет
FastWrite и другим программам работать с виртуальным экраном.
Смотрите документацию  по OPWINDOW.

WhichHerс : HercCardType;

При наличии графической   платы Hercules,  и   ее   активного
состояния, определяет ее тип. Эта переменная инициализируется
при старте программы,   а   ее  значения  переустанавливается
всякий раз при вызове   ReinitCrt.   Если   плата    Hercules
отсутствует либо не активна,  то WhichHerc  устанавливается в
HercNone.


        Описание процедур и функций модуля OPCRT

Процедура BlockCursor;

Hазначение

Устанавливает размер блочного курсора

Описание

Эта процедура изменяет количество пикселов курсора так, чтобы
он  был максимально большим. Для адаптеров CGA это  означает,
это курсор занимает 8 пикселов, а для EGA и VGA-14.

Смотрите также

FatCursor HiddenCursor NormalCursor SetCursorSize
-----------------------------------------------------------

Процедура ChangeAttribute(Number : Word; Row, Col : Word,
                                    Attr : Byte);

Hазначение

Изменяет видеоатрибуты на Attr начиная с позиции Row , Col.

Описание

Эта программа позволяет вам увидеть цвета экрана, не     видя
сам текст. Типичный пример использования ChangeAttribute -это
изменять размер столбцов меню, таким образом вы можете  "рас-
тягивать" или "cжимать" ту или иную области  экрана,  не  за-
ботясь о том, что же там  изображено ранее. Смотрите демонст-
pационную программу SMACS.PAS как пример использования зтого
средства.
Number указывает  число видеоатрибутов, которые    необходимо
изменить. Row и Col указывают   позицию  экрана,  начиная   с
которой будут изменяться видеоатрибуты.  (Помните,   что  эти
координаты - абсолютные экранные,  а не зависящие от текущего
окна). Аttr - значение нового видеоатрибута.

Пример

  Program Colors;
  uses OPCRT;
  const Attr : Byte=0;
  begin
  ClrScr;
  Writeln('Hello multi-colored world!'^M^J'Now watch the
  color change...');
  Delay(1000);
  while not KeyPressed do
  begin
  ChangeAttribute(26,1,1,Attr and $7f); {suppress blink bit}
  Delay(50); {Make it a little easier on the eyes...}
  Inc(Attr); {Change the attribute}
  end;
  end.
  Показывает в цикле все цветовые комбинации, пока не будет
  нажата клавиша.
-----------------------------------------------------------

Функция CheckKbd(var KeyCode : Word) : Boolean;

Hазначение

Возвращает  True  (и  код  клавиши),  если ожидается     ввод
с клавиатуры.

Описание

Эта  процедура  похожа  на  KeyPressed, однако если ожидается
строка, то она также возвращает также код клавиши (в  том  же
формате, что и KeyPressed).  Это преимущество позволяет   вам
увидеть, какой же символ ожидается,   при  этом  в отличие от
ReadKey или ReadKeyWord она  не  очищает  клавиатурный  буфер
BIOS.

Смотрите также

ReadKeyWord
-----------------------------------------------------------

Функция ClassifyCursorType : Cursor Type;

Hазначение

Определяет тип курсора, то есть его размер в пикселях

Описание

Функция просматривает форму курсора и  классифицирует  ее   в
соответствии со стандартными типами курсора в OPCRT

Пример

  CT: = ClassifyCursorType;
  SelectFont8x8 (not Font8x8Selected);
  SetCursorType (CT);

Сохраняет тип курсора,  переключает  режим с  25-строчного на
43/50-строчный, затем восстанавливает предыдущий тип курсора.
(SelectFont8x8 всегда устанавливает курсор в cuNormal).

Cмотрите также

SetCursorType
-----------------------------------------------------------------

Процедура ClearPage (PageNo : Byte);

Hазначение

Чистит определенную страницу видеопамяти, заполняя ее    сим-
волами TextChar c видеоатрибутами Textattr.

Описание

Эта программа очищает определенную страницу видеопамяти  сим-
волами TextChar (oбычно ' '), и видеоатрибутами TextAttr. Эта
программа никогда не используется при монохромных  адаптерах,
которые имеют только одну страницу видеопамяти. Часто она ис-
пользуется для очистки неактивных   страниц   перед   вызовом
SetActivePage.

Пример

Смотрите пример для SetActivePage

Смотрите также

SetActivePage

------------------------------------------------------------

Процедура ClearWindow (Xlow, Ylow, XHigh, Yhigh: Word;
   Ch:char; A:Byte);

Hазначение

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

Описание

Эта программа очищает окно,   заданное Xlow,   Ylow,   XHigh,
YHigh, используя определенный символ (Ch) и видеоатрибут (А).
в отличие от ScrollWindowUp и ScrollWindowDown  эта программа
может работать с виртуальным экраном так же  успешно, как и с
физическим.

Пример

  ClearWindow (1,2,80, ScreenHeight-1, #176, $07);

Заполняет все строки, кроме верхней и нижней, узором   "в го-
pошек".

Смотрите также

ScrollWindowDown, ScrollWindowUp
----------------------------------------------------------------

Функция ColorMono (Color, Mono: Byte) : Byte;

Hазначение

Выбирает цветной и монохромный видеоатрибут

Описание

Это - одна из наиболее широко используемых функций в   Object
Рrofessional. Она вызывается всякий раз, когда    какому-либо
экранно-ориентированному объекту нужно сделать   выбор  между
двумя видеоатрибутами, Color и Mono.  Эта  простая  программа
возвращает значение Color, если функция UseColor   возвращает
Тrue, и Mono,  если иначе.  Вы можете использовать ее в ваших
собственных дисплейных программах, если вам надо будет делать
подобный выбор.

Пример

  FastWrite ('Hello World!', 1, 1, ColorMono ($1F, $OF));

Высвечивает на   экране 'Hello World!'   белым по голубому на
цветном дисплее, и белым по черному на монохромном или черно-
белом дисплее.

Смотрите также

UseColor
-------------------------------------------------------------------

Функция CursorEndLine : Byte;

Hазначение

Возвращает номер последнего пиксела курсора

Описание

Эта программа возвращает номер последнего  по  счету  пиксела
курсора, обычно или 7 (в цветном текстовом режиме) или 13  (в
монохромном текстовом режиме)

Пример

Смотрите ниже.
----------------------------------------------------------------

Функция CursorStartLine : Byte;

Hазначение

Возвращает первый пиксел курсора.

Описание

Возвращает  номер первого пиксела,  который  обычно равняется
6 (для цветного текстового режима) или 12 (для монохромного).
Для EGA в режиме 43 строк значение равно обычно 5.

Пример

   NormalCursor; {select normal two-line cursor}
   WriteLn('Starting scan line for cursor:',CursorStartLine);
   WriteLn('Ending scan line for cursor:',CursorEndLine);

Будет получено на экране 5, 6 или 12 -   значение   начальных
пикселов курсора, в зависимости от текущего режима, и 7   или
13 - значение последних пикселов.
-------------------------------------------------------------

Функция CursorTypeSL : word;

Hазначение

Возвращает начальный и конечный пиксел, образующие курсор.

Описание

Эта    процедура    совмещает    функции    CursorEndLine   и
СursorStarLine возвращая оба значения.   Номер     начального
пиксела возвращается в старшем байте слова, а номер конечного
в младшем байте слова.   Эта  процедура  иногда   может  быть
использована  вместе  с   SetCursorSize,  как  параметр   для
SetcursorState и RestoreCursorState.

Пример
Var CursorScanLines, key : word;
begin
 CursorScanLines := CursorTypeSL;
 HiddenCursor;
 FastWrite('Error. Press any key to continue...',25,1,Textattr);
 key := ReadKeyWord;
 SetCursorSize( Hi (CursorScanLines), Lo (CursorScanLines));
end;

Сохраняет размер курсора, делает   курсор  скрытым,   выдает
сообщение об ошибке внизу экрана,   затем    восстанавливает
размер курсора.

Смотрите также

GetCursorState
SetCursorSize
-----------------------------------------------------------

Функция EnhancedKbdInstalled : Boolean;

Hазначение

Возвращает значение True, если установлена расширенная   кла-
виатура.

Описание

Эта программа пытается определить,   установлена  расширенная
клавиатура  или нет. Для этого она использует тест, полностью
идентичный тому, что используется модулем OPENHKBD. Для полу-
чения более полной  информации об  этом обратитесь  к разделу
"Поддержка расширенной клавиатуры" в начале главы.
Типичный  пример использования  этой функции - это определить
значение переменной   UseEnhancedKbd,   которая   определяет,
будут ли  программы,   обращающиеся к   клавиатуре, такие как
ReadKey, ReadKeyWord и KeyPressed   использовать  специальные
функции  BIOS  для  поддержки   расширенной  клавиатуры. Если
UseEnhancedKbd имеет значение False, (как и по умолчанию), то
комбинации  клавиш, не  существующие в "обычных" клавиатурах,
будут игнорироваться (<F11>, <^Up), <AltTab>).
Единственным  недостатком  обеспечения  поддержки расширенной
клавиатуры является то, что иногда это будет    предотвращать
написанные ранее TSR от перекрывания в ситуациях,  когда было
бы  нужно сделать это.

Пример

  UseEnhancedKbd : = EnhancedKbdInstaled;
  if UseEnhancedKbd then begin
  Write ('Press the <F12> key...');
  repeat
  until ReadKeyWord = $8500; {wait for <F12> to be pressed}
  end
  else
  writeln ('Enhanced key board not instaled');

Если установлена расширенная клавиатура, цикл будет повторять-
ся, пока не будет нажата клавиша <F12>.

----------------------------------------------------------------------

Процедура FastCenter (St: string; Row, Attr : Byte);

Hазначение

Пишет строку St в центре окна в ряду Row видеоатрибутом  Attr

Описание

Эта программа высвечивает определенную строку (St) в   центре
текущего окна в определенном   ряду   Row        определенным
видеоатрибутом   (Attr).   Ряд определяется   по  отношению к
текущему окну.

Пример

  Window (2,2,79,24);
  FastCenter ('Hello world', 1, $F);

Hа экране появится 'Hello world' во втором ряду (в абсолютном
значении), размещенная посередине между 2-й и 79-й колонками.

Смотрите также

FastFlish

--------------------------------------------------------------------

Процедура FastFill (Number: Word; Ch: Char; Row, Col: Word;
  Attr: Byte);

Hазначение

Заполняет Number слов видеопамяти символами Ch с видеоатрибу-
тами Attr, начиная с позиции Row, Col

Описание

Эта программа заполняет определенную   область   видеопамяти,
начиная с Row, Col  символами   Ch  с  атрибутами   Attr    в
количестве  Number  штук. Типичный  пример использования этой
процедуры -     заполнить определенную строку экрана символом
pисования линии, к примеру, #196.

Пример

  FastFill (ScreenWidth, #196, 13,1,$F);
Заполнение всего 13-го ряда символом #196, белым по черному.

-------------------------------------------------------------------

Процедура FastFlush (St: String; Row, Attr: Byte);

Hазначение

Пишет строку St, выравнивая ее по правой границе окна Window,
видеоатрибутом Attr.

Описание

Эта программа высвечивает определенную строку St,  выравненную
по    правому  краю текущего окна,  в определенном   ряду Row
определенным видеоатрибутом Attr. Ряд    Row    отсчитывается
относительно текущего окна

Пример

  Window (2, 2, 79, 24);
  FastFlush ('Hello wordl!', 1, $F);
Высвечивает 'Hello world!' во 2-м ряду (в абсолютном исчисле-
нии), конец записи - "!" будет в 79-й колонке.

Смотрите также

FastCenter

-----------------------------------------------------------------

FastRead(Number,Row,Col : byte, Var ST : String);

Hазначение

Считывает Number знаков в строку ST начиная с Row, Col.

Описание

Подобно процедуре ReadCharAtCursor,  FastRead читает текст  с
экрана, но делает это с максимальной  скоростью. Эта полезная
процедура,    которая    используется    для       перекрытий
в   модуле   ОPTSR,   который  исследует  содержимое   экрана
прерванной программы.
Number - это число символов, считываемых с экрана.  Row и Col
определяют позицию, начиная с которой   начинать  считывание.
(Заметим, что Row, Col определяют абсолютную позицию , а   не
относительно текущего окна.) А St - это   строка,   в которую
происходит считывание с экрана.
Смотрите  SMACS.PAS  для  ознакомления    с      практическим
применением FastRead.

Смотрите также

ReadCharAtCursor

-----------------------------------------------------------

Процедура FastText (St: String; Row, Color: Word);

Hазначение

Пишет строку St, начиная с позиции Row, Col  без    изменения
предыдущих видеоатрибутов этих позиций.

Описание

Эта   программа  идентична FastWrite   кроме того, что она не
имеет параметра видеоатрибута.  Текст   будет написан теми же
цветами, что были  на экране на этих же позициях до написания
текста.

Пример

   Text Attr : = $F;
   ClrScr;
FastText ('This text will be displayed in white on black', 1,1);
Высвечивает данную стрoку в левом верхнем углу экрана    теми
цветами, которые были в позициях 1-го ряда.

Смотрите также

FastWrite

--------------------------------------------------------------------

Процедура FastVert (St: String; Row, Col: Word; Attr: Byte);

Hазначение

Вертикально пишет строку St с позиции Row,Col  видеоатрибутом
Аttr.

Описание

Эта программа идентична FastWrite,   кроме того,   что    она
pазмещает текст вертикально, а не горизонтально.

Пример

  FastWrite ('Writing horizontally...',1, 2,Text Attr);
  FastVert ('Writting Vertically...', 2, 1, Text Attr);

  Первая строка будет написана горизонтально вверху экрана,
  вторая - вертикально, вдоль левого края экрана

Смотрите также

FastWrite

---------------------------------------------------------------------

Procedure FastWrite (St: String, Row, Col:Word, Attr: Byte);

Hазначение

Выводит строку ST начиная с позиции Row, Col с
видеоатрибутами Attr

Описание

Процедура дает возможность выводить на экран текст на экран с
максимальной  скоростью  и без мерцания и снега.   В  отличие
от стандартной процедуры  Write,  FastWrite     предоставляет
Вам возможность контролировать, где и с каким  видеоатрибутом
выводить строку, эмулируя   следующую      последовательность
действий:

 GOTOXY(Col,Row);
 TextColor(n);
 TextBackGround(n);
 Write(S);

Единственное ограничение этой процедуры состоит в  том,   что
она она работает только в текстовых режимах. St - строка  для
вывода.  Row и Col определяют позицию, с которой   начинается
вывод. (Заметим, что Row, Col определяют абсолютную позицию ,
а   не относительно текущего окна.)   Attr   -   видеоатрибут
выводимой  строки.

Пример

 Var Row, I : byte;
 begin
  ClrSсr;
  Write('Press any key to demonstration FastWrite');
  I:= ReadKeyWord;
    While not KeyPressed do
       for Row := 1 to ScreenHeight do
         for i := 0 to 7 do
 FastWrite('FastWrite ', Row, Succ(I*10), lo(random(127)));
       I:=ReadKeyWord;
 end;

-----------------------------------------------------------

Процедура FastWriteAttr (St: String; Row,Col: Word;
  AttrSt: String);

Hазначение

Пишет строку St с позиции Row,Col используя атрибуты в AttrSt

Описание

FastWriteAttr похожа на  FastWrite, за исключением того, что
последним параметром здесь является строка видеоатрибутов.
Каждый элемент строки AttrSt однозначно соответствует символу
в строке St: символ St[1] будет нарисован атрибутом AttrSt[1]
St[2]-AttrSt[2] и так далее.Строка AttrSt обязана быть той же
длины, что и St.
Обычно эта программа используется в сочетании с ReadAttribute,
которая возвращает строку видеоатрибутов, но она может исполь-
зоваться вместо FlexWrite в случаях,   когда       требуется
повышенная  гибкость.

Пример

  const ASt: String [4] = #$1F#$2F#$3F#$4F;
  ...
  FastWriteAttr ('TEST', 1, 1, ASt);
  Высвечивает каждый элемент строки 'TEST' различным цветом
  (синим, зеленым, бирюзовым и красным)

Смотрите также

FlexWrite     ReadAttribute

-------------------------------------------------------------------

Процедура FastWriteCtrl (St:string; Row,Col: Word;
  Attr,Ctrl: Byte);

Hазначение

Пишет строку St начиная с позиции Row,Col, используя   видео-
атрибут Attr, подавляя "снег"

Описание

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

Пример

 FastWriteCtrl ('Control characters: '^A^B^C^D,1,1,$O7,$OF);

Пишет первую часть строки обычно, светло-серым по черному;
последние четыре символа (A^B^C^D) пишутся прописными буквами
белым по черному.

Смотрите также

FastWrite

------------------------------------------------------------------

Процедура FatCursor;

Hазначение

Устанавливает "жирный" курсор в текущем видеорежиме.

Описание

Эта  процедура  изменяет  размер  курсора  так,  что   курсор
становиться больше  чем нормальный  (толстеет). На  машинах с
цветным  графическим  адаптером  курсор  будет  состоять из 3
пикселов из 8 возможных. Для монохромного адаптера это   зна-
чение  равно 4 из 14 возможных. Для EGA (43 строки) и VGA (50
строк)-  будет размером в 5 пикселов из 8 возможных.

Смотрите также

ВlockCursor       NormalCurSor
HiddenCursor      SetCursorSize

-----------------------------------------------------------


Функция FlexLen (S:string):Byte;

Hазначение

Возвращает "визуальную" длину строки.

Описание

Эта функция работает со строками, написанными обычно   проце-
дурой FlexWrite и вычисляет их "визуальную" длину       (т.е.
физическую длину минус число специальных управляющих символов
в строке). Функция написана  преимущественно  для  внутреннего
использования в OPPICK, но вы также можете ей пользоваться.

Пример

 FlexLen ('This' ^A' is a'^B' test');

Возвращает 14, то есть длину строки ('This is a test')

-------------------------------------------------------------------

Процедура FlexWrite (St:String; Row,Col: Word;
  var FAttrs:FlexAttrs);

Hазначение

Пишет строку St начиная с позиции Row,Col, используя   гибкое
управление цветами

Описание

Эта программа похожа на FastWrite, но последний    параметр -
не один байт,  содержащий значение видеоатрибута всей строки,
а массив байт [0..3]. Это сделано с целью позволить различным
частям строки иметь свои видеоатрибуты;   а   сигналом      к
изменению  текущего видеоатрибута служат управляющие символы:
^A,^B,^C. Значение по    умолчанию   видеоатрибута   строки -
- FAttrs [0]. Чтобы изменить его на FAttrs[1], нужно   ввести
^A; на FAttrs[2] - ^B; на FAttrs[3] - ^C. Чтобы вернуть преды-
дущее значение атрибута, надо  ввести тот же управляющий сим-
вол еще  раз. Смотрите  пример ниже.
Заметим,   что  всякий раз, когда вы "переключаете" атрибуты,
используются 2 байта стека.  Стек    восстанавливается    при
переключении на предыдущий атрибут      или по     завершению
программы, смотря что случится раньше. Программист сам должен
убедиться в наличии нужного объема стека, хотя это приходится
делать  редко.
Смотрите PTIME.PAS  и  OPCALS.PAS  как дополнительные примеры
тспользования FlexWrite

Примеры

  const Fattrs: FlexAttrs = ($7, $F, $E, $70);
  FlexWrite ('This' ^A'is'^A''^B'a'^B''^C'test',1,1,FAttrs);

  В этом примере каждое из четырех слов строки будет иметь
  собственный атрибут. Первое слово и пробелы между словами
  будут иметь атрибуты по умолчанию (FAttrs[0]).

  FlexWrite ('This'^A'is also a'^B'test',1,1,FAttrs);

  Первое слово будет иметь атрибут FAttrs[0], следующие
  три FAttrs[1], а последнее слово - FAttrs[2].

Смотрите также

FastWrite     FastWriteAttr.

------------------------------------------------------------

Функция  Font8x8Seleted : boolean;

Hазначение

Возвращает True если адаптер EGA (VGA) используют шрифт 8х8

ОПИСАНИЕ

Эта процедура  возвращает True  если адаптер  EGA в настоящий
момент работает в режиме 43  строк или VGA работает в  режиме
50    строк.    Вызов    процедуры    Font8x8Seleced    также
переустанавливает глобальную переменную ScreenHeight.
Запомним: инициализационный  код OPCRT          автоматически
определяет наличие режима 43/50 строк и устанавливает    раз-
меры окна по умолчанию  1,1,80,43/50 при  обнаружении.   Если
Ваша программа работает на 25-строчном дисплее,    включите в
Вашу программу следующие строки:

Window(1, 1, 80, 25);
If Font8x8Selected then
   SelectFont8x8(false);

Пример

If CurrentDisplay >= EGA
then
      SelectFont8x8(not Font8x8Selected);

Если присутствует адаптер VGA или EGА, то переключает его в
pежим 50 (43) линий.

Смотрите также

SelectFont8x8

-----------------------------------------------------------

Процедура FrameWindow(LeftCol,TopRow,RightCol, BotRow : Word,
                     Fatrr, Hattr: byte; Header : String);

Hазначение

Рисует рамку вокруг окна.

Описание

Эта  процедура  обрамляет   окно, размеры  которого определя-
ется  переменными  LeftCol,TopRow,RightCol,  BotRow. (Исполь-
зуются абсолютные экранные   координаты,   а   не  координаты
относительно   текущего  окна).  Символы которые используются
для рисования  рамки   хранятся   в глобальной   типизованной
константе   FrameChars.   Headеr  -  это  заголовок,  который
выводится посередине верхнего ряда окна. Если заголовок    не
требуется  то вы можете ввести пустую строку. Fattr -     это
видеоатрибут  для  вывода  рамки,  а Hatrr  -    видеоатрибут
для  вывода  заголовка.

Пример

FrameWindow(1,1,ScreenWidth, ScreenHeight textAttr,
           TextAttr, ' Header goes here ');

Рисует рамку вокруг всего экрана

-----------------------------------------------------------

Функция GetCrtMode : Byte ;

Hазначение

Выдает текущий видеорежим.

Описание

GetCrtMode возвращает текущий видеорежим, и также   переуста-
навливает  глобальные   переменные   используемые   в  ОPCRT:
СurrentMode(текущий   видеорежим),  InTextMode( False если  в
графическом режиме),  ScreenWidth  (текущая  ширина  экрана),
СurrentPage  (текущая страница видеопамяти) и    VideoSegment
(адрес сегмента начала видеопамяти). Она предназначена в  ос-
новном для перекрывающих программ как альтернатива ReinitCrt,
которая переустанавливает несколько важных глобальных   пере-
менных и занимает больше времени.
Для более лучшего понимания работы этой процедуры    смотрите
РTIME.PAS.   PTIME  перед  тем  как  вывести  время на экран:
1.-  определяет верхний правый угол для вывода времени,
2.-определяет, что нет графического  режима,
3.- кроме  того  время  выводится на текущую         страницу
активного адаптера.

Смотрите также

Font8x8Selected        ReInitCRT

-----------------------------------------------------------

Процедура  GetCursorState( Var XY, ScanLines : Word);

Hазначение

Возвращает текущее положение и размер курсора.

Описание

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

Пример

Var XY, CursorScanLines, Key : word;

Begin
 GetCursorState( XY, CursorScanLines);
 HiddenCursor;
 FastWrite('Error. Press any key to continue...',25,1,TextAttr);
 Key := ReadKeyWord;
 RestoreCursorState(XY, CursorScanLines);
end;

Для дальнейших примеров смотрите демонстрационные программы

Смотрите также

RestoreCursorState

-----------------------------------------------------------


Функция GetPagePointer (PageNo: Byte):Pointer;

Hазначение

Устанавливает указатель на начало определенной видеостраницы

Описание

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

'Ptr (GetPageSegment (PageNo),O)'

-----------------------------------------------------------------

Функция GetPageSegment (PageNo: Byte): Word;

Hазначение

Устанавливает видеосегмент, соответствующий определенной стра-
нице видеопамяти

Описание

Имея на входе номер видеостраницы, эта   функция   возвращает
сегментную   часть ее адреса в видеопамяти. Если PageNo задан
неверно, GetPageSegment возвратит VideoSegment.
GetPageSegment предназначена в   основном   для   внутреннего
использования в SetActivePage и в GetPagePointer, но вы также
можете  использовать   ее вместе  с  VirtScreen.Init.   Таким
образом, если    ваша  программа  работает  только с цветными
дисплеями, вы можете     использовать   ненулевые    страницы
видеопамяти как буферы виртуальных экранов, экономя память.
смотрите описание VirtScreen.Init.

Смотрите также

VirtScreen.Init
------------------------------------------------------------------

Функция HercGraphicsMode: Boolean;

Hазначение

Возвращает True, если плата Hercules работает в   графическом
pежиме

Описание

Эта   программа   возвращает  True,  если плата Hercules (или
совместимая с ней) установлена,   и   установлен  графический
pежим.  Имейте в виду, что тест, проверяющий установку, далек
от    совершенства. Он всегда работает безупречно с "родными"
платами     Hercules, и в большинстве случаев с платами этого
семейства; но    часто   случаются и сбои. Особенно часто это
происходит с платами    EGA/VGA, эмулирующими Hercules. Чтобы
определить, можно ли   надеяться на надежность этой программы
в конкретном случае,    вызовите  HercModeTestWorks. Заметим,
что определить, какая страница видеопамяти активна (0 или 1),
невозможно.

Пример

if HercPresent then begin
if HercModeTestWorks and HercGraphicsMode then
SetHerc Mode (False,0);
....
end;

Проверка наличия платы  Hercules  и графического режима. Если
они  установлены, дисплей переключается на текстовый режим.

Смотрите также

HercPresent
SetHercMode
-------------------------------------------------------------------
Функция HercModeTestWorks: Boolean;

Hазначение

Вoзвратит True, если будет работать HercGraphicsMode

Описание

Эта программа предназначена для  использования  с  программой
HercGraphicsMode.  Ее  функция -  просто определить, будет ли
надежным тест данной программы.
---------------------------------------------------------------------
Функция HercPresent: Boolean;

Hазначение

Возвращает True, если установлена графическая плата Hercules.

Описание

Эта программа возвращает True, если в   системе   установлена
графическая плата Hercules.  Заметим,  однако,  что   наличие
платы Hercules не означает, что она активна: в двухдисплейных
системах Hercules может оказаться неактивной.

Пример

if HercPresent then begin
Writeln ('This program cannot be used on a Hercules display
adapter');
Halt;
end;
Останавливает программу, если установлена плата Hercules
----------------------------------------------------------------

Функция MakeHiddenAttr (A:Byte): Byte;

Hазначение

Делает цвета текста и фона одинаковыми

Описание

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

Примеры

МakeHiddenAttr ($70) {light gray on black}
Возвращает $00 (черный на черном)
МakeHiddenAttr ($1F) {white on blue}
Возвращает $11 (синий на синем)
----------------------------------------------------------------
Функция MapColor (C:Byte):Byte;

Hазначение

Hастраивает видеоатрибуты для визуализации на монохромных
/черно-белых дисплеях/

Описание

Если функция UseColor возвращает False, то эта функция просто
возвращает  входной  параметр (С) неизменным.  Иначе MapColor
будет  пытаться  придать параметру С значение, подходящее для
изображения на нецветном   дисплее, используя его как элемент
массива ColorMap. К сожалению,   совершенная настройка невоз-
можна, но во многих случаях MapColor работает хорошо. Заметим,
что ColorMap - глобальная типизованная константа, и   поэтому
Вы можете изменить способ настройки  цветов,  просто  изменив
массив.

Пример

FastWrite ('hello', 1, 1, MapSolor ($1C));

в цветной  системе на   экране   появится  "hello" красным по
синему.    В монохромном или черно-белом дисплее строка будет
белым    по черному.  Попробуйте  запустить  демонстрационную
программу    WINDOW в цветном и черно-белом (или монохромном)
pежимах,     чтобы лучше почувствовать, как работает MapColor

Смотрите также

UseColor
-------------------------------------------------------------------
Функция MapMono (Color,Mono: Byte): Byte;

Hазначение

Возвращает настроенный  цветной видеоатрибут, если Mono=$FF

Описание

Имея на входе цветной и монохромный видеоатрибуты, эта функция
возвращает или Mono, или, если Mono=$FF,   ColorMap  [Color].
Эта функция предназначена в основном для внутреннего  исполь-
вования

Примеры

МapMono ($4F, $07);

Возвращает $07

МapMono ($4F,$FF);

Возвращает ColorMap [$4F] (по умолчанию $70)
------------------------------------------------------------------
Процедура MoveScreen (var Sourse,Dest,Length:Word);

Hазначение

Перемещает Length слов с адреса Sourse по адресу Dest, подав-
ляя  снег

Описание

МoveScreen подобна стандартной процедуре Турбо Паскаля  Move,
но она предназначена строго для перемещения данных из обычной
памяти в видеопамять,  или  из  одного  места  видеопамяти  в
другое.  Также она отличается от стандартной Move тем, что не
может перемещать отдельные байты данных, только слова. Sourse
- это адрес, начиная   с   которого   берутся   данные    для
перемещения, Dest - адрес,  куда   перемещать   данные.  Если
сегментная часть обоих адресов   совпадает   с       памятью,
используемой CGA ($B8xx) и ChekSnow = True,       Move Screen
обеспечит подавление снега и мерцания; в остальных    случаях
он будет перемещать данные с максимально возможной скоростью.
Length - это количество перемещаемых слов.

Пример

var
ScreenBufPtr: Pointer;
BytesOnScreen: Word;
begin
BytesOnScreen:=(ScreenWidth * ScreenHeigth)*2;
GetMem (ScreenBufPtr, BytesOnScren);
MoveScreen (Mem [VideoSegment:0], ScreenBufPtr^, BytesOnScreen
div 2);
.....
MoveScreen (ScreenBufPtr^,Mem [VideoSegment:0], BytesOnScreen
Div 2);
FreeMem (ScreenBufPtr);
End;

Сохраняет содержимое экрана и затем   восстанавливает    его.
Заметим,   что   эта   работа   проще   выполняется с помощью
SaveWindow и RestoreWindow.

Смотрите также

RestoreWindow
SaveWindow
--------------------------------------------------------------------
Процедура NormalCursor;

Hазначение

Устанавливает нормальный размер курсора для текущего видеорежима

Описание

Эта программа восстанавливает курсор в его нормальный размер -
обычно 2 пиксела высотой.

Смотрите также

BlockCursor                   HiddenCursor
FatCursor                     SetCursоrSize
----------------------------------------------------------------
Функция ReadAttrAtCursor: Byte;

Hазначение

Возвращает атрибут текущей позиции курсора данной страницы.

Описание

Эта программа похожа на ReadCharAtCursor, только вместо  сим-
Вола   с   позиции  курсора  считывается  видеоатрибут  этого
Символа.

Пример

СharAtCursor: = ReadCharATCursor;
АttrAtCursor: = ReadAttrAtCursor;

Записывает символ, находящийся в позиции курсора, и его видео-
атрибут соответственно в CharAtCursor и AttrAtCursor.

Смотрите также

ReadCharAtCursor

------------------------------------------------------------------
Процедура ReadAttribute (Number: Byte: Row,Col: Word;
var St:String);

Hазначение

Считывает Number атрибутов с  экрана в строку St  начиная   с
позиции  Row,Col

Описание

Эта программа похожа на FastRead,  только  вместо  считывания
символов с экрана здесь происходит считывание видеоатрибутов.
Эта программа  также напоминает ReadAttrAtCursor, но  она на-
много быстрее. Number - это число атрибутов,    считываемых с
экрана. Row и Col определяют   позицию,  с которой начинается
считывание. А St - это    строка,   в  которую   записываются
считанные атрибуты.

Пример

ReadAttribute (ScrеenWidth, 1, 1, s);
for I=:1 to ScreenWidth do
Byte (s[I]:=SwapNible (Byte (s[I]) and $7F;
WriteAttribute (s,1,1);

Меняет местами цвета символов и фона в ряду 1.

Смотрите также

FastRead            WriteAttribute
FastWriteAttr

_______________________________________________________________


Функция ReadCharAtCursor : Char;

HАЗНАЧЕНИЕ

Читает символ из текущей позиции курсора.

ОПИСАНИЕ

Подобно процедуре FastRead  ReadCharAtCursor читает данные  с
экрана.  ReadCharAtCursor читает только один символ с  экрана
и требует,  чтоб курсор  был установлен  правильно. Процедура
имеет преимущество : она работает также    хорошо  и в режиме
графики CGA (точно также как и  процедуры Write и Writeln для
вывода текста). FastRead     может использоваться только    в
текстовых режимах.

ПРИМЕР

Var  X,Y : word;
     XY  : word;
     ...
degin
  XY := WhereXY;
  For Y := 1 to ScreenHeight do begin
   For X := 1 to ScreenWidth do begin
    GotoXY(X,Y); Write(lst, ReadCharAtCursor);
   end;
   Writeln(lst);
 end;
 GotoXYAbs( Lo(XY), Hi(XY) );
end;

Делает то же самое, что и процедура BIOS PrintScreen.

-----------------------------------------------------------

Function ReadKeyWord : Word;

HАЗНАЧЕНИЕ

Ожидает нажатие клавиши, а затем возвращает сканирующий код и
символьный код.

ОПИСАНИЕ

В  отличие  от  ReadKey  эта  процедура  возращает  оба  кода:
сканирующий  и  cимвольный коды  клавиши,   которая   нажата.
Младший байт  возвращаемого слова содержит символьный  код, а
старший -  сканирующий код.
ReadKeyWord имеет  два важных  преемущества перед  процедурой
ReadKey. Во-первых она  позволяет получить всю информацию  за
один  вызов.  Во-вторых  она  позволяет вам различать клавиши,
которые имеют одинаковые символьные коды,    однако    разные
сканирующие коды. Например,  в  стандартной клавиатуре PC  AT
существуют две клавиши,  которые возвращают '+':    одна    в
верхнем ряду основного блока клавиатуры, другая  - в цифровой
клавиатуре. Первая имеет сканирующий код 13 ($02b), а  вторая
имеет сканирующий код 78 ($4E). Используя   ReadKeyWord,   вы
можете различать такие клавиши. Смотрите пример.

ПРИМЕР

Var
  Key : word;
  Ch  : Char Absolute Key;
  ...
begin
  Key : ReadKeyWord;
      If Ch= '+'  then
      If(Hi(Key):=$4e) then
              Writeln('Большой плюс нажат')
         Else
              Writeln('Малый плюс нажат');

end;

CМОТРИТЕ ТАКЖЕ

CheckKbd

-----------------------------------------------------------

Procedure ReinitCRT;

HАЗНАЧЕНИЕ

Переустанавливает внутренние переменные модуля ОPCRT.

ОПИСАНИЕ

ReinitCRT  используется в основном :
 (1) в  TSR
 (2) в  программах, которые используют вызов ExecDos или Dos
 (3) в  программах, которые используют графику.
ReinitCRT  полностью   переустанавливает   все     изменяемые
глобальные   переменные,   использующиеся        в     ОPCRT:
СurrentMode  (Текущий видеорежим), InTexMode (False      если
графический  режим), ScreenWidth     (текущая ширина экрана),
ScreenHeight ( текущая высота экрана ),  WindMin,     WindMax
(размеры окна; текущим   окном   может   стать   весь экран),
CurrentPage  (текущая  видеостраница),  CurrentDisplay   (тип
текущего  видеоадаптера),  CheckSnow  (подавление "снега"  на
цветных мониторах), и VideoSegment (сегментная часть начально-
го адреса  дисплейной    памяти).
Вообще говоря, вызов ReinitCrt может потребоваться вам в трех
случаях : при перекрытии, после выполнения другой  программы,
или после включения/выключения графического режима.

СМОТРИТЕ ТАКЖЕ

ЕxecDos (ОРDOS)      GetCrtMode

-----------------------------------------------------------

Процедура RestoreCursorState (XY, ScanLines: word);

HАЗНАЧЕНИЕ

Восстанавливает    позицию  и  размер  курсора, сохраненные  с
помощью SetCursorState

ОПИСАНИЕ

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

СМОТРИТЕ ТАКЖЕ

Смотрите также описание   GetCursorState.

-----------------------------------------------------------

Процедура RestoreWindow(Xlow, Ylow, Xhight, Yhight : Byte;
Deallocate : boolean;  var Covers : pointer);

HАЗНАЧЕНИЕ

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

ОПИСАНИЕ

Вместе  с  SaveWindow  эта  процедура  создает удобный
механизм для сохранения и   восстановления  cодержимого всего
экрана или его части (окна).
Размеры восстанавливаемого окна     определяются   следующими
параметрами:    Xlow,    Ylow,   Xhight,   Yhight,   (Которые
представляют из себя  абсолютные  экранные  координаты). Хотя
координаты окна чаще всего будут такими же, что и в процедуре
SaveWindow, они не обязаны совпадать.Covers - это   указатель
буфера из которого будет   восстановлено   окно.   Deallocate
указывает, будет  или  нет  буфер  освобожден из динамической
памяти после того  как окно восстановиться.

ПРИМЕР

Смотрите описание SaveWindow

-----------------------------------------------------------

Процедура RestoreWindowCoordinates (WC: Window Coordinates);

Hазначение

Восстанавливает предварительно сохраненные координаты окна

Описание

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

Смотрите также

StoreWindowCoordinates

-----------------------------------------------------------------

Процедура SaveWindow(Xlow, Ylow, Xhight, Yhight : Byte;
         Deallocate : boolean;  Var Covers : pointer);

HАЗНАЧЕНИЕ

Выделяет память, если необходимо, под буфер и запоминает  там
окно.

ОПИСАНИЕ

Вместе с RestoreWindow  эта  процедура  создает удобный
механизм для сохранения и восстановления содержимого    всего
экрана или его части (окна). Размеры  сохраняемой     области
экрана    определяется следующими  параметрами:  Xlow,  Ylow,
Хhight,    Yhight,    (Которые    представляют    из     себя
абсолютные экранные координаты). Allocate указывает будет или
нет выделено место  под буфер из  динамической  памяти  перед
сохранением  окна. Если Allocate = True,   указатель   буфера
pазместиться в  Covers. Другими словами, Covers должен   быть
указателем буфера, достаточно большого, чтобы вместить    все
данные. SaveWindow  возвратит  False  лишь  если   Allocate =
= True , и не хватает места в динамической памяти под буфер.
Поскольку  SaveWindow  использует  процедуру  MoveScreen  для
перемещения данных, будет происходить подавление  мерцания  и
снега, если это необходимо.
Замечание : SaveWindow и RestoreWindow  работают   только   в
текстовых, а не в графических, режимах.

ПРИМЕР

Var
 BufPtr : Pointer;
Begin
If Not SaveWindow (1,1 ScreenWidth, ScreenHeight,
True, BufPtr) then exit;

{-- do something ----}

 RestoreWindow(1,1,ScreenWidth,ScreenHeight,True,BufPtr);
End;

Правильно. Будет размещен буфер и сохранен весь экран,  затем
восстановлен с помощью RestoreWindow.

If not SaveWindow(1,1,ScreenWidth,ScreenHeight,True,BufPtr^)
then exit;

Hеправильно! '^' в BufPtr^ не требуется.

СМОТРИТЕ ТАКЖЕ

RestoreWindow    MoveScreen

-----------------------------------------------------------

Procedure ScrollWindowDown ( Xlo,Ylo,Xhi,Yhi, lines : byte);

HАЗНАЧЕНИЕ

Смещает строки внутри окна на указанное количество строк вниз.

ОПИСАНИЕ

Эта процедура является альтернативой  процедуры InsLine в том
случае, когда вы не желаете перемещать курсор, или вы  хотите
переместить часть экрана, не входящую в текущее окно.
перемещаемое  окошко  определяется  Xlo,Ylo,Xhi,Yhi (Помните,
это   координаты   окна   задаются   в   абсолютных  экранных
координатах, не в относительных  оконных).  Lines -     число
строк, на  которые  необходимо сместить содержимое    окошка.
если Lines:=0, то  текущее окно очищается.
Подобно   процедуре   InsLine,   процедура   ScrollWindowDown
заполняет образовавшиеся  пустые    строки    пробелами     с
видеоатрибутами  TextAttr.
Следует   помнить,   что   если   BiosScroll:=False,   то для
выполнения  этой  функции  будет  использоваться  специальная
процедура, подавляющая снег и мерцание.

ПРИМЕР

Var
 I : word;
Begin
 ClrScr;
 For i := 1 to (ScreenHeight-2)*ScreenWidh) do
 Write('*');
 FrameWindow(1,1,ScreenWidht, ScreenHeight-2, TextAttr,
 TextAttr, 'ScrollWindowDown demonstration');
 Delay(2000);
 ScrollWindowDown(2,2,Pred(ScreenWidth),ScreenHeight-3,1);
end;

Заполняет все, кроме последних двух строк, звездочками, рисует
pамку вокруг всего экрана, затем смещает вниз содержимое окна
на одну строку.

-----------------------------------------------------------

Процедура ScrollWindowUp ( Xlo,Ylo,Xhi,Yhi, lines : byte);

HАЗНАЧЕНИЕ

Смещает строки внутри окна на указанное количество строк вверх.

ОПИСАНИЕ

Эта процедура является альтернативой  процедуры DelLine в  том
случае, когда вы не желаете перемещать курсор, или вы   хотите
переместить часть экрана, не входящую в текущее окно.
перемещаемое  окошко  определяется  Xlo,Ylo,Xhi,Yhi (Помните,
это   координаты   окна   задаются   в   абсолютных  экранных
координатах, не в относительных  оконных).  Lines -     число
строк, на  которые  необходимо сместить содержимое    окошка.
Если Lines:=0, то  текущее окно очищается.
Подобно   процедуре   InsLine,   процедура   ScrollWindowDown
заполняет образовавшиеся  пустые    строки    пробелами     с
видеоатрибутами  TextAttr.
Следует   помнить,   что   если   BiosScroll:=False,   то для
выполнения  этой  функции  будет  использоваться  специальная
процедура, подавляющая снег и мерцание.

ПРИМЕР

Смотрите пример в описании ScrollWindowDown выше.

-----------------------------------------------------------

Процедура SelectFont8x8 ( On : boolean);

HАЗНАЧЕНИЕ

Включает или выключает шрифт 8х8 в режиме 43 или 50 строк.

ОПИСАНИЕ

Эта  процедура  позволяет  вам  включать (Оn=True), или   вы-
ключать режим 43 строк EGA и 50 строк VGA. Если ни   один  из
этих  адаптеров  не  установлен, то  процедура  не произведет
никакого  действия. После  переключения на 43/50-    строчный
pежим глобальная переменная  ScreenHeight  будет  установлена
в  43  или  50, а не в 25. Однако текущие  оконные координаты
не  изменятся,  пока вы это сами не сделаете.
Эта процедура не очищает экран как это  делает   единственная
аналогичная процедура в  стандартном модуле CRT:

ТextMode(CurrentMode + Font8x8);

Следует  помнить, что  нормальный  курсор  (с 6 по 7 пикселы)
при переключении с помощью BIOS EGA в 43-строчный режим, исчез-
нет, если действует эмуляция курсора CGA. Для  предотвращения
этого, процедура SelectFont8x8    автоматически     отключает
эмуляцию при переходе в 43-строчный режим, и включает      ее
снова при возвращении в 25-строчный режим.

ПРИМЕР

If not CurrentDisplay < EGA then
 Wtiteln('EGA or VGA required')
Else
 begin
 Write('This is 25-line mode ');
 Delay(1000);
 SelectFont8x8(True);
 Write('And this is', ScreenHeight,'-line mode');
 Delay(1000);
 SelectFont8x8(False);
end;

CМОТРИТЕ ТАКЖЕ

Font8x8Selected

-----------------------------------------------------------

Процедура SetActivePage (PageNo: Byte);

Hазначение

Выбирает страницу видеопамяти для последующих   действий    с
экраном

Описание

Эта программа позволяет вам направить экранный вывод на  аль-
тернативную видеостраницу.  Типичный  пример ее использования
- случай,   когда требуется вывести сложное изображение, а вы
не хотите,   чтобы пользователь видел его, пока оно полностью
не сформировано.
Смотрите пример ниже.
SetActivePage связана с FastWrite, FlexWrite и другими  прог-
pаммами записи  на  экран  модуля  OPCRT,  не   использующими
функции BIOS (как, например, использует их ReadCharAtCursor).
Однако она не  взаимодействует с Writeln или Readln.
Заметим,   что   эта   функция   -   не  одно  и  тоже, что и
Graph.SetActivePage.

Пример

СlearPage(1);
SetActivePage(1);
{...write to page 1...}
SetVisiblePage (1);
{...do something...}
SetVisiblePage (0);

Чистит страницу 1, перерисовывает туда содержимое экрана,  не
позволяя   пользователю   увидеть   процесс        рисования;
визуализирует экран, и переключается   обратно на страницу 0.

Смотрите также

СlearPage     SetVisiblePage

--------------------------------------
Пpоцедуpа SetBlink (On: Boolean);

Hазначение

Pазрешает мерцание символов в текстовом режиме, если On=true

Описание

SetBlink разрешает или запрещает мерцание текста.  Если   оно
dыключено, то "яркие" цвета, такие, как розовый ($D) и желтый
($E) могут  использоваться как фоновые.
Чтобы посмотреть,  чего  можно  достигнуть, отключая SetBlink,
запустите демонстрационную программу DESKPOP,  найдите  окно с
картой    цветов,  нажмите <CtrlPgUp>, чтобы оказаться в конце
карты цветов,   затем <Ctrl B>,  чтобы выключить мерцание. Все
значения, большие 127,    будут соответствовать цветам с более
ярким фоном.

Пример

TextAttr: = $8F;
Writeln ('This produces blinking text');
Setblink (False);
Writeln ('This doesn't, even though the attribute is the same');

Первая строка высветится белым на мерцающем черном фоне. Вторая -
белым на темно-сером фоне.


---------------------------------------------------------------

Процедура SetCrtBorder (Attr: Byte);

Hазначение

Устанавливает атрибут бордюра экрана в Attr, если тип платы и
текущий  режим позволяют это.

Описание

SetCrtBorder позволяет вам  установить  для   бордюра  экрана
видеоатрибут    (Attr) в  случае цветных адаптеров (CGA, MCGA,
ЕGA, VGA). Она ничего не делает, если установлена монохромная
плата. Предупреждаем вас,  что    зрительный   эффект    этой
процедуры меньше по сравнению с работой плат EGA.

Пример

ТextColor (While);
ТextBackground (Blue);
СlrScr;
SetCrtBorder (Blue shi 4);

Устанавливает цвета экрана в белый на синем, а бордюр  экрана
- в синий.

----------------------------------------------------------------

Процедура SetCursorSize (StartLine, EndLine: Byte);

Hазначение

Устанавливает начальный и конечный пикселы курсора

Описание

Хотя другие процедуры OPCRT позволяют   вам  изменять  размер
курсора, эта     процедура -  единственная, дающая вам полный
контроль над начальным    и  конечным   пикселами  курсора. В
монохромном текстовом режиме (7),    коробка курсора содержит
14 пикселов, пронумерованных  сверху  вниз  от  0  до  13.  В
цветных текстовых режимах коробка курсора имеет   8 пикселов,
пронумерованных сверху вниз от 0 до 7.  Заметим,   что,  хотя
коробка   курсора   EGA  имеет  14   пикселов,   обычно   она
соответствует  коробке  СGA  (для  совместимости),  и   таким
образом может задействовать только     8 пикселов в текстовых
pежимах.

Пример

if CurrentMode = 7 then
Endline: = $OD {=13}
else
Endline: = $07  {=7}
SetCursorSize (O,Endline);

Формирует "блочный" курсор (смотрите описание BlockCursor)

Смотрите также

BlockCursor                 HiddenCursor
FatCursor                   NormalCursor

----------------------------------------------------------------

Процедура SetCursorType (CT: Cursor Type);

Hазначение

Устанавливает форму курсора в соответствии с определенным типом.

Описание

SetCursorType объединяет действия четырех  других  программ -
BlockCursor,  HiddenCursor,  FatCursor и NormalCursor -    в
одну. Обычно  она используется   вместе с ClassifyCursorType.
СТ может иметь одно из следующих значений: cuNormal, cuBlock,
или cuHidden. Если СТ установлен в cuUnknown, то курсор будет
невидимым, точно так же, если бы СТ был равен cuHidden

Пример

var
SaveCursorTyoe: Cursor Type;
begin
SaveCursorType: = ClassifyCursorType;
GetCursorType (cuHidden);
...
SetCursorType (SaveCursorType);
end;
Сохраняет текущий  тип   курсора,   "прячет"   курсор,  затем
восстанавливает  его.

Смотрите также

BlockCursor             HiddenCursor        FatCursor
ClassifyCursorType      NormalCursor

---------------------------------------------------------------

Процедура SetHercMode (GraphMode: Boolean; GraphPage: Byte);

Hазначение

Устанавливает  плату  Hercules  для  работы  в  текстовом или
графическом   режиме

Описание

Эта программа позволяет  вам  использовать плату Hercules как
в графическом (GraphMode = True),   так  и в текстовом режиме
(GraphMode = False).   Если  GraphMode = True,  то  GraphPage
определяет, какая из видеостраниц  графики  будет  активна (0
или 1). Если GraphMode = False, то  GraphPage игнорируется.

Пример

HercGraph: = HercGraphicsMode;
if HercGraph then SetHercMode (False, 0);
...
if HercGraph then SetHercMode (True, 0);

Переключает графическую  плату  Hercules в текстовый режим, а
затем обратно    в графический рeжим.

Смотрите также

HercGraphicsMode        HercPresent

-----------------------------------------------------------------

Процедура SetVisiblePage (PageNum: Byte);

Hазначение

Устанавливает текущую видеостраницу

Описание

Эта программа позволяет вам установить текущую  видеостраницу
цветных   адаптеров (CGA, EGA, MCGA или VGA). При монохромном
адаптере она   не действует. В 40-колоночном текстовом режиме
существует  8   видеостраниц   (с   номерами  от  0  до 7). В
80-колоночном текстовом режиме  существует 4 видеостраницы (с
номерами 0-3). Заметим,  что  номер   текущей   видеостраницы
всегда запоминается в CurrentPage. Также    заметим,  что эта
функция не одно и тоже, что и Graph.SetVisiblePage.

Пример

if CurrentMode = 7 then
Writeln ('Color adapter required')
else begin
Writeln ('This is video page O');
Delay (1000);
SetVisiblePage (1);
ClrScr;
Writeln ('This is video page 1');
Delay (1000);
SetVisiblePage (0);
end;

Cмотрите также

SetActivePage

----------------------------------------------------------------

Процедура StoreWindowCoordinates (var WC: Window Coordinates);

Hазначение

Сохраняет координаты текущего окна

Описание

Эта программа позволяет вам  сохранять  координаты  активного
окна. Они    впоследствии  могут быть восстановлены с помощью
RestoreWindowCoordinates.

Пример

var WC: Window Coordinates;
begin
StoreWindowCoordinates (WC);
Window (1,1,80,10);
...
RestoreWindowCoordinates (WC);
end;

Cмотрите также

RestoreWindowCoordinates

-----------------------------------------------------------------


Процедура StuffKey (W: Word);

Назначение

Вставляет код клавиши в буфер клавиатуры

Описание

Эта программа включает  код   определенной  клавиши  в буфер
клавиатуры. Если буфер полон, эта программа не делает ничего.

Примеры

StuffKey ($3800);

Включает код клавиши <F1> в буфер клавиатуры

StuffKey (Ord('A'));

Включает код клавиши <A> в  буфер  клавиатуры.  (Большинство
программ игнорируют старший байт  кода клавиши, если младший
байт ненулевой)

--------------------------------------------------------------------
Процедура StuffString (S: string);

Назначение

Вставляет содержимое строки S в буфер клавиатуры

Описание

Эта программа записывает определенную строку  прямо  в  буфер
клавиатуры. Строка должна быть не  более 15  символов длиной
(в предположении, что изначально буфер пуст). Лишние символы
игнорируются. Как и StuffKey,   эта   программа   может быть
использована   в   простых   макросистемах,   работающих   с
клавиатурой, а  также при работе с клавиатурой в программах,
работающих с Exec (DOS) или ExecDos (OPDOS)

Пример

StuffString ('Hello world!' ^M);
Readln (MyString);
Загружает в буфер MyString: 'Hello world!'

-----------------------------------------------------------------
Процедура SwitchColorCard (ColorOn: Boolean);

Назначение

Включает и выключает цвета на плате HerculesInColor

Описание

Эта программа включает и выключает эмуляцию  CGA  на   плате
HerculesInColor.   Она   может   быть   вызвана только  если
глобальная переменная WhichHerс  установлена  в HerсInColor.
Заметим, что эа программа  вызывается  автоматически   кодом
инициализации    OPCRT   при   включении    эмуляции    CGA.
Следовательно,    все,  что   вам надо сделать для поддержки
платы   InColor   в   большинстве  программ -  это проверить
значение, возвращаемое UseColor при выборе цветов для текста
на экране. Если   возвращается True, вы должны выбрать те же
цвета, что вы     используете при CGA или другой графической
плате, даже если текущий видеорежим равен 7.
Возвращаясь к   данной   процедуре,  SwitchInColorCard нужно
вызывать, только если вы хотите отключить  эмуляцию CGA, или
если   вы   хотите  перезапустить  эмуляцию после выполнения
какой-либо другой программы.

Пример

If WhichHerc = HercInColor then
SwitchInColorCard(False);
{...execute the other program...}
if WhichHerc = HercInColor then
SwitchIncolorCard(True);

Переход в монохромный видеорежим, выполнение другой программы,
затем переустановка эмуляции CGA.

______________________________________________________________

Функция UseColor : Boolean;

Назначение

Возвращает True, если будут использованы цветные видеоатрибуты.

Описание

Эта функция определяет, будут ли выбраны цветные видеоатрибу-
ты,  когда делается выбор между цветным и монохромным (черно-
белым)  видеорежимами. На результат UseColor влияет несколько
факторов.    Если   глобальная   типизованная       константа
DefColorChoice установлена  в   ForceColor   или   ForceMono,
UseColor возвращает True    или  False   соответственно. Если
DefColorChoice установлена в     UseDefault, как это и бывает
по умолчанию, тогда результат зависит от текущего видеорежима
: если режим 0 (BW40) или    2 (BW80), то возвращается False;
если режим 7 (MONO), то также будет возвращаться False (кроме
случая, когда глобальная  переменная  WhichHerc установлена в
HercInColor);  во всех остальных случаях возвращается True.

Пример

TextColor(White);
if UseColor then
TextBackground(Blue)
else
TextBackground(Black);
ClrScr;

Заливает экран голубым, если цветной дмсплей, и черным, если
монохромный.

Cмотрите также

ColorMono

______________________________________________________________

Функция WhereXAbs : Byte;

Назначение

Возвращает абсолютную Х-координату (колонку) курсора.

Описание

Как и стандартная функция WhereX, эта  процедура  возвращает
текущую  координату  Х  (колонку)  курсора,  но в абсолютном
исчислении, а не в  координатах   текущего  окна.  Как и для
WhereX, координаты отсчитываются  от  левого   верхнего угла
экрана (1,1).

Пример

Window(3,3,80,25);
GotoXY(1,1);

В этом случае WhereX вернет значение 1, а WhereXAbs - 3.

Смотрите также

WhereYAbs

---------------------------------------------------------------

Функция WhereXY : Word;

Назначение

Возвращает абсолютные Х и У- координаты курсора (колонку и
строку).

Описание

Эта программа является объединением  WhereXAbs и  WhereYAbs,
позволяя вам получать оба числа за один вызов. Cтарший  байт
результата содержит координату У   (строку),  младший байт -
- координату Х (колонку).  Как  и  для WhereXAbs, WhereYAbs,
координаты отсчитываются с левого верхнего угла (1,1)

Пример

Window(3,3,80,25);
GotoXY(1,1);

В этом случае WhereX и WhereY возвратят 1, WhereXAbs и
WhereYAbs возвратят 3, а WhereXY возвратит $0303 (771)

Смотрите также

WhereYAbs       WhereXYDirect

---------------------------------------------------------------

Процедура WhereXYDirect (var X,Y : Byte);

Назначение

Считывает текущую позицию курсора прямо в контроллер CRT

Описание

В отличие от других  программ  OPCRT,   считывающих  позицию
курсора, эта  процедура  считывает   позицию  курсора  прямо
в контроллер CRT  6845,  используя  обращения  к портам и не
используя BIOS.  Очевидно,  это  делает  WhereXYDirect  чре-
звычайно аппаратно-зависимой, но вместе с тем позволяет  вам
точно узнать позицию  курсора  в случаях,  когда   остальные
программы   не   работают.   Наиболее   часто  WhereXYDirect
употребляется в   TSR,  которые   иногда  запрашиваются  пе-
рекрывающими прикладными программами, не использующими  BIOS
для вычисления позиции курсора.   Наиболее  известный пример
такой программы - это Lotus 1-2-3, но есть и много  других.

Пример

Var
SaveX,SaveY : Byte;
begin
{get the cursor position}
WhereXYDirect(SaveX,SaveY);
{update the BIOS's cursor data}
GotoXYAbs(SaveX,SaveY);
...
{restore the cursor to its previous position}
GotoXYAbs(SaveX,SaveY);
end;

Смотрите также

GotoXYAbs             WhereXY

-----------------------------------------------------------------

Функция WhereYAbs : Byte;

Назначение

Возвращает абсолютную Y-координату (строку) курсора.

Описание

Как и стандартная функция WhereY, эта процедура   возвращает
текущую координату   Y  (строку)   курсора,  но в абсолютном
исчислении, а  не  в  координатах  текущего  окна. Как и для
WhereУ,  координаты  отсчитываются  от  левого верхнего угла
экрана (1,1).

Пример

Window(3,3,80,25);
GotoXY(1,1);

В этом случае WhereУ вернет значение 1, а WhereУAbs - 3.

Смотрите также

WhereХAbs         WhereXY

---------------------------------------------------------------

Процедура WriteAttribute (St : string; Row,Col : Word);

Hазначение

Пишет строку  атрибутов  St  начиная  с  позиции Row, Col, не
изменяя символов.

Описание

Эта программа пишет  строку  видеоатрибутов на экран, начиная
с  позиции Row, Col. Символы на экране не меняются. WriteAtt-
ribute  предназначена  для использования совместно с ReadAtt-
ribute.

Пример

ReadAttribute (ScreenWidth,1,1,s);
for i:=1 to ScreenWidth do
Byte (s[i]):=SwapNibble(Byte(s[i]) and $7f;
WriteAttribute(s,1,1);

Mеняет местами цвета символов и фона в первой строке.

Cмотрите также

ReadAttribute

-----------------------------------------------------------------


                   2.  ColorSet

Один из важнейших  объектных  типов,  определенных в OPСRT,  -
это ColorSet.  Его  идея  в  конечном  счете  проста, но лучше
всего понять ее посредством сравнения.
При написании  Turbo   Professional,   предшественника  Object
Рrofessional,  мы часто замечали, что пытаемся найти наилучший
способ  помочь  программисту   с  выбором цветов в разработках
меню, списков   для   выбора,  записи данных на экран и других
экранно-ориентированных программах.
Со временем  число   предлагаемых   способов  росло: некоторые
программы   работали  с  наборами  видеоатрибутов  в  качестве
параметров; другие брали в качестве параметра один, специально
подобранный массив  видеоатрибутов, третьи требовали изменения
глобальных переменных, и так далее.
Когда мы начали  работу  над  Object  Professional,  мы решили
привести   в  порядок общую стратегию выбора цветов. Поскольку
большинство программ используют одни и те же цвета для похожих
функций (рамок окон,    заголовков окон, текстов внутри окон и
т.д.), мы пожелали, чтобы   массив  всех выбираемых цветов был
сосредоточен в одной определенной    структуре,  которая может
быть доступна любой программе. Мы также   стремились упростить
написание программ, которые смотрелись  бы    хорошо  как   на
цветных, так и на монохромных мониторах. Программист,  считали
вы, должен иметь право выбора альтернативных видеоатрибутов, и
иметь библиотечную программу, выбирающую подходящий для работы
атрибут.
Результатом наших стремлений стал ColorSet, объект, содержащий
31  пару видеоатрибутов, которые можно использовать для всего:
от рамок  окон  до  выделения  помеченных  блоков   данных   в
текстовых редакторах.  В  отличие  от  других  объектов Oblect
Рrofessional, ColorSet   на самом деле не выполняет "реальной"
pаботы. Хотя он использует различные методы (все-статические),
эти методы лишь выбирают определенные значения из поля данных.
Работа  ColorSet  заключается  просто  в  "выдаче рецептов", и
хранении цветовых  комбинаций, которые могут легко быть целыми
группами использованы  в других объектах.
СolorSet   почти   всегда   описывается как набор типизованных
констант, как, например, следующие:

    Const MyColorSet : Colorset = (
          TextColor      : $1e;   TextMono     : $0f;
          CtrlColor      : $1c;   CtrlMono     : $07;
          FrameColor     : $13;   FrameMono    : $07;
          HeaderColor    : $3f;   HeaderMono   : $70;
          ShadowColor    : $08;   ShadowMono   : $70;
          HighLightColor : $4f;   HighLightMono: $70;
          PromptColor    : $30;   PromptMono   : $07;
          SelPromptColor : $30;   SelPromptMono: $07;
          ProPromptColor : $30;   ProPromptMono: $07;
          FieldColor     : $31;   FieldMono    : $0f;
          SelFieldColor  : $31;   SelFieldMono : $0f;
          ProFieldColor  : $17;   ProFieldMono : $07;
          ScrollBarColor : $13;   ScrollBarMono: $07;
          SliderColor    : $13;   SliderMono   : $0f;
          HotSpotColor   : $30;   HotSpotMono  : $70;
          BlockColor     : $3e;   BlockMono    : $0f;
          MarkerColor    : $5f;   MarkerMono   : $70;
          DelimColor     : $31;   DelimMono    : $0f;
          SelDelimColor  : $31;   SelDelimMono : $0f;
          ProDelimColor  : $31;   ProDelimMono : $0f;
          SelItemColor   : $3e;   SelItemMono  : $70;
          ProItemColor   : $17;   ProItemMono  : $07;
          HighItemColor  : $1f;   HighItemMono : $0f;
          AltItemColor   : $1f;   AltItemMono  : $0f;
          AltSelItemColor: $3f;   AltSelItemMono: $70;
          FlexAHelpColor : $1f;   FlexAHelpMono: $0f;
          FlexBHelpColor : $1f;   FlexBHelpMono: $0f;
          FlexCHelpColor : $1b;   FlexCHelpMono: $70;
          UnselXrefColor : $1e;   UnselXrefMono: $09;
          SelXrefColor   : $5f;   SelXrefMono  : $70;
          MouseColor     : $4f;   MouseMono    : $70);

Значения  из  левого  столбца  (ХххColor)  предназначены  для
использования   в   цветных  дисплеях;  из  правого   столбца
(ХххMono) - в монохромных   или черно-белых дисплеях.
Как отмечено выше,   единственная   операция,  которую  можно
сделать с  ColorSet -  это  передать его как параметр другому
конструктору.
Hапример:
МyStackWindow.InitCustom (2,2,79,24,MyColorSet,wBordered)

В большинстве  случаев  конструктор объекта скопирует те пары
видеоатрибутов, которые ему  нужны  для  работы. Если какому-
либо из правил  объекта    потребуется отобразить что-либо на
экране, то ему нужно выбрать   пару   атрибутов  (ХххColor  и
ХxxMono) и передать ее  на   вход  программы ColorMono модуля
ОPCRT, и ColorMono   сделает   правильный выбор,   подходящий
текущему дисплейному адаптеру.
Hиже перечислены все поля данных ColorSet, и краткие описания,
что для чего используется. Во многих  случаях   использование
данного  поля  ясно  из  названия.  Например,  FrameColor   и
FrameMono используются  как видеоатрибуты для рисования рамок
вокруг окон. В других случаях, однако, характер использования
полей данных ясен   не сразу. Эти случаи можно разбить на две
категории. В первой - значения,  используемые  лишь одним или
двумя объектами,   такие как    FlexAHelpColor/FlexAHelpMono,
используемые только в OPHELP.   Подробное   описание     этих
значений можно найти  в   документации  объекта,  работающего
с ними. Во второй категории - значения, используемые  разными
объектами  в  разных  случаях. Наиболее типичен такой пример,
как TextColor/TextMono.  Для  любых  объектов,  работающих  с
окнами, они показывают,  каким   цветом  очищать внутренность
окна, и любой текст,   написанный  внутри  окна,  будет иметь
данный атрибут. Но некоторые   объекты, такие как PickLists и
Мenus, также используют TextColor/TextMono,  но   с   другими
целями. Что это за цели, можно прочесть   в документации этих
объектов.


                        Типы


  ColorSet =
   object
    TextColor,TextMono : Byte;
    {Ordinary text; interior portion of the window;
     unselected pick/menu items}
    CtrlColor,CtrlMono : Byte;
    {Control characters, when displayed in uppercase alpas}
    FrameColor,FrameMono : Byte;
    {Window frames}
    HeaderColor,HeaderMono : Byte;
    {Window headers}
    ShadowColor,ShadowMono : Byte;
    {Window shadows}
    HighLightColor,HighLightMono : Byte;
    {Color used to highlight text found by TextEditor}
    PromptColor,Promptmono : Byte;
    {Prompts for unselected data entry fields}
    SetPromptColor,SetPromptMono : Byte;
    {Prompts for selected data entry fields}
    ProPromptColor,ProPromptMono : Byte;
    {Prompts for protected data entry fields}
    FieldColor,FieldMono : Byte;
    {Unselected data entry fields}
    SetFieldColor,SetFieldMono : Byte;
    {Selected data entry fields}
    ProFieldColor,ProFieldMono : Byte;
    {Protected data entry fields}
    ScrollBarColor,ScrollBarMono : Byte;
    {Scrolls bars}
    SliderColor,SliderMono :Byte;
    {Slider in scroll bars}
    HotSpotColor,HotSpotMono : Byte;
    {Mouse hot spots}
    BlockColor,BlockMono : Byte;
    {Marked blocks in a TextEditor, Browser}
    MarkerColor,MarkerMono : Byte;
    {Text markers in TextEditor, Browser}
    DelimColor,DelimMono : Byte;
    {Delimiters for unselected data entry fields}
    SelDelimColor,SelDelimMono : Byte;
    {Delimiters for selected data entry fields}
    ProDelimColor,ProDelimMono : Byte;
    {Delimiters for protected data entry fields}
    SelItemColor,SelItemMono : Byte;
    {Selected pick and menu items}
    ProItemColor,ProItemMono : Byte;
    {Protected pick and menu items}
    HighItemColor,HighItemMono : Byte;
    {HighLight characters in menu items}
    AltItemColor,AltItemMono : Byte;
    {Alternate color for unselected pick items}
    AltSelItemColor,AltSelItemMono : Byte;
    {Alternate color for selected pick items}
    FlexAHelpColor,FlexAHelpMono : Byte;
    {Highlighted help text surrounded by ^A}
    FlexBHelpColor,FlexBHelpMono : Byte;
    {Highlighted help text surrounded by ^B}
    FlexCHelpColor,FlexCHelpMono : Byte;
    {Highlighted help text surrounded by ^C}
    UnselXrefColor,UnselXrefMono : Byte;
    {Unselected cross reference in a help screen}
    SelXrefColor,SelXrefMono : Byte;
    {Selected cross reference in a help screen}
    MouseColor,MouseMono : Byte;
    {Color for mouse cursor; a placeholder, never
     used directly}
   end;

Список видеоатрибутов, используемых различными объектами.

---------------------------------------------------------------

Процедура SetXxxAttr (Color,Mono : Byte);

Hазначение

Устанавливает одну пару видеоатрибутов

Описание

Все правила   для ColorSet  имеют такой  вид, где 'Xxx' - это
имя атрибутов,  которые  должны быть изменены.  Полный список
правил  приведен  ниже.  Сolor - это видеоатрибут, использую-
щийся в цветных дисплеях, Mono -  атрибут для монохромных или
черно-белых   дисплеев.   Заметим,  что   если Mono=$ff (т.е.
АutoMapMono),  то  монохромный атрибут будет выбран автомати-
чески    из   таблицы   переводов   ColorMар   (т.е.   Mono =
СolorMap[Color]).  Вот список правил :

    Правило                 Использование атрибута

 SetBlockAttr             Помеченные блоки
 SetCtrlAttr              Управляющие символы
 SetDelimAttr             Граница непомеченного поля
 SetFieldAttr             Непомеченное содержимое полей
 SetFlexAHelpAttr         Справочный текст, вызываемый по ^A
 SetFlexBHelpAttr         Справочный текст, вызываемый по ^B
 SetFlexCHelpAttr         Справочный текст, вызываемый по ^C
 SetFrameAttr             Рамки окон
 SetHeaderAttr            Заголовки окон
 SetHighLightAttr         Повышенная яркость редактируемого
                          или просматриваемого текста
 SetHighLightItemAttr     Повышенная   яркость   символов в
                          пунктах меню
 SetHotSpotAttr           "Горячие кнопки" мыши
 SetMarkerAttr            Маркеры текста
 SetMouseАttr             Курсор мыши
 SetPromptAttr            Подсказки содержимого полей
 SetProtectedDelimAttr    Защищенные разделители полей
 SetProtectedFieldAttr    Защищенные поля
 SetProtectedItemAttr     Защищенные элементы меню и списков
 SetProtectedPromptAttr   Защищенные подсказки полей
 SetScrollBarAttr         Просматриваемые столбцы
 SetSelectedDelimAttr     Выбранные разделители полей
 SetSelectedFieldAttr     Выбранное содержимое полей
 SetSelectedItemAttr      Выбранные элементы меню и списков
 SetSelectedPromptAttr    Выбранные  подсказки  содержимого
                          полей
 SetSelXrefAttr           Выбранная для просмотра информация
                          в справочных текстах
 SetShadowAttr            Тени окон
 SetSliderAttr            "Скользящий просмотр" столбцов
 SetTextAttr              Обычный текст
 SetUnselXrefAttr         Невыбранная просматриваемая инфор-
                          мация в справочных текстах

Примеры

МyColorSet.SetTextAttr($1f,$0f);

Устанавливает атрибуты текста в белый-на-синем в цветном
дисплее, и в белый-на-черном - в монохромном.

МyColorSet.SetTextAttr($1f,AutoMapMono);
МyColorSet.SetTextAttr($1f,$ff);

Эти два выражения функционально идентичны. Оба  констатируют,
что монохромный атрибут  будет  выбран  автоматически. В этом
конкретном примере  монохромный  атрибут  будет  установлен в
$0f (=ColorMap[$1f]).



      C.    OPCOLOR :    ИМЕНА ЦВЕТОВ

  Этот модуль предлагается в помощь пользователям,   которые
предпочитают использовать константы с именами, а не  шестнад-
цатиричные числа в   качестве  видеоатрибутов.  Использование
этого модуля - дело вкуса. Ниже  приводится   полный   список
констант модуля OPCOLOR.
  В самом Object  Professional  модуль  OPCOLOR используется
только утилитами MAKEMENU и   MAKESCRN,   каждая  из  которых
может самостоятельно  генерировать  коды,  которым ставятся в
соответствие константы модуля OPCOLOR.
  Заметим, что OPCOLOR не определяет констант и видеоатрибу-
тов  с   кодами,   большими,  чем   $7f.   Однако,  вы можете
достигнуть  желаемого эффекта, добавив "+Blink" в конце имени
цвета.   К примеру, чтобы получить мерцающий белый на красном
текст,   используйте  имя  " WhiteOnRed+Blink".  (Blink - это
константа, определенная в модуле OPCRT).

                  Константы

    {Black background}
      BlackOnBlack      = $00;
      BlueOnBlack       = $01;
      GreenOnBlack      = $02;
      CyanOnBlack       = $03;
      RedOnBlack        = $04;
      MagentaOnBlack    = $05;
      BrownOnBlack      = $06;
      LtGrayOnBlack     = $07;
      DkGrayOnBlack     = $08;
      LtBlueOnBlack     = $09;
      LtGreenOnBlack    = $0a;
      LtCyanOnBlack     = $0b;
      LtRedOnBlack      = $0c;
      LtMagentaOnBlack  = $0d;
      YellowOnBlack     = $0e;
      WhiteOnBlack      = $0f;

      {Blue background}
      BlackOnBlue      = $10;
      BlueOnBlue       = $11;
      GreenOnBlue      = $12;
      CyanOnBlue       = $13;
      RedOnBlue        = $14;
      MagentaOnBlue    = $15;
      BrownOnBlue      = $16;
      LtGrayOnBlue     = $17;
      DkGrayOnBlue     = $18;
      LtBlueOnBlue     = $19;
      LtGreenOnBlue    = $1a;
      LtCyanOnBlue     = $1b;
      LtRedOnBlue      = $1c;
      LtMagentaOnBlue  = $1d;
      YellowOnBlue     = $1e;
      WhiteOnBlue      = $1f;

      {Green background}
      BlackOnGreen      = $20;
      BlueOnGreen       = $21;
      GreenOnGreen      = $22;
      CyanOnGreen       = $23;
      RedOnGreen        = $24;
      MagentaOnGreen    = $25;
      BrownOnGreen      = $26;
      LtGrayOnGreen     = $27;
      DkGrayOnGreen     = $28;
      LtBlueOnGreen     = $29;
      LtGreenOnGreen    = $2a;
      LtCyanOnGreen     = $2b;
      LtRedOnGreen      = $2c;
      LtMagentaOnGreen  = $2d;
      YellowOnGreen     = $2e;
      WhiteOnGreen      = $2f;

      {Cyan background}
      BlackOnCyan      = $30;
      BlueOnCyan       = $31;
      GreenOnCyan      = $32;
      CyanOnCyan       = $33;
      RedOnCyan        = $34;
      MagentaOnCyan    = $35;
      BrownOnCyan      = $36;
      LtGrayOnCyan     = $37;
      DkGrayOnCyan     = $38;
      LtBlueOnCyan     = $39;
      LtGreenOnCyan    = $3a;
      LtCyanOnCyan     = $3b;
      LtRedOnCyan      = $3c;
      LtMagentaOnCyan  = $3d;
      YellowOnCyan     = $3e;
      WhiteOnCyan      = $3f;

      {Red background}
      BlackOnRed      = $40;
      BlueOnRed       = $41;
      GreenOnRed      = $42;
      CyanOnRed       = $43;
      RedOnRed        = $44;
      MagentaOnRed    = $45;
      BrownOnRed      = $46;
      LtGrayOnRed     = $47;
      DkGrayOnRed     = $48;
      LtBlueOnRed     = $49;
      LtGreenOnRed    = $4a;
      LtCyanOnRed     = $4b;
      LtRedOnRed      = $4c;
      LtMagentaOnRed  = $4d;
      YellowOnRed     = $4e;
      WhiteOnRed      = $4f;

      {Magenta background}
      BlackOnMagenta      = $50;
      BlueOnMagenta       = $51;
      GreenOnMagenta      = $52;
      CyanOnMagenta       = $53;
      RedOnMagenta        = $54;
      MagentaOnMagenta    = $55;
      BrownOnMagenta      = $56;
      LtGrayOnMagenta     = $57;
      DkGrayOnMagenta     = $58;
      LtBlueOnMagenta     = $59;
      LtGreenOnMagenta    = $5a;
      LtCyanOnMagenta     = $5b;
      LtRedOnMagenta      = $5c;
      LtMagentaOnMagenta  = $5d;
      YellowOnMagenta     = $5e;
      WhiteOnMagenta      = $5f;

      {Brown background}
      BlackOnBrown      = $60;
      BlueOnBrown       = $61;
      GreenOnBrown      = $62;
      CyanOnBrown       = $63;
      RedOnBrown        = $64;
      MagentaOnBrown    = $65;
      BrownOnBrown      = $66;
      LtGrayOnBrown     = $67;
      DkGrayOnBrown     = $68;
      LtBlueOnBrown     = $69;
      LtGreenOnBrown    = $6a;
      LtCyanOnBrown     = $6b;
      LtRedOnBrown      = $6c;
      LtMagentaOnBrown  = $6d;
      YellowOnBrown     = $6e;
      WhiteOnBrown      = $6f;

      {Light Gray background}
      BlackOnLightGray      = $70;
      BlueOnLightGray       = $71;
      GreenOnLightGray      = $72;
      CyanOnLightGray       = $73;
      RedOnLightGray        = $74;
      MagentaOnLightGray    = $75;
      BrownOnLightGray      = $76;
      LtGrayOnLightGray     = $77;
      DkGrayOnLightGray     = $78;
      LtBlueOnLightGray     = $79;
      LtGreenOnLightGray    = $7a;
      LtCyanOnLightGray     = $7b;
      LtRedOnLightGray      = $7c;
      LtMagentaOnLightGray  = $7d;
      YellowOnLightGray     = $7e;
      WhiteOnLightGray      = $7f;



                E . OPCMD : Обработка команд

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

Ch:=ReadKey;
If Ch = #0 then begin
Ch:=ReadKey;
case Ch of
#3b:(F1);
#3C:(F2);
else {something else};
end;
end
else case Ch of
#27:{Escape};
^H:{BackSpace}
^I:{Tab};
else {something else};
end;

  Рассмотрим этот пример : мы распознаем, какая клавиша  на-
жата, и выполняем определенные действия - соответствующие на-
жатым клавишам "команды".  Всем известно,  что  такой  подход
удобен во многих случаях. Но есть ситуации, когда он неприем-
лем. Допустим, вы используете такой подход в своей программе,
и пользователи вашей программы захотели переопределить назна-
чения клавиш, cоответствия между нажатыми клавишами и "коман-
дами". Конечно, этого не удастся сделать, не внося в програ-
мму многочисленных изменений, потому что все назначения кла-
виш были вами "жестко закреплены". Так что для удовлетворения
желаний ваших пользователей  вам  нужно  использовать  другой
способ перевода нажатий клавиш в команды.
  Первое, что вам пригодится, -  это  набор  "кодов команд",
- cписок номеров, соответствующих всем командам вашей програм-
мы.  Этот набор поможет вам определить другую нужную   вещь -
таблицу соответствий нажатий клавиш (или групп клавиш) и  ко-
манд в различных частях вашей программы. Каждая таблица  будет
содержать набор строк, состоящих из кода команды и одного или
более соответствующих кодов клавиш.
   Следующий шаг - это написание  программы,  которая  должна
переводить нажатия клавиш в коды команд. Получив нажатие кла-
виши (или группы клавиш) она  будет   просматривать   таблицу
соответствий и выберет подходящий код команды. Эта  процедура
не обязана знать о фактическом назначении нажатой клавиши, ее
дело - найти нужный код команды.
   Объединив все назначения клавиш в структуру  определенного
формата, вы дадите пользователю возможность изменять эти наз-
начения, может быть, с помощью определенной процедуры  конфи-
гурации в той же программе, а может быть, с помощью отдельной
инсталляционной программы, которая будет находить эти таблицы
в EXE - файле основной программы, менять их и записывать  об-
pатно.
   Кроме возможности менять назначения клавиш, в этом  методе
есть и другие очевидные выгоды. К примеру, если одна и та  же
таблица соответствий используется в трех разных   программах,
вы можете изменить назначения клавиш во всех трех программах,
изменив их в одной таблице.
   Как вы уже, видимо, догадались, ниже речь  пойдет  о  том,
как выполняется обработка команд в Turbo  Professional.   Она
обеспечивается модулем OPCMD.

                     1. Коды команд

  Во-первых, в OPCMD определены стандартные коды команд. Эти
коды - константы вида 'ccXxx = n', где сс - признак того, что
данная константа - код команды, 'Xxx' - имя команды, 'n'    -
значение кода. Полный список кодов команд приведен в этом ра-
зделе ниже, с краткими комментариями.
  Некоторые из кодов команд используются широко.   Например,
сcQuit означает и "Закончить обработку", и, возможно, " Игно-
pировать изменения". Обычно она соответствует клавише  <Esc>.
сcLeft,ccRight,ccUp,ccDown обозначают "Перемещение курсора  в
нужном направлении", и обычно им соответствуют клавиши <Left>,
<Right>,<Up>,<Down>. Эти команды  имеют  самое  разнообразное
применение : в меню, списках, строковых и текстовых  редакто-
pах и т.д. Остальные команды, приведенные ниже,  используются
для одной-двух целей. Например, ccBlkToggle ("Переключить эк-
pан на помеченный блок"), используется при просмотре   файлов
(OPBROWSE) и в текстовых редакторах (OPEDITOR).
  Но самая многочисленная группа кодов команд - это так  на-
зываемые пользовательские команды выхода : ccUser0...ccUser54.
Использование набора этих команд   обеспечивает     множество
удобств в Object Professional, и одно  из  них -  специальное
переназначение клавиш для конкретной  программы.  К  примеру,
пусть вы хотите использовать <Ctrl F2>, чтобы "Сохранить  все
и выйти из программы", когда пользователь находится в  основ-
ном меню. Стандартной команды такого назначения нет,  поэтому
вам надо изменить таблицу соответствий так, чтобы   <Ctrl F2>
соответствовала одной из пользовательских команд, что  позво-
лит вам по нажатию данной комбинации клавиш выполнить  нужное
действие. Как изменить таблицу? Об этом мы расскажем в разде-
ле 2, рассматривая объект CommandProcessor.

       Объявления

   ccNone              = 000; {Неверная команда}
   ccChar              = 001; {Обычный символ}
   ссСtrlChar          = 002; {Управляющий символ}
   ссSelect            = 003; {Выбрать/принять элемент данных,
                               поле, и т.д.}
   ccQuit              = 004; {Выход без сохранения изменений}
   ccError             = 005; {Выход по фатальной ошибке}
   ccMouseSel          = 006; {Выбор мышью элемента, поля и т.д.}
   ccRestore           = 007; {Восстановить значение по умолча-
                               нию и продолжать}
   ccHome              = 008; {Курсор на начало строки/листа}
   ccEnd               = 009; {Курсор на конец строки/листа}
   ccLeft              = 010; {Курсор влево на один символ/
                               /колонку}
   ccRight             = 011; {Курсор вправо на один символ/
                               /колонку}
   ccUp                = 012; {Вверх}
   ccDown              = 013; {Вниз}
   ccScrollUp          = 014; {Cкроллинг окна вверх}
   ccScrollDn          = 015; {Cкроллинг окна вниз}
   ccWordLeft          = 016; {Курсор влево на одно слово}
   ccWordRight         = 017; {Курсор вправо на одно слово}
   ccPageUp            = 018; {Вверх на страницу}
   ccPageDn            = 019; {Вниз на страницу}
   ccScreenTop         = 020; {Верх экрана}
   ccScreenBot         = 021; {Низ экрана}
   ccTopOfFile         = 022; {Начало файла}
   ccEndOfFile         = 023; {Конец файла}
   ccBack              = 024; {Один символ BackSpace}
   ссDel               = 025; {Стереть текущий символ}
   ccDelEol            = 026; {Стереть от позиции курсора до
                               конца строки}
   ccDelBot            = 027; {Стереть от начала строки до
                               курсора}
   ccDelLine           = 028; {Cтереть строку}
   ccDelWord           = 029; {Стереть слово справа от курсора}
   ccIns               = 030; {Переключиться на режим вставки}
   ccHelp              = 031; {Вызов справочной программы}
   ccTab               = 032; {Сдвиг курсора по табуляции}
   ссBackTab           = 033; {Сдвиг курсора назад по табуляции}
   {Специальные команды OPMEMO/OPEDITOR}
   ccIndent            = 034; {Переключение на режим смещения}
   ccWordWrap          = 035; {Переключение на режим автомати-
                               ческого перехода на новую строку}
   ccReformatP         = 036; {Переформатировать параграф}
   ccReformatG         = 037; {Общее переформатирование}
   {Специальные команды OPSELECT/OPENTRY}
   ccIncChoice         = 038; {Выбрать приращение}
   ccDecChoice         = 039; {Выбрать отрицательное приращение}
   ccNextField         = 040; {Курсор на следующее поле}
   ccPrevField         = 041; {Курсор на предыдущее поле}
   ccNextRec           = 042; {Cледующая запись (команда выхода)}
   ccPrevRec           = 043; {Предыдущая запись (команда выхода)}
   ccFirstFld          = 044; {Курсор на первое поле}
   ccLastFld           = 045; {Курсор на последнее поле}
   ccNested            = 046; {Внутренний выход}
   ccDone              = 047; {Завершение редактирования}
   {Специальные команды для внутреннего пользования, не могут
    быть переназначены}
   ссСlickExit         = 048; {Нажатие и отпуск кнопки мыши для
                               выхода}
   ccAutoAdvance       = 049; {Автоматический переход на сле-
                               дующее поле}
   ccExitAtTop         = 050; {Переход на верхний край окна}
   ссExitAtBot         = 051; {Переход на нижний край окна}
   ссExitLeft          = 052; {Переход на левый край окна}
   ccExitRight         = 053; {Переход на правый край окна}
   {Специальные команды для OPHELP}
   ccPrevTopic         = 055; {Высветить основную справочную
                               информацию}
   ccIndex             = 056; {Высветить список всех справочных
                               разделов}
   ccNextXref          = 057; {Переход на следующую ссылку}
   ccPrevXref          = 058; {Переход на предыдущую ссылку}
   {Специальные команды OPBROWSE/OPEDITOR}
   ccSetMark0          = 060; {Установка текстовых маркеров 0..9}
   {ccSetMark1..ccSetMark8}
   ccSetMark9          = 069;
   ccJmpMark0          = 070; {Переход на текстовые маркеры 0..9}
   {ccJmpMark1..ccJmpMark8}
   ccJmpMark9          = 079;
   ccMarkToggle        = 080; {Переключиться на высвечивание
                               маркера текста}
   ccBlkBegin          = 081; {Пометить начало блока}
   ccBlkEnd            = 082; {Пометить конец блока}
   ccBlkBotton         = 083; {Пометить конец блока (внизу
                               просматриваемого окна)}
   ccBlkToggle         = 084; {Переключиться на высвечивание
                               блока}
   ccBlkRead           = 085; {Считать блок}
   ccBlkWrite          = 086; {Записать блок}
   ccBlkCopy           = 087; {Скопировать блок}
   ccBlkMove           = 088; {Переместить блок}
   ccBlkDelete         = 089; {Стереть блок}
   ccBlkWord           = 090; {Пометить данное слово в блоке}
   ccBlkUCase          = 091; {Изменить символы блока на
                               символы верхнего регистра}
   ccBlkLCase          = 092; {Изменить символы блока на
                               символы нижнего регистра}
   ccBlkTCase          = 093; {Переключить регистр для
                               символов блока}
   ccBlkIndent         = 094; {Перенести помеченный блок на
                               один уровень вправо}
   ссBlkUnindent       = 095; {Перенести помеченный блок на
                               один уровень влево}
   ссSetIndent         = 096; {Установка размера уровня пере-
                               носа блока для indent/unindent}
   ccPrevPos           = 097; {Курсор на предыдущую позицию в
                               файле}
   ccJmpBegin          = 098; {Переход на начало помеченного
                               блока}
   ccJmpEnd            = 099; {Переход на конец помеченного
                               блока}
   ccJmpLine           = 100; {Переход на строку}
   ccInsertLine        = 101; {Вставить строку на место курсора}
   ccCenterLine        = 102; {Центр текущей строки}
   ccSearch            = 103; {Поиск}
   ccReplace           = 104; {Поиск и перемещение}
   ccReSearch          = 105; {Повторный поиск}
   ccHexMode           = 106; {Включить шестнадцатиричный режим}
   ccTabExpand         = 107; {Включить расширение табуляции}
   ccTabToggle         = 108; {Переключение расширенная табу-
                               ляция/фиксированная табуляция}
   ccTabSize           = 109; {Установка размера фиксированной
                               табуляции}
   ccRtMargin          = 110; {Установка правой границы}
   ccStripHigh         = 111; {Включение очистки старших битов}
   ccNewFile           = 112; {Считать новый файл}
   ccSaveFile          = 113; {Сохранить файл}
   ccSaveNamed         = 114; {Сохранить файл под новым именем}
   ccSaveExit          = 115; {Выход с сохранением файла}
   ccSaveSwitch        = 116; {Сохранить файл и загрузить новый}
   ccAbandonFile       = 117; {Оставить файл}
   ccBlkPrint          = 118; {Распечатать помеченный блок}
   {Специальные команды выбора данных OPPICK}
   ccToggle            = 119; {Включить выбор данных}
   {Специальные команды выбора подменю OPMENU}
   ccSubPrev           = 120; {Переход в предыдущее подменю}
   ccSubNext           = 121; {Переход в следующее подменю}
   ccSubQuit           = 122; {Покинуть текущее подменю}
   {Команды перемещения курсора по диагонали}
   ccUpLeft            = 130; {Курсор вверх и налево}
   ccDownLeft          = 131; {Курсор вниз и налево}
   ccUpRight           = 132; {Курсор вверх и направо}
   ccDownRight         = 133; {Курсор вниз и направо}
   {Команды выхода пользователя}
   ccUser0             = 200;
   {ccUser1..ccUser53}
   ccUser54            = 254;
   ccUser55            = 255; {Зарезервирована для внутреннего
                               использования}
   ccUser65535         = 65535;{Значения, большие ccUser55,
                                возможны только при исполь-
                                зовании кодов длиной в слово}

  Это - стандартные коды команд Object Professional.   Боль-
шинство команд первой группы (ccNone..ccBackTab) имеют широкое
применение. Команды остальных групп, кроме последней, исполь-
зуются специально в  одном-двух  объектах.  Последняя  группа,
пользовательские команды выхода, применяются во всех объектах.
Заметим, что не существует имен команд между User55 и User65535,
которая просто обозначает максимально возможный номер пользо-
вательской команды выхода.

           2.  Объект CommandProcessor

  Наиболее важное средство, предлагаемое модулем OPCMD - это
объект CommandProcessor, основная задача которого -   перевод
значений клавиш в коды команд. Пожалуй, лучший способ для уя-
снения, как работает объект - это рассмотреть простой пример,
типа следующего:

Program CommandProcessorExample;   {EXMDPRC.PAS}
uses
OPCRT,OPCMD;
const
Define a small KeySet of a few cursor commands}
KeySetId : string[14] = 'KeySet follows';
KeyMax = 30;
KeySet : array[0..KeyMax] of Byte = (
{length   keys       command type    key sequence}
3,       $00,$48,   ccUp,             {Up
3,       $00,$50,   ccDown,          {Down}
3,       $00,$4b,   ccLeft,          {Left}
3,       $00,$4d,   ccRight,         {Right}
2,       $1b,       ccQuit,          {Esc}
0,0,0,0,0,0,0,0,0,0,0,0,);      {-room for more commands}
var
Commands : CommandProcessor;
Cmd, Key : Word;
begin
{Make a small CommandProcessor}
Commands.Init(@KeySet,KeyMax);
{add a user exit command - <F1>}
Commands.AddCommand(ccUser0,1,$3800,0);
{check for error adding the command}
if Commands.GetLastError <>0 then
RingBell;
repeat
Cmd:=Commands.GetCommand(Key);
case Cmd of
ccChar : WriteLn('ccChar :<символ>,Char(Lo(Key)),<символ>);
ccUp   : WriteLn('ccUp');
ccDown : WriteLn('ccDown');
ccLeft : WriteLn('ccLeft');
ccRight: WriteLn('ccRight');
ccQuit : WriteLn('ccQuit');
ccUser0: WriteLn('ccUser0');
else WriteLn('ccNone');
end;
until (Cmd = ccQuit);
end.

  Отметим, что константа KeySet - типизованный массив  байт,
начинающийся с нулевого элемента. Эта таблица  содержит   все
назначения клавиш в программе. Как вы можете видеть, информа-
ция размещена в массиве, представляющем собой  последователь-
ность записей переменной длины, каждая из записей имеет   три
поля. Первое поле - это байт, показывающий  суммарную   длину
двух остальных полей. Во втором поле содержатся коды  клавиш.
В третьем - коды команд.
  Второе поле - переменной длины. В большинстве случаев одна
команда соответствует одной клавише (<Ctrl A> или <Home>) или
комбинации двух клавиш (<Ctrl Q>, <Ctrl D>),  и  коды  клавиш
занимают один - два байта. Управляющие символы требуют по од-
ному байту, в то время как клавиши с расширенными скан-кодами
(функциональные, управления курсором  и т. д)   занимают  два
байта : 0 + скан-код. Следовательно, размер поля кодов клавиш
обычно будет в диапазоне от 1 (один управляющий символ) до  4
(две клавиши с расширенными скан-кодами, к примеру,   <Alt U>
<AltU>). Хотя можно назначать для команд комбинации   трех  и
более клавиш, это просто неудобно.
  В конце таблицы команд - последовательность нулей. Все они
кроме последнего, ничего не значат. Они   просто  резервируют
место для возможных добавлений новых команд.  Последний ноль,
однако, важен. При поиске в таблице команды,  соответствующей
нажатой клавише, просмотр строк продолжается до тех пор, пока
либо найдется нужная строка, либо будет обнаружен 0 на  месте
байта длины очередной строки. Следовательно, в конце  таблицы
всегда должен быть хотя бы один 0, он будет меткой конца таб-
лицы.
  Теперь - о самом объекте CommandProcessor. Сommands иници-
ализируется вызовом конструктора Init (работающего без сбоев)
с параметрами : адресом таблицы команд и величиной этой  таб-
лицы. Отметим, что второй параметр содержит не собственно ра-
змер таблицы, а номер ее  последнего   элемента.   Это важно.
СommandProcessor всегда предполагает, что если таблица  явля-
ется 'array[0..n] of Byte', то второй параметр а Init   будет
pавен n.
  Еще одна информация, которая не видна явно. Init активизи-
pует группу указателей процедур, хранящихся в  CommandProces-
sor, наиболее важная из которых - GetKeyProc.   Эта   функция
возвращает нажатую пользователем определенную клавишу. О  ней
мы поговорим позже. Что здесь важно отметить, это   то,   что
СommandProcessor caм приспособлен к получению нажатий клавиш.
Вы не просите его 'перевести нажатие клавиши в команду',   вы
просите 'принять определенную команду'.
  Вызов АddCommand позволит добавить новое назначение клави-
ши, например <F1> для пользовательской команды выхода ccUser0.
Чтобы убедиться, что добавление прошло успешно, можно вызвать
GetLastError. Если GetLastError возвратит ненулевое значение,
pаздастся звуковой сигнал, сообщающий об ошибке.
  Цикл Repeat - Until показывает, как можно получать команды
от пользователя посредством CommandProcessor. Результат, воз-
вращаемый в GetCommand, - это введенная команда, а   параметр
Кey содержит последнюю нажатую клавишу. Заметим, что если бу-
дет нажата обычная клавиша, то есть введен алфавитно-цифровой,
графический символ или разделитель, которым не поставлено   в
соответствие никаких команд, то GetCommand возвратит значение
'ccChar'. Это обстоятельство позволит, к примеру, строковым и
текстовым редакторам отличить команду редактирования от обыч-
ного текста. Если же введен управляющий символ, нажата клави-
ша управления курсором или функциональная - то в случае отсутс-
твия для них соответствующей команды будет возвращено 'ccNone'.
(Для управляющих символов #0..#31 будет возвращен ccChar, если
опция cpCtrlAltChars будет включена).

               Команды длиной в слово

  Если вернуться к формату таблицы команд, можно   заметить,
что коды команд являются однобайтовыми, позволяя вам  исполь-
зовать 256 команд. В большинстве этого с лихвой хватает.   Но
иногда, например в сложном программном редакторе или  системе
подготовки текстов этого мало. В таком случае вы должны снять
это ограничение. Для этого нужно сделать две вещи.
Во-первых, вам надо активизировать опцию WordCmds,  например,
так :
Сommands.cpOptionsOn(cpWordCmds);
Во-вторых, вам нужно изменить таблицу (таблицы)  соответствий
так, чтобы коды команд являлись словами, а не байтами. К при-
меру, мы меняем таблицу соответствий в следующей демонстраци-
онной программе:

сonst
КeyMax = 35;
КeySet = array[0..KeyMax] of Byte = (
 {length    keys      command   type   key sequence}
 4,         $00,$48,  ccUp,     0,     {Up}
 4,         $00,$50,  ccDown,   0,     {Down}
 4,         $00,$4b,  ccLeft,   0,     {Left}
 4,         $00,$4d,  ccRight,  0,     {Right}
 3,         $1b,      ccQuit,   0,     {Esc}
 0,0,0,0,0,0,0,0,0,0,0,0);      {room for more commands}

  Здесь мы сделали три вещи. Во-первых, мы увеличили  КеyMax
с 30 до 35. Во-вторых, мы добавили по единице к каждому байту,
показывающему длину полей. И в-третьих, мы добавили по  нулю
в конец каждой из записей, потому что каждый из  пяти   кодов
команд имеет значение, <= 255. Если бы мы имели код  команды,
больший 255, к примеру, 'ccSpecialCmd=300',   соответствующая
запись имела бы вид :
  3,    $0d,   Lo(ccSpecialCmd),Hi(ccSpecialCmd),   {Enter}
  Важно помнить, что младший байт кода команды приходит пер-
вым, а старший - вторым; и нужно изменять байты длины записей
если вы решили использовать коды команд длиной в слово.

                 Поддержка мыши

  Одна важная особенность CommandProcessor, не нашедшая отра-
жения в примере выше, - это поддержка мыши. Все экранно-ориен-
тированные объекты высокого уровня в Object Professional под-
держивают мышь, и эта поддержка начинается с объекта Command-
Рrocessor.
  Как уже объяснялось в описании OPMOUSE, основные программы
чтения с кнопок мыши (ReadKeyMouse и ReadKeyOrButton) возвра-
щают псевдо-скан-коды, значения длиной в слово, подобные рас-
ширенным скан-кодам. Вместе с другими,   это   обстоятельство
обеспечивает возможность для CommandProcessor   рассматривать
нажатие кнопок  мыши как обычное нажатие клавиш. Итак, первое
что вы должны сделать для поддержки мыши - это добавить  коды
кнопок мыши в таблицу команд вашего CommandProcessor. К  при-
меру, выражение
  Command.AddCommand(ccQuit,1,MouseRt,0);
сделает нажатие правой кнопки мыши эквивалентным нажатию кла-
виши Esc. Второе, что вам следует сделать, -   это   сообщить
объекту CommandProcessor, что необходима поддержка мыши :
  Command.cpOptionsOn(cpEnableMouse);
Активизация опции cpEnableMouse означает три вещи : 1) Разре-
шение внутреннего контроля событий в модуле OPMOUSE, 2) Уста-
новка указателя GetKeyProc на KeyOrButtonPressed, а   не   на
ReadKeyWord. После этого CommandProcessor может считывать   с
кнопок мыши так же успешно, как и с клавиатуры. Конечно,  для
поддержки мыши вашей программой нужно сделать и другие вещи:
выбрать и высветить курсор мыши, прятать  и   восстанавливать
его при записи текста на экран, - но лично объекту   Command-
Рrocessor для работы с мышью ничего больше не нужно.

            О фоновых заданиях

  Выше мы упоминали о 'GetKeyProc' и 'КеуPressedProc'. Это -
указатели процедур, хранящиеся в CommandProcessor и  сообщаю-
щие ему, какие программы должны быть вызваны  для   получения
информации от клавиш/кнопок или ее обработки. Обычно они ука-
зывают на ReadKeyWord и KeyPressed, если мышь не поддерживает-
ся, и на ReadKeyOrButton и KeyOrButtonPressed, если поддержи-
вается. Однако вы можете переустановить эти указатели на ваши
собственные программы, как показано ниже:

{F+}
function MyKeyPressed : Boolean;
begin
if KeyOrButtonPressed then
MyKeyPressed:=True
else begin
inline ($cd/$28);   {allow TSRs to pop up}
{** perform background task here **}
MyKeyPressed:=KeyOrButtonPressed;
end;
end;

function MyReadKey : Word;
begin
while not MyKeyPressed do  {wait};
MyReadKey:=ReadKeyOrButton;
end;
{F-}
...
Commands.cpOptions(cpEnableMouse);
Commands.SetGetKeyProc(MyReadKey);
Commands.SetKeyPressedProc(MyKeyPressed);

  Цель этой программы - занять время ожидания ввода с клави-
атуры или мыши чем-нибудь полезным, например, показом текуще-
го времени на экране. Выглядит это просто, это и в самом деле
просто, но необходимо учесть несколько моментов.
первое. GetKeyProc и KeyPressedProc должны иметь тот же  вид,
что и в примере выше. Они должны быть описаны как Far, с  ис-
пользованием директивы {F+}, они не должны помещаться  внутри
других процедур, и они должны возвращать результаты определен-
ного типа.
Второе. Для выполнения любого фонового задания  должна   быть
произведена хотя бы одна проверка нажатия клавиши или  кнопки
мыши. Это нужно, чтобы избежать ненужной задержки реакции  на
ввод с клавиатуры или мыши.
Третье. Оператор 'inline ($cd/$28)' иногда нужен  для   того,
чтобы позволить перекрытие TSR во время ожидания  ввода.   Он
формирует прерывание $28, которое является сигналом для  TSR,
что можно производить перекрытие. Мы рекомендуем вам включать
этот оператор всегда в вашу KeyPressedProc (если она  у   вас
есть), или в вашу GetKeyProc (если нет); не забудьте об этом,
pаботая с TSR.
Hаконец, помните, что поддержка мыши доступна, пока не переус-
тановлены указатели двух процедур. Это важно, так как  'cpOp-
tionsOn(cpEnableMouse)' также переустанавливает оба указателя
поэтому если этот оператор будет идти после вызовов SetGetKey-
Proc и SetKeyPressedProc, он "испортит" их работу.

                Внутреннее справочное средство


  Еще одно средство, поддерживаемое CommandProcessor, -  это
внутренняя справочная информация. Она состоит просто из  ука-
зателя процедуры, называющейся GetHelpProc, которая вызывает-
ся всякий раз, когда пользователь задает команду ccHelp. Ког-
да команда дана, процедура или объект, использующий  Command-
Рrocessor, вызывают правило cpGetHelp с параметрами,  опреде-
ляющими характер запроса. Если определена  GetHelpProc,   эти
параметры посылаются прямо в нее, не изменяясь в  CommandPro-
сessor.
Простой пример GetHelpProc показан ниже. Помните,   что   она
должна объявляться как Far, с использованием директивы  {$F+}
и не может быть помещена внутрь другой процедуры.

{$F+}
procedure MyGetHelpProc (UnitCode:Byte;IdPtr:Pointer;
                         HelpIndex:Word);
begin
{** display help **}
end;
{$F-}
...
Commands.SethelpProc(MyGetHelpProc);

Первый параметр - это "код модуля",  значение,   показывающее
источник запроса. Например, если запрос о справке был дан при
нахождении внутри меню, код модуля будет 'ucMenu'. Полный пе-
pечень стандартных кодов модулей вы можете найти в документа-
ции OPROOT. Второй параметр - обычно (но не всегда) указатель
объекта, использующего CommandProcessor. Третий параметр пока-
зывает более точно, где в программе находится пользователь на
момент посылки запроса. При работе с полями данных, например,
параметр определит поле экрана, при работе с меню или списка-
ми - экран, который в данный момент подсвечен.
   Значения двух последних параметров очень зависят от источ-
ника запроса. Чтобы определить, что же будет там  содержаться
в вашем конкретном случае, обратитесь к документации по   ис-
пользованию CommandProcessor в объектах и программах.
Более подробный пример GetHelpProc, написанный с  использова-
нием модуля OPHELP вы можете найти в ENTRY.PAS

              Дополнительные таблицы команд

  В большинстве случаев одной таблицы команд достаточно  для
любого объекта или программы, использующей данный CommandPro-
сessor. Но иногда желательно иметь вторую таблицу команд, со-
держащую набор стандартных пользовательских  команд   выхода,
или же "горячих клавиш". Яркий пример - демонстрационная про-
грамма DeskPop, где каждое из основных рабочих  окон   должно
"уметь" в ответ на запрос об изменении окна : перемещать, ра-
зличать, менять размеры окна, вызывать внутренние или  основ-
ное меню и т.д. Хотя для каждого окна можно завести свою таб-
лицу команд, будет намного эффективней добавить одну таблицу,
содержащую назначения всех "горячих клавиш",    и   заставить
СommandProcessor просматривать обе таблицы при нажатии клави-
ши. Таким образом, CommamdProcessor обеспечивает работу  пра-
вила SetSecondaryKeyPtr, которое позволяет вам определить до-
полнительную таблицу команд, и опции cpSwitchPriority,   поз-
воляющей вам установить порядок просмотра таблиц. Если  вклю-
чена опция cpSwitchPriority, то дополнительная таблица команд
просматривается первой, а основная - затем. Если две  таблицы
не конфликтуют между собой, то эта опция оказывается ненужной.
Она необходима в случаях, если одна и та же клавиша (или ком-
бинация клавиш) имеет в двух таблицах различные   назначения.
В качестве примера использования дополнительной таблицы   ко-
манд смотрите TPUI.PAS и TPUI.ICD.

               Автовыполнение команд

  Еще одно удобное средство CommandProcessor - это   правило
SetCommandList, которое позволяет вам определить список   ко-
манд, выполняемых автоматически. Обычно это список   является
массивом байт (если используются коды команд длиной в  байт )
или слов (если коды команд - длиной в слово).  SetCommandList
не интересуется, какая структура данных используется на самом
деле, главное, что она воспринимается как массив   байт   или
слов. Приведем пример, который может быть использован при про-
смотре файлов с помощью OPBROWSE :

type
CmdRec = record
         Cmd1, Cmd2, Cmd3 : Byte;
         end;
const
 CmdList1 : array[1..3] of Byte = (ccTopOfFile,ccHexMode,
                                   ccQuit);
 CmdList2 : CmdRec = (
                 Cmd1 : ccTopOfFile;
                 Cmd2 : ccHexMode;
                 Cmd3 : ccQuit);
...
BrowseCommands.SetCommandsList(@CmdList1,3);
BrowseCommands.SetCommandsList(@CmdList2,3);

  В данном случае первая команда перемещает курсор в  начало
просматриваемого файла, вторая - включает/выключает  шестнад-
цатиричный режим, третья - передает управление вызывающей про-
грамме. Список команд может содержать и обычный текст,  отде-
ленный командами ccChar, что позволяет автоматически ответить
на введенный пользователем запрос. Это средство можно исполь-
зовать, например, при задании для TextEditor или Browser :
найти определенную строку. Общий формат команд будет следую-
щим :
 command, command,...ccChar,--text--,ccChar, command, command

  Как это работает? Как только TextEditor или Browser  вызы-
вают программу, написанную пользователем, для поиска  нужного
символа или строки, они вызывают также и правило CommandString-
Рending объекта CommandProcessor, чтобы посмотреть, не являет-
ся ли данная команда в списке автоматически выполняемых коман-
дой ccChar. Если да, то будет вызван GetCommandString, который
найдет строку (' --text--'),  ограниченную   двумя   командами
сcChar.
   Заметим, что объект CommandWindow, описанный в   OPWINDOW,
упрощает процесс использования этого средства. Для  получения
подробностей смотрите описание правила ProcassAutoPilot.
   Примеры авто-выполнений команд можно найти в исходном тек-
сте демонстрационной программы DESKPOP. DESKPOP  широко   ис-
пользует это средство, чтобы позволить различным командам ра-
ботать внутри локальных меню.

                 Cредство  UserProc

  Еще одно специальное средство CommandProcessor, о  котором
здесь стоит упомянуть, это правило SetUserHookProc. Это сред-
ство позволит вам определить программу, которая будет вызыва-
ться всякий раз, когда правило GetCommand будет  распознавать
нажатие клавиши пользователем. Хотя есть   много   приложений
этого средства, наиболее часто оно используется  для   выдачи
сообщений о нажатии первой клавиши пары клавиш. Например:

{$F+}
procedure MyUserHook(CPP:CommandProcessorPtr;Mt:MatchType;
                    Key:Word);
 var
 s : sting[2];
 begin
 s:=' ';
 if Mt = PartMatch then
 if Lo(Key) < Ord(' ') then begin
 s[1]:='^';
 s[2]:=Char(Lo(Key)+$40);
 end
 else
 s[1]:='+';
 FastWrite(s,1,1,$07);
 end;
 {$F-}
 ...
 Commands.SetUserHookProc(MyUserHook);

  Такая программа часто используется, когда много команд со-
ответствует комбинациям клавиш   редактора   WordStar,   типа
<CtrlK><CtrlD> и <CtrlQ><CtrlF>. Если   пользователь   нажмет
<CtrlK>, например, то в углу экрана появится '^K', чтобы  на-
помнить пользователю, что нажата первая клавиша пары.  Другой
пример использования этого  средства   можно   посмотреть   в
ЕDITOR.PAS

               Константы

  BadCmdOptions : Word = cpDoingChars+cpDeallocP+cpDeallocS;

Это - опции для внутреннего использования. Они не могут  быть
изменены вызовом cpOptionsOn или cpOptionsOff.

  cpMapWordStar       = $0001; {Wordstar мapping on?}
  cpEnableMouse       = $0002; {Mouse support enabled?}
  cpUpcase            = $0004; {Convert keys to uppercase
                                before evaluating?}
  cpWordCmds         = $0008; {If set, commands are words
                                rather then bytes}
  cpSwitchPriority   = $0010; {Give secondary commands
                                priority when searching}
  cpCtrlAreChars     = $0020; {Treat unassigned control
                               chars as regular chars}
  cpDoingChars       = $2000; {For internal use}
  cpDeallocP         = $4000; {For internal use}
  cpDeallocS         = $8000; {For internal use}

  Это - опции объекта CommandProcessor, которые могут   быть
включены/выключены с помощью cpOptionsOn и cpOptionsOff.  Оп-
ция cpMapWordStar показывает, что CommandProcessor будет вос-
принимать   комбинации    клавиш    типа    <CtrlK><D>    как
<CtrlK><CtrlD>. cpEnableMouse используется для установки/сня-
тия поддержки мыши. cpUpcase показывает, что  все   буквенные
клавиши, нажатые пользователем, будут переведены  в   верхний
pегистр до начала просмотра таблицы команд; эта опция   часто
используется, когда есть команды, cоответствующие   буквенным
клавишам, например <A>. cpWordCmds показывает, что команды во
всех таблицах имеют коды длиной в слово,   а   не   в   байт.
сpSwitchPriority показывает, что дополнительная таблица   ко-
манд будет просматриваться раньше  основной.   сpCtrlAreChars
показывает, что все управляющие символы, которым не соответс-
твует никакая из команд, будут восприниматься   как   обычные
символы. Например, если пользователь нажимает <CtrlC>, и   на
<CtrlC> не назначено команды, то GetCommand вернет ccChar,  а
не ссNone. Остальные опции - для внутреннего использования.

  DefCmdOptions : Word = cpMapWordStar;

Опции CommandProcessor, задаваемые по умолчанию.

                    Типы

  Command Processor Ptr = ^ CommandProcessor;
  Command Processor =
      object (Root)
      ...
      end;

Объект, используемый для обработки команд, введенных  пользо-
вателем  с клавиатуры или мыши.

GetHelpProc = procedure (VnitCode: Byte; IdPtr: Pointer;
HelpIndex: Word);

Процедура, вызываемая, когда задается команда ccHelp. Смотри-
те     описание  "Внутреннее справочное средство", изложенное
выше.

GetKeyProc = function: Word;

Функция,  вызываемая  для  определения  нажатой пользователем
клавиши. Смотрите раздел "О фоновых заданиях" выше.

CmdTable = array[0..32000] of byte;
CmdTablePtr = ^CmdTable;

Абстрактное определение таблицы команд (массив байт,  начина-
ющийся с нулевого элемента) . Значение  32000   в   принципе,
необоснованное. Обычно CmdTable - переменной длины.

КeyPressedProc = function: Boolean;

Функция,  вызываемая для  определения, была ли нажата клавиша
пользователем. Смотрите раздел "О фоновых заданиях"

МatсhType = (NoMatch, PartMatch, FullMatch);

Используется для определения, соответствует ли (полностью или
частично) данный код клавиши какой-либо команде. Если нажатая
клавиша не  соответствует  никакой из  команд, то MatchType =
NoMatch, PartMatch означает частичное соответствие, например,
если нажата <CtrlK>, а одной из команд соответствует комбина-
ция <CtrlK><CtrlQ>.   FullMatch  означает  полное соответствие
нажатой клавиши (группы клавиш) какой-либо команде.

UserHookProc = procedure (CPP: CommandProcessorPtr;
                              MT:MatchType;Key:Word);

Процедура, вызываемая сразу после того, как было зафиксирова-
но  нажатие клавиши. СРР - это указатель на текущий командный
процессор. МТ показывает, не соответствует ли нажатая клавиша
какой-либо команде. Key - это клавиша, нажатая пользователем.

                 Процедуры и функции

Процедура AddCommand (Cmd:Wprd; NumKeys:Byte; Key1, Key2: Word);

Hазначение

Добавляет новую команду или меняет существующую

Описание

Это правило позволяет вам делать три вида изменений в   соот-
ветствиях  команд  и  клавиш  в  CommandProcessor;  вы можете
определить новые   команды (пользовательские команды выхода),
отменить назначение  клавиши,  изменить  назначение  клавиши.
Предположим, что мы используем OPEDIT и хотим,   чтобы   <F2>
сообщала о том, что пользователь хочет посмотреть список. Что
вы должны сделать, чтобы OPEDIT передал вам управление, когда
будет  нажата <F2>:
{assign CсUserO to <F2>}
EditCommands.AddCommand (cc UserO, 1, $3C00, 0);
if EditCommands.GetLastError <> O then
writeln ('Failed to add command');
Первый параметр - это код команды: здесь мы используем первый
из 55  зарезервированных  кодов  для  пользовательских команд
выхода. Второй  параметр показывает, соответствует ли команда
одной клавише    (например, <F2>), или паре клавиш (например,
<CtrlQ><D>). Третий  и  четвертый  параметры  содержат   коды
клавиш. В нашем случае, когда   команда задается одной клави-
шей, параметр Key2 будет игнорироваться.   Но если мы захотим
добавить команду типа WordStar, соответствующую  двум  клави-
шам, скажем, <CtrlQ><D>, мы должны   ввести   'Ord(^Q)'(Key1)
и 'Ord('D)'(Key2). Заметим, что вы должны набрать  'Ord(^D)',
а не 'Ord(D)': OPEDIT  тогда  воспримет одинаково как нажатие
<D>, так  и <CtrlD> после  <CtrlQ>, как это делает WordStar и
остальные редакторы фирмы Borland. (Здесь предполагается, что
включена  опция cpMapWordStar,  как это и есть по умолчанию).
Вызов GetLastError используется  для  проверки,  успешно   ли
прошла   операция добавления команды. Список возможных ошибок
можно посмотреть в описании GetLastError.
Теперь допустим, что мы хотим  отменить нашу пользовательскую
команду выхода. Для этого нужно переназначить клавишу <F2> на
пустую команду ссNone:

{assign <F2> to the null command}
ЕditCommands.AddCommand (None,1,$3C00,0);

Кроме  отмены  команды,  при  этом  произойдет и освобождение
места для возможного добавления новых команд.
Hаконец,  допустим,  что  мы  хотим   изменить   существующее
назначение  клавиш.  Например,  мы  хотим,  чтобы  <CtrlHome>
выполняла те же  действия, что и <Home>, а <CtrlEnd> - те же,
что и <End>:

{assign <CtrlHome> to ccHome}
ЕditCommands.AddCommand (ccHome,1,$7700,$0000);
ЕditCommands.AddCommand (ccEnd,1,$7500,$0000);

Когда  AddCommand  будет  просматривать  таблицу  команд, она
увидит, что  <CtrlHome> уже назначена на команду ccDelBol,  и
просто изменит ее назначение на ccHome. Аналогично, <CtrlEnd>
будет   назначена на команду ccEnd, а не на ccDelEol. В обоих
случаях   размер  места  для  добавления  новых   команд   не
изменится.

Смотрите также

АddSecondaryCommand                GetLastError

-------------------------------------------------------------
Процедура AddSecondaryCommand (Cmd:Word; Numkeys: Byte;
                              Key1,Key2: Word);

Hазначение

Добавляет команду в дополнительную таблицу, или изменяет уже
существующую

Описание

Это правило идентично правилу AddCommand, только оно изменяет
не основную, а дополнительную таблицу команд.

Примеры

Сommands.AddSecondaryCommand(ccUser 0,1,$4400,0);
if Commands.GetLastError <>0 then
writeln ('Failed to add comand');

Hазначает команде ccUserO клавишу <F10>, которая перед   этим
не была задействована.

Сommands.AddSecondaryCommand(ccNone,2,Ord(^Q),Ord(^I));

Отменяет назначение команды ccUser2 на клавишу <Home>.

Смотрите также

АddCommand

----------------------------------------------------------------
Функция CheckForConFliсt (NumKeys: Byte;
                         Key1,Key2: Word):MatchType;

Назначение

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

Описание

Это правило можно использовать для определения, не конфликту-
ет ли  нажатая комбинация клавиш с уже назначенной комбинацией
с основной или дополнительной таблице команд. Результат будет
NoMatch, если задействована часть клавиш данной   комбинации,
например, если   вы нажали <CtrlK><CtrlQ>, а в таблице команд
задействована <CtrlK>. Три параметра - те же, что и последние
три параметра процедуры AddCommand : NumKeys определяет число
клавиш в комбинации, Key1 - первая клавиша комбинации, а Key2
- вторая (если NumKeys=2).

Пример

if Commands.CheckForConflicts (1,$3B00,0)<>NoMatch then
writeln ('<F1> Key already assigned')
else
Commands.AddCommand (ccUserO, 1, $3B00,0);

Назначает команде ccUserO клавишу <F1>, если <F1> еще не
задействована другой командой

Смотрите также

AddCommand
---------------------------------------------------------------------
Функция CommandStringPending: Boolean;

Назначение

Возвращает True, если строка текста является элементом списка
команд, выполняющихся автоматически.

Описание

Эта функция предназначена для использования в объектах   типа
текстовых редакторов, которые должны иметь строки текста, со-
держащиеся  в списке авто-выполняемых команд. Смотрите раздел
"Автовыполнение команд" выше,   там   изложены   подробности
использования этого правила.

Пример

Сonst
CmdList : array[1..8] of Byte = (
  ccDown,ccUp,ccUser0,ccChar,Byte('A'),Byte('B'),Byte('C'),
  ccChar);
var
Commands : CommandProcessor;
Cmd,Key : Word;
begin
{...initialize commands...}
{point to command list}
Commands.SetCommandList(@CmdList,8);
repeat
{Get a command of command steing}
if Commands.CommandStringPending then
WriteLn (Commands.GetCommandString)
else begin
Cmd := Commands.GetCommand(Key);
case Cmd of
ccUp    : WriteLn('ccUp');
ccDown  : WriteLn('ccDown');
ccQuit  : WriteLn('ccQuit');
ccUser0 : WriteLn('ccUser0');
else      WriteLn('ccNone');
end;
end;
until Cmd = ccQuit;
Commands.Done;
end;

Проверяет, являются ли данные команды командами или  включен-
ными   в список  текстовыми строками. Команды выполняются;  а
строки  высвечиваются на экране

Смотрите также

SetCommandString           SetCommandList
--------------------------------------------------------------------
процедура cpGetHelp(UnitCode: Byte; IdPtr: Pointer;
                   HelpIndex: Word);    virtual;

Назначение

Вызывается, когда нужна справочная информация

Описание

Это правило вызывается другими объектами, когда  пользователь
даст   команду-запрос  справки  (ccHelp).   Если   определена
GetHelpProc (то  есть она вызвана),  то   GetHelpProc   будет
вызываться с теми же  параметрами, что и cpGetHelp, если Get-
HelpProc не определена, то cpGetHelp ничего не делает.

Смотрите также

GetHelpProc
--------------------------------------------------------------------
Функция cpGetKey: Word; virtual;

Назначение

Вызывается для получения нажатой клавиши

Описание

Это виртуальное правило вызывается из GetCommand, чтобы опре-
делить,  какую клавишу нажал пользователь, с помощью соответ-
ствующей GetKeyProc. cpGetKey может вызываться и  непосредст-
венно из других объектов, в   случаях, когда желательно знать
нажатую клавишу, а не команду.

Пример

writeln('Press any key to continue...');
Key:=Commands.cpGetKey;

Смотрите также

SetGetKeyProc
------------------------------------------------------------------
Функция cpKeyPressed: Booleаn; virtual;

Назначение

Вызывается, если нажата клавиша

Описание

Это виртуальное правило никогда не вызывается непосредственно
из объекта CommandProcessor, только из определенных  объектов
и программ, использующих  CommandProcessor.  Она   возвращает
True,  если соответствующая KeyPressedProc сообщает, что ожи-
дается  реакция на нажатие клавиши.

Пример

While not Commands.cpKeyPressed do
{do something white waiting for a key to be pressed};
Cmd: = Commands.GetCommand (Key));

Выполняет какую-то работу, пока не будет нажата клавиша.  Для
более интересного примера использования cpKeyPressed  посмот-
рите  OPMACED.PAS.

Смотрите также

GetKeyPressedProc
--------------------------------------------------------------------
Функция cpOptionsAreOn (OptionsFlags: Word): Boolean;

Назначение

Возвращает True, если включены определенные опции

Описание

Это правило возвращает True, если активизирована определенная
опция (опции)

Пример

if Commands.cpOptionsAreOn (cpSwitchPriorrty) then
write ('Secondary')
else
Write ('Primary');
writeln ('command table be searched first.');

Высвечивает состояние опции cpSwitch Priority.
--------------------------------------------------------------------
Процедура cpOptionsOff (OptionsFlags: Word);

Выключает определенные опции

Описание

Это правило выключает определенную опцию (опции), кроме  тех,
которые определены как BadCmdOptions (смотрите секцию  описа-
ний  выше). Помните,что если в OptionFlags  фигурирует  опция
UpEnableMouse,   то  GetKeyProc  для данного CommandProcessor
станет указывать на OpCrt.ReadKeyWord   и    KeyPressedProc
станут указывать на OpCrt.KeyPressed.

Пример

Commands.cpOptionsOff (cpSitehPriority + cpEnableMouse);

Выключает просмотр дополнительной таблицы команд перед основ-
ной, и выключает поддержку мыши
-------------------------------------------------------------------
Процедура cpOptionsOn (OptionsFlags: Word);

Назначение

Включает определенные опции

Описание

Это правило включает определенную опцию (опции), кроме опций,
определенных как BadCmdOptions (смотрите секцию описаний  вы-
ше). Заметим, что если в OptionFlags фигурирует опция cpEnab-
leMouse, то  GetKeyProc  для  данного CommandProcessor станет
оказывать на OpMouse. ReadKeyOrButtion и KeyPressedProc будут
оказывать на OpMouse.KeyOrButtionPressed.

Пример

Commands.cpOptionsOn (cpSwitch Priority + cp EnableMouse);

Включает опцию просмотра дополнительной таблицы команд раньше
чем основной, и включает поддержку мыши.
--------------------------------------------------------------------
Процедура cpUserHook (MT: MatchType; Key:Word); virtual;

Назначение

Вызывается всякий раз при обработке нажатия клавиши

Описание

Это правило, предназначенное в основном для внутреннего испо-
льзования,  вызывается всякий раз, когда GetCommand обрабаты-
вает  нажатие клавиши. Если UserHookProc определена с помощью
вызова  SetUserHookProc, то UserHookProc вызывается с теми же
параметрами, что и cpUserHook. Если же нет, то cpUserHook ни-
чего не делает

Смотрите также

SetUserHookProc

------------------------------------------------------------

Деструктор Done; virtual;

Назначение

Высвобождает память, которая была занята объектом
CommandProcessor

Описание

Этот деструктор перераспределяет память для таблиц    команд,
если это возможно. Его нужно вызывать только если CommandPro-
cessor был загружен из потока

Смотрите также

Store
------------------------------------------------------------

Функция GetCmdAssignment (NumKeys : byte; Key1,Key2 : Word;
                         var Primary : Boolean) : Word;

Назначение

Возвращает команду, соответствующую определенной  комбинации
клавиш

Описание

Это правило можно использовать для определения  соответствую-
щей определенной комбинации клавиш команды. Если такой коман-
ды нет, то функция возвращает 0 (ccNone).
Первые три параметра - те же, что и последние три   параметра
процедуры AddCommand : NumKeys - число клавиш в   комбинации,
Key1 - первая клавиша  комбинации,   Key2 -   вторая (   если
NumKeys = 2). Если результат отличен от ccNone, то  Primary =
True показывает, что найденная команда расположена в основной
таблице команд, а Primary = False - что в дополнительной.

Пример

Var
 Cmd : Word;
 Primary : Boolean;
 ...
 {What command is associated with <F1>?}
 Cmd:=Commands.GetCmdAssignment(1,$3800,0,Primary);
 if Cmd = ccNone then
 WriteLn('<F1> not used')
 else begin
 Write('<F1> returns','from');
 if Primary then
 WriteLn('Primary command processor');
 else
 WriteLn('Secondary command processor');
 end;

 Этот пример определяет команду,   соответствующую   клавише
 <F1>. Также устанавливается, в какой таблице (основной  или
 дополнительной) расположена эта команда

 Смотрите также

 AddCommand            GetKeyAssignment
 ----------------------------------------------------------

Функция GetCommand (var Key : Word) : Word;

Назначение

Принимает данную пользователем команду

Описание

Это правило вызывается для получения введенной  пользователем
команды. Если была нажата клавиша (клавиши),  соответствующая
какой-либо команде, то эта команда и будет возвращаться функ-
цией. Иначе, результатом ее работы будет либо  ccChar (  если
была нажата "обычная" клавиша (' '...'~',#128..#255)),   либо
ccNone(0). (ссСhar будет возвращен также, если нажаты  клави-
ши #0..#31 и включена опция cpCtrlAreChars).
Последняя из нажатых пользователем клавиш возвращается в  па-
раметре Key. Она обычно представляет интерес только в случае,
когда GetCommand возвращает ссChar.
Обычно GetCommand сначала просматривает основную таблицу  ко-
манд, затем - дополнительную таблицу, если она   есть.   Если
включена опция cpSwitchPriority, то сначала   просматривается
дополнительная таблица. Порядок просмотра таблиц важен в  тех
случаях, когда одна и та же комбинация клавиш  имеет   разные
назначения в разных таблицах. Другие опции, связанные с  Get-
Сommand : если включена опция cpUpcase, то GetCommand переве-
дет клавиши, нажатые пользователем, в верхний регистр   перед
просмотром таблиц команд. Если включена опция cpWordCmds,  то
GetCommand будет предполагать, что коды команд как в   основ-
ной, так и в дополнительной таблицах имеют длину слово, а  не
байт. Если включена опция cpMapWordStar, то обычные буквенные
клавиши будут считаться соответствующими им управляющими кла-
вишами, если предыдущая нажатая клавиша будет частично  соот-
ветствовать какой-либо команде.
При получении очередного нажатия клавиши GetCommand  вызывает
правило cpUserHook  с этой клавишей в качестве параметра, да-
вая тем самым UserHookProc возможность установить  соответст-
вие (частичное или полное) этой клавиши какой-либо команде.

Пример

Repeat
Cmd:=Commands.GetCommand(Key);
case Cmd of
...process the command...}
end;
until (Cmd = ccQuit) or (Cmd = ccError);

Выполняет команды, пока не будет нажат <Esc> или не  случится
ошибка

Смотрите также

UpUserHook
-------------------------------------------------------------

Функция GetCommandString : String;

Назначение

Возвращает строку, если CommandStringPending   установлен  в
True

Описание

Это правило должно вызываться, когда   CommandStringPending =
True; оно возвращает строку, содержащуюся в  списке   команд.
Смотрите раздел "Автовыполнение команд".

Пример

Смотрите пример для CommandStringPending

Смотрите также

CommandStringPending        SetCommandList
-------------------------------------------------------------

Процедура GetKeyAssignment(Cmd : Word; var NumKeys : Byte;
                          var Key1,Key2 : Word);

Назначение

Возвращает клавишу (клавиши), соответствующие данной команде.

Описание

Это правило просматривает основную и (если необходимо) допол-
нительную таблицу команд, отыскивая комбинацию клавиш,  соот-
ветствующую команде Cmd. Если такой команды нет, то   NumKeys
останавливается в 0. Иначе  NumKeys возвратит число клавиш  в
найденной комбинации (1 или 2), значения которых  разместятся
и Key1 и Key2.
Заметим, что основная таблица команд всегда   просматривается
первой, даже если опция cpSwitchPriority включена, и  возвра-
щается только первая из найденных комбинаций клавиш   (в  тех
случаях, когда одной команде соответствуют несколько комбинаций)

Пример

var
NumKeys : Byte;
Key1,Key2 : Word;
...
Commands.GetKeyAssignment(ccRight,NumKeys,Key1,Key2);
if NumKeys <>0 then begin
WriteLn ('ccRight is an active command');

Просматривает основную и дополнительную таблицу команд, ища
команду ccRight.

Смотрите также

GetCmdAssignment
------------------------------------------------------------

Функция GetKeyPtr (var MaxIndex : Word) : CmdTablePtr;

Назначение

Возвращает указатель основной таблицы команд.

Описание

Эта функция возвращает указатель основной   таблицы   команд.
MaxIndex - это номер последнего элемента таблицы команд.   То
есть, если таблица команд - 'array[1..n] of Byte', то    Max-
Index возвратит n.

Пример

var
SavePtr : Pointer;
SaveMax : Word;
...
SavePtr:=Command.GetKeyPtr(SaveMax);
...
Commands.SetKeyPtr(SavePtr,SaveMax);

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

Смотрите также

SetSecondaryKeyPtr           SetKeyPtr
------------------------------------------------------------

Функция GetLastError: Word;

Назначение

Возвращает код последней ошибки с комментариями

Описание

Это   правило  нужно   вызывать  после   выполнения  процедур
AddCommand или  AddSecondaryCommand для  проверки, успешно ли
добавилась новая команда в таблицу команд. Возможные значения:

    О                                 Успех
 epNonFatal+ecKeyTableFull         Таблица полна
 epNonFatal+ecPartialParam         Комбинация клавиш входит в
                                   в уже назначенную
 epNonFatal+ecBadParam             Параметр NumKeys не равен
                                   1 или 2

Вторая ошибка, ecPartialMatch, случится, если вы, например,
попытаетесь  назначить   команде  клавишу  <CtrlK>,  а  уже
существует  команда,   которой   назначена       комбинация
<CtrlK><CtrlQ>.

Пример

Commands.AddCommand (ccUserO,1,$3800,0);
if Commands.GetLastError <> o then
{unable to assign ccUserO command to <F1>};

Смотрите также

AddCommand
--------------------------------------------------------------------
Функция GetSecondaryKeyPtr (var MaxIndex: Word): Cmd TablePtr;

Назначение

Возвращает указатель дополнительной таблицы команд

Описание

Эта функция  возвращает  указатель  дополнительной  таблицы
команд, если она есть,  или nil, если ее нет. MaxIndex - это
номер последнего    элемента таблицы. То есть, если таблица
команд объявлена как     'array{1..n} of Byte', то MaxIndex
возвратит n.
Пример

var
SavePtr: Poiter;
SaveMax: Word;
...
SavePtr: = Commands.GetSecondaryKeyPtr (SaveMax);
...
Commands.SetSecondaryKeyPtr (SavePtr, SaveMax);

Сохраняет указатель и номер  последнего  элемента  дополни-
тельной таблицы  команд,  и затем восстанавливает их. Между
этими событиями,  возможно  используется   другая   таблица
команд.

Смотрите также

SetKeyPtr                    SetSecondaryKeyPtr
---------------------------------------------------------------------
Конструктор Init (KeysPtr: CmdTablePtr; MaxIndex: Word);

Назначение

Конструктор   инициализирует   "обычный"  CommandProcessor,
который имеет только одну, основную, таблицу команд. KeyPtr
указывает   на начало таблицы команд, а MaxIndex определяет
номер последнего  элемента таблицы. Заметим, что нет  необ-
ходимости рассматривать  Init как  логическую функцию, пос-
кольку он всегда работает без  сбоев.

Пример

Смотрите пример в описании InitCustom, ниже
---------------------------------------------------------------------
Конструктор InitCustom (PrimaryKeys: CmdTablePtr;
         PrimaryMaxIndex: Word; SecondaryKeys:CmdTablePtr;
         SecondaryMaxIndex: Word; Options: Word);

Назначение

Инициализирует командный процессор с настройкой опций

Описание

Этот конструктор инициализирует "специальный" CommandProces-
sor, имеющий две таблицы команд (основную и дополнительную),
или же требующий специальных опций.
PrimaryKeys указывает  на  начало  основной таблицы команд,
PrimaryMaxIndex  определяет  номер  ее последнего элемента.
SecondaryKeys  и  SecondaryMaxIndex  аналогично  определяют
дополнительную таблицу  команд. Если дополнительной таблицы
нет, то они равны соответственно  'nil,0'.  Options  -  это
опции объекта CommandProcessor, которые надо включить; если
никаких специальных  опций  вам не  требуется,  используйте
'DefCmdOptions'. Заметим, что нет необходимости  рассматри-
вать InitCustom как   логическую функцию, так как он всегда
работает без сбоев.

Пример

const
   {Define a small KeySet of a few cursor commands}
   KeyMax = 30;
   KeySet : array[o..KeyMax] of Byte = (
   { length    keys       command type      key sequence}
     3,        $00,$48,   ccUp,             {Up}
     3,        $00,$50,   ccDown,           {Down}
     3,        $00,$4b,   ccLeft,           {Left}
     3,        $00,$4d,   ccRight,          {Right}
     2,        $1b,       ccQuit,           {Esc}
     0,0,0,0,0,0,0,0,0,0,0,0);    {room for more commands}
     SecKeyMax = 15;
     SecKeySet : array[0..SecKeyMax] of Byte = (
     3,        $00,$47,   ccHome,           {Home}
     3,        $00,$4f,   ccEnd,            {End}
     2,        $1b,       ccQuit,           {Esc}
     0,0,0,0,0);                  {room for more commands}
     var Commands : CommandProcessor;
     ...
     Commands.InitCustom(@KeySet,KeyMax,    {Primary keys}
                   @SecKeySet,SecKeyMax   {Secondary keys}
                   DefCmdOptions);        {Options}

Создает CommandProcessor с основной и дополнительной табли-
цами  команд
------------------------------------------------------------------
Конструктор Load (var S: IdStream);

Назначение

Загружает командный процессор из потока

Описание

S- это надлежащим образом определенный поточный объект (на-
пример, поточный файл, открытый для чтения). Заметим, что S
может быть какой-либо разновидностью типа IdStream, который
включает в себя  DosIdStream, BufldStream и MemIsStream.
Load считывает заданную  последовательность  байт из потока
S. Эти  байты должны быть предварительно записаны с помощью
вызова CommandProcessor.Store.  Если   таблица    (таблицы)
команд объекта CommandProcessor      не зарегистрированы на
момент сохранения, и содержание  таблиц  команд  последова-
тельно хранится в потоке, Load выделит память под   таблицу
(таблицы) команд и загрузит их туда.
Если Load работает со сбоями,  конструктор возвратит значе-
ние  False и код ошибки, который будет храниться в глобаль-
ной переменной InitStatus.
Регистрирующая  процедура  для  объекта CommandProcessor, -
это CommandProcessorStream.

Пример

uses
OPCRT,OPROOT,OPCMD;
var
Commands : CommandProcessor;
Cmd,Key,Status : Word;
S : BufIdStream;
begin
S.Init('Command.STM',SOpen,1024);
S.RegisterHier(CommandProcessorStream);
S.Get(Commands);
Status:=S.GetStatus;
If Status<>0 then begin
WriteLn('Load error',Status);
Halt;
end;
S.Done;
repeat
Cmd:=Commands.GetCommand(Key);
case Cmd of
ccUp   : WriteLn('ccUp');
ccDown : WriteLn('ccDown');
ccLeft : WriteLn('ccLeft');
ccRight: WriteLn('ccRight');
ccQuit : WriteLn('ccQuit');
ccUser0: WriteLn('ccUser0);
else        WriteLn('ccNone');
end;
until Cmd = ccQuit;
Commands.Done;
end.

Загружает Commands из потока, созданного в примере описания
Store (Load  вызывается неявно операцией Get). Заметим, что
в этом примере  не  зарегистрирована  таблица  команд;  она
здесь не нужна.

Смотрите также

Store
----------------------------------------------------------------------
Функция MouseEnabled: Boolean;

Назначение

Возвращает True, если есть поддержка мыши

Описание

Эта функция возвращает True, если  объект  CommandProcessor
поддерживает работу с мышью. Результат ее идентичен резуль-
тату  выражения:
"cpOptionsAreOn (cpEnableMouse)".

Смотрите также

cpOptionsAreOn
------------------------------------------------------------------
Процедура SetCommandList (CmdList: Pointer; NumCmds: Word);

Назначение

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

Описание

Это правило позволяет вам определить список команд, которые
будут  выполняться автоматически. CmdList - указатель этого
списка; сам  же список будет либо массивом байт, либо (если
включена опция  cpWordCmds), массивом слов. NumCmds - число
команд в списке. Смотрите  описание "Автовыполнение команд"
в начале этой секции.

Пример

Смотрите пример в описании CommandStringPending.

Смотрите также

CommandStringPending          GetCommandString
-----------------------------------------------------------------------
Процедура SetGetKeyProc (GKP: GetKeyProc);

Назначение

Определяет, какую  программу  надо  вызвать  для  обработки
нажатия  клавиши

Описание

Эта программа позволяет вам определить  программу,  которая
должна  быть вызвана cpGetKey для обработки нажатия клавиши
пользователем.
Типичный  пример  ее  использования - ситуация, когда нужно
выполнять  фоновое задание во время ожидания нажатия клави-
ши. Смотрите    описание "О фоновых заданиях" в начале этой
секции. Заметим, что если установлена поддержка мыши (вклю-
чена опция cpMouseSupport), то эта программа должна вызыва-
ться после cpOptionsOn.

Пример

Uses OpCrt,  OpCmd, OpDate;
{$Ft}
function OurGetKey: Word;
begin
inline not keyPressed do begin
inline ($CD/$28); {Give TSRs chance to pop up}
FastWrite (Current Time String ('HH:MM'), 1, 75, TextAttr);
                                      {Update screen clock}
{...perform other background tascks...}
end;
OurGetKey: = ReadKeyWord;
end;
{$F-}
...
Commands.SetGetKeyProc (OurGetKey);

Это - функция перемещения для GetKey,  выводящая  на  экран
время при ожидании нажатия клавиши.

Смотрите также

cpGetKey             SetKeyPressedProc
--------------------------------------------------------------------
Процедура SetHelpProc (GHP: GetHelpProc);

Назначение

Определяет программу, которую надо вызвать на запрос о
справке

Описание

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

Пример

{F+}
procedure MyHelpProc (UnitCode: Byte; IdPtr: Pointer,
                       HelpIndex:Word);
begin
{Show help based on UnitCode, IdPtr and HeloIndex}
end;
...
Commands.SetGEtHelpProc (MyHelpProc);

Смотрите также

cpGetHelp
---------------------------------------------------------------------
Процедура SetKeyPressedProc (KPP: KeyPressedProc);

Назначение

Определяет программу, которая должна  установить,  была  ли
нажата клавиша

Описание

Это правило позволит вам определить, какая программа должна
вызываться   cpKeyPressed   (обычно   OpCrt.KeyPressed  или
OpMouse.KeyOrButtionPressed).  Обычно  в использовании этой
процедуры нет  необходимости. Но она нужна, если ваша прог-
рамма использует OPMACED и должна выполнять фоновое задание
в ожидании нажатия  клавиши.

Пример

{$F+}
Function MyKeyPressedProc: Boolean;
begin
MyKeyPresedProc: = KeyPressed;
end;
{$F-}
...
Commands.SetKeyPressedProc (MyKeyPressedProc);

Смотрите также

cpKeyPressed              Set GetKeyProc
---------------------------------------------------------------------
Процедура SetKeyPtr (KeysPtr: CmdTablePtr; MaxIndex: Word);

Назначение

Изменяет основную таблицу команд

Описание

Это правило позволяет вам менять  основную  таблицу  команд
объекта CommandProcessor. Обычно это используется в случаях,
когда одна  таблица команд используется в одной части прог-
раммы, а другая - в другой. Например, вы  хотите  использо-
вать специальную   таблицу  для   определенного     объекта
DirList(OPDIR), а не ту таблицу,которая обычно используется
разновидностями объекта PickList(OPPICK).
KeysPtr - это адрес таблицы команд, а MaxIndex -  номер  ее
последнего элемента.

Пример

Commands.SetKeyPtr (KeySet3, KeySetMax3);

Здесь   предполагается,  что  существует   таблица   команд
KeySet3, - 'array [0..KeySetMax3]  of  Byte'.  После  этого
выражения она  станет основной таблицей команд

Смотрите также

SetSecondaryKeyPtr
------------------------------------------------------------------
Процедура SetSecondaryKeyPtr (Keys Ptr: CmdTablePtr;
                               MaxIndex: Word);

Назначение

Изменяет дополнительную таблицу команд

Описание

Это правило позволяет вам определить дополнительную таблицу
команд.  Наиболее часто это используется в приложениях, где
много объектов, работающих с окнами, и необходимо использо-
вать общие "горячие клавиши".  Как  пример  можно  привести
DESCKPOP. Смотрите описание TPUI.PAS; там показано, как ис-
пользуется SetSecondaryKeyPtr.      KeysPtr - адрес таблицы
команд, а MaxIndex - номер ее последнего  элемента.

Пример

Commands.SetSecondaryKeyPtr (KeySet3, KeySetMax3);

Здесь  предполагается,  что   существует  таблица    команд
KeySet3 - 'array  [0..KeySetMax3]  of  Byte'.  После  этого
выражения KeySet3 станет дополнительной таблицей команд

Смотрите также

SetKeyPtr
--------------------------------------------------------------------
Процедура SetUserHookProc (UHP: UserHookProc);

Назначение

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

Описание

Это правило  позволяет  вам  определить программу,  которая
должна вызываться при распознавании GetComand нажатия клави-
ши. Наиболее  распространенный  случай его применения - это
информировать  пользователя,  что  введена  часть  команды.
Например, если  есть несколько команд, вызываемых  комбина-
циями двух клавиш, первая из которых - <CtrlK>, то процеду-
ра всегда будет высвечивать '^K' в строке состояния, всякий
раз когда нажимается <CtrlK>.  Пример  использования   этой
процедуры смотрите в EDITOR.PAS

Примеры

{$F+}
procedure MyUserHock [CPP: CommandProcessorPtr; MT:MatchType;
                       Key: Word);
begin
if MT = Partial Match then
ringBell;
end;
{$F-}
...
Commands.SetUserHookProc (MyUserHook);

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

Commands.SetUserHookProc (OMyUserHook);
Неверно: Параметр  SetUserHookProc должен быть процедурного
типа, а не адресом.

Смотрите также

cpUserHook                     GetCommand
----------------------------------------------------------------------
Процедура Store (var s: IdStream);

Назначение

Запоминает командный процессор в потоке

Описание

S - надлежащим образом  установленный  поточный  объект  (к
примеру,  поточный файл, открытый для записи). Заметим, что
S может быть  разновидностью  типа  IdStream,   включающего
DosIdStream, BufldStream  и  MemIdStream (хотя вы, конечно,
не сможете произвести запись  в объект типа MemIdStream).
Процедура  записывает  все  сведения  о  CommandProcessor в
поток S. Если таблица (таблицы) команд не зарегистрирована,
то ее содержание также запишется в поток.
Чтобы проверить, не было ли ошибок при записи в поток,  вы-
зовите поточную функцию  GetStatus, как  показано в примере
ниже.
Процедура регистрации для CommandProcessor - CommandProces-
sorStream.

Пример

uses OPCRT,OPROOT,OPCMD;
const
{Define a small KeySet of a few cursor commands}
KeyMax:=30;
KeySet : array[0..KeyMax] of Byte = (
{ length   keys       command type     key sequence}
   3,       $00,$48,   ccUp,            {Up}
   3,       $00,$50,   ccDown,          {Down}
   3,       $00,$4b,   ccLeft,          {Left}
   3,       $00,$4d,   ccRight,         {Right}
   2,       $1b,       ccQuit,          {Esc}
   0,0,0,0,0,0,0,0,0,0,0,0);      {room for more commands}
   var
   Commands : CommandProcessor;
   Cmd,Key,Status : Word;
   S : BufIdStream;
   begin
   Commands.Init(@KeySet,KeyMax);
   S.Init('COMMAND.STM',Screate,1024);
   S.RegisterHier(CommandProcessorStream);
   S.Put(Commands);
   Status:=S.GetStatus;
   if Status<>0 then begin
   WriteLn('Store error',Status);
   Halt;
   end;
   S.Done;
   Commands.Done;
   end.

Определяет объект Commands и  сохраняет его  в потоке,  ис-
пользуя  поточное  правило  Put,  которое  неявно  вызывает
CommandProcessor.Store. Пример  извлечения  из потока можно
найти в описании Load.

Смотрите также

Load
------------------------------------------------------------

               3. Объект CommandPacker

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

Program CommandPackerDemo;  {EXMDPK.PAS}
ses OPCRT,OPCMD;
Const
 {Define a small KeySet of a few cursor commands}
 KeyMax:=30;
 KeySet : array[0..KeyMax] of Byte = (
 { length   keys       command type     key sequence}
   3,       $00,$48,   ccUp,            {Up}
   3,       $00,$50,   ccDown,          {Down}
   3,       $00,$4b,   ccLeft,          {Left}
   3,       $00,$4d,   ccRight,         {Right}
   2,       $1b,       ccQuit,          {Esc}
   0,0,0,0,0,0,0,0,0,0,0,0);      {room for more commands}
   MaxCmd = ccDown;     {Highest legal command in command table}
   NumCols = 3;     {Number of columns in unpacked command table}
   var
   Packer : CommandPacker;    {CommandPacker object}
   UKeySet : array[1..MaxCmd,1..NumCols] of KeyRec; {Unpacked
                                                 command table}
   Commands : CommandProcessor;  {CommandProcess object}
   Key,Cmd : Word;
   begin
   {Unpack the KeySet command table}
   Packer.Init (@KeySet,  {Pointer to packed command table}
                MaxCmd,  {Highest legal command in packed
                          command table}
                KeyMax,  {Highest legal index into packed
                          command table}
                @UKeySet {Pointer to unpacked command table}
                NumCols  {Number of "columns" in unpacked
                          command table}
                False);  {Commands are bytes, not words}

   {UKeySet is now available for modification...change ccUp
    from <Up> to <F1>}
   UKeySet[ccUp,1].Keys:=#00#3b;
   UKeySet[ccUp,1].Modified:=True;

   {Check the modified UKeySet for keystroke conflicts}
   if Packer.ConflictsFound then
   WriteLn('KeyStroke conflicts was found');

   {Repack the UKeySet array into the KeySet array}
   if not Packer.PackKeys then
   WriteLn('Failed to repack command table');
   else
   WriteLn('Keys repacked successfully');

   {Demonstrate our custom command table}
   Commands.Init(@KeySet,KeyMax);
   repeat
   Cmd:=Commands.GetCommand(Key);
   case Cmd of
   ccUp   : WriteLn('ccUp');
   ccDown : WriteLn('ccDown');
   ccLeft : WriteLn('ccLeft');
   ccRight: WriteLn('ccRight');
   ccQuit : WriteLn('ccQuit');
   else        WriteLn('ccNone');
   end;
   until Cmd = ccQuit;
   end.

Первое, что  здесь  надо  отметить, -  это  двумерный  массив
UKeySet,  который используется для хранения назначений клавиш
после распаковки    таблицы команд (KeySet). После распаковки
назначения клавиш    принимают вид записей из трех "колонок".
Это значит, что, если,  например, ccQuit соответствовала трем
различным комбинациям  клавиш, то  после  распаковки  эти три
комбинации   будут  размещены  в  UKeySet[ccQuit,1],  UKeySet
ccQuit2], UKeySet[ccQuit3] соответственно. Первая размерность
массива указывает имя последней  по  счету  команды,  которую
надо сохранить. Обычно это  будет  пользовательская   команда
выхода, типа ccUserO (код 200), но в   простейших  случаях ей
может оказаться и ccDown (код 13). Каждый элемент распакован-
ной таблицы команд (UKeySet) - это  запись типа KeyRec:
Const
KeyLength = 6;
Type
KeyString = string [KeyLength];
KeyRec =
Record
Codifie: Boolean;
Confliet: Boolean;
CmdCode: Word;
Keys: KeyString;
end;
Первое поле, Modified, не используется объектом CommandPacker;
оно лишь устанавливает размеры памяти  для  фиксации  команд,
которые  были  изменены пользователем. Второе поле, Conflict,
останавливается  в  False  конструктором  Init, но может быть
установлено в True правилом ConfliсtsFound, проверяющим нали-
чие конфликтов    в назначениях клавиш. Третье поле, CmdCode,
содержит код команды, связанной с последовательностью клавиш,
которая в свою очередь хранится  в  четвертом  поле,  Keys, в
ввиде строки длиной <= 6 символов.
После того, как  таблица  команд  распакована   конструктором
Init, команде  ccUp  ставится  в  соответствие   клавиша <F1>
вместо <Up>).  Конечно,  это  очень  простой пример - обычно
программы конфигурации  позволяют  пользователю  изменять на-
значение клавиш в интерактивном  режиме.  Но здесь просто по-
казано, что нужно сделать для такого изменения.
Следующий шаг -  отслеживание  конфликтов. И  здесь все очень
упрощено. Обычно программа при обнаружении конфликта останав-
ливается и дает пользователю возможность исправить его.
Наконец, последний этап - это  "упаковка"  измененной таблицы
команд с  использованием  правила  PaсkKeys.  Если  случается
сбой, (обычно из-за того, что число назначений клавиш слишком
велико и не  может быть запомнено в таблице), то возвращается
значение False.   В нашем примере об этом просто будет выдано
сообщение; на самом же деле правильней будет остановить прог-
рамму и позволить пользователю  урезать  таблицу  команд   до-
пустимых размеров.
Конечно, приведенный  выше пример оставляет желать лучшего. Но
цель этого примера -  показать  вам, какие  правила и в каком
порядке вызывать.  За более серьезными примерами обратитесь к
PINST.PAS.

                        Константы

KeyLength = 6;

Максимальная длина поля KeyString

MaxCommands = 255 * 3;

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

Типы

CommandPacker =
Object (Root)
...
end;

Объект, используемый для распаковки и запаковки таблицы команд
объекта CommandProcessor.

KeyString = string [KeyLength]

Строка, хранящая комбинацию клавиш.

KeyRecPtr = ^KeyRec;
KeyRec =
Record
Codified: Boolean;
Conflict: Boolean;
CmdCode: Word;
Keys: KeyString;
end;

Элемент  распакованной  таблицы  команд.  CmdCode -  это  код
команды,  для которой надо изменить назначение клавиш. Keys -
строка, хранящая это назначение. Например, если команде соот-
ветствует    клавиша <F10> (ее скан-код $4400), то Keys будет
иметь вид: '#0#$44' (два символа); если команде соответствует
комбинация клавиш  <CtrlK><CtrlD>,  то  Keys  будет содержать
^K^D' (два символа).  Если  нет  соответствующих  клавиш, то
строка будет пустой. Поле ConflictSet устанавливается в False
при инициализации KeyRec, и переустанавливается в True только
если ConflictFound   определит конфликт в назначениях клавиш.
Поле Modified также устанавливается в False  при  инициализа-
ции KeyRec и его значение  не  может  быть  изменено никакими
правилами объекта CommandPacker. Он просто резервирует память
для написанных пользователем программ, нуждающихся в фиксиро-
вании изменений в назначениях клавиш.

UnpackedCmdTable = array [1..MaxCommands] of KeyRec;
UnpackedCmdPtr = ^UnpackedCmdTable;

Таблица команд после распаковки

                   Процедуры и функции

Функция ConfiсtsFound: Boolean;

Назначение

Проверяет наличие конфликтов в распакованной таблице команд

Описание

Это правило используется для определения, нет ли конфликтов в
распакованной таблице команд. Например, если пользователь на-
значит  клавишу <F1> одновременно на команды ccHelp и ccQuit,
то будет  выявлен  конфликт.  Таким  образом,  CоnfliсtsFound
должна вызываться  перед PackKeys, и если она возвратит True,
то пользователь должен  устранить конфликт (конфликты).
После вызова ConflictsFound,  каждый  KeyRec, соответствующий
"конфликтующий" команде, установит свой флаг "Conflict" в True.

Пример

KeySet: array[1..MaxCmd, 1..NumCds] of KeyRec; {Unpacked command
                                               table}
Сmd, Col: Byte;
...
if Packer.ConficrsFound then begin
writeln ('KeyStroke conflicts found for the following command
codes:');
or Cmd: = 1 to MaxCommands do
or Col: = 1 to NumCols do
if UKeySet [Cmd, Col].Coflict then
writeln ('Comans:', Cmd, 'Column:', Col);
end;

Проверяет наличие конфликтов в распакованной таблице команд и
высвечивает на экране все команды
--------------------------------------------------------------------
Функция GetKeyRecPtr (Cmd: Word; Col: Byte): KeyRecPtr;

Назначение

Возвращает указатель KeyRec "колонки" Col строки Cmd

Описание

Это правило позволяет вам обнаружить адрес данного назначения
клавиши в распакованной таблице команд. В  основном  оно  ис-
пользуется, когда распакованная таблица команд была объявлена
как одномерный  массив; и в программах  общего назначения, не
имеющих прямого  доступа к распакованной таблице команд.
Если распакованная таблица команд объявлена как
var  UnpackedKeys: array [1..MaxCmd, 1..NumCols] of KeyRec;
2 Cmd  и  Col оба  являются  допустимыми номерами массива, то
GetKeyRec    возвратит указатель UnpаckedKeys [Cmd,Col]. Если
же  либо  Cmd,   либо  Col  заданы  некорректно,  возвратится
значение nil.

Пример

var
KRP: KeyRecPtr;
...
KRP: = Packer.GetKeyPtr (ccUp, 1);

Возвращает указатель первой KeyRec для команды ccUp.
---------------------------------------------------------------------
Конструктор Init (PKeys: CmdTablePtr; MaxCmd, MaxIndex: Word;
                       UKeys: UnpackedCmdPtr; Columns: Byte;
                       CmdsAreWords:Boolean);

Назначение

Устанавливает указатели упакованных/ распакованных таблиц команд

Описание

Этот конструктор инициализирует объект CommandPacker и распа-
ковывает  таблицу  команд.  PKeys - это  адрес  распакованной
таблицы,  а  MaxIndex  -  максимальный  номер  элемента  этой
таблицы. MaxCmd - это код последней  команды,  хранящейся   в
массиве. UKeys - это адрес массива, в котором хранится распа-
кованная таблица. Columns - это число "колонок" в распакован-
ной таблице команд. А CmdsAreWords показывает,  будет ли рас-
пакованная таблица хранится как маcсив слов (True),  или байт
(False). Короче говоря, PKeys указывает на массив вида
Packeys: array [0..MaxIndex] of Byte; а  UKeys  -  на  массив
вида UnPackedKeys: array [1..MaxCmd;1..Columns] of KeyRec;

Заметим, что Init работает без сбоев.  Он предполагает,   что
распакуемая таблица команд достаточно большая (то есть такая,
какая должна быть), и  если  MaxCmd  слишком  мал,  а  в упа-
кованной таблице будет  команда с номером, большим MaxCmd, то
эта ошибка будет проигнорирована.

Пример

Смотрите пример в начале этой секции
--------------------------------------------------------------------------
Функция PackKeys: Boolaen;

Назначение

Упаковывает распакованный массив команд

Описание

Это правило должно вызываться, когда в распакованную  таблицу
команд  внесены  нужные  изменения, и нужно упаковать таблицу
обратно. Она    возвратит True, если упаковка прошла успешно,
и False, если измененной таблице команд не хватило зарезерви-
рованного для упакованной  таблицы памяти. Если упаковка   не
удалась, вы можете использовать   SizeKeys, чтобы определить,
насколько "велика" измененная таблица.
Заметим,    что   PaсkKeys  обычно  следует  вызывать   после
oflictsFound, которая проверяет наличие  конфликтов в распа-
кованной таблице команд.

Пример

if not Packer.PackKeys then
writeln ('Failed to repack command table')
else
writeln ('Keys packed successfully');
-------------------------------------------------------------------
Функция SizeKeys: Word;

Назначение

Возвращает число байт в упакованной (после распаковки и
изменений) таблице команд

Описание

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

             4. Процедуры и функции модуля OPCMD

Ниже  приведены  описания различных процедур и функций модуля
OPCMD.

Процедура DefaultErrorProc (UnitCode: Byte; var ErrorCode: Word;
                           ErrorMsg: string);

Назначение

Контроль ошибок для всех объектов, задаваемый по умолчанию

Описание

Эта программа отслеживает ошибки во всех объектах, куда она
включена. Она просто вызывает RingBell
------------------------------------------------------------------------
Процедура RingBell;

Назначение

Издает звуковой сигнал

Описание

Эта программа генерирует  звук (частота  по  умолчанию =  700
Герц, продолжительность - 100 миллисекунд). Эти значения можно
изменить, вызвав SetBell.

Пример

{$F+}
Procedure MyErrorProc(UnitCode:Byte;var ErrorCode:Word;
                     ErrorMsg:String);
Begin
if ErrorMsg<> ' ' then
writeLn('Error',ErrorCode);
ringBell;
end;
{$F-}

Простой контроль ошибок
---------------------------------------------------------------------
Процедура SetBell (Pitch, Duration: Word);

Назначение

Останавливает продолжительность и частоту звукового сигнала

Описание

Эта программа устанавливает продолжительность и частоту звука,
вырабатываемого программой. RingBell.Pitch показывает частоту
звука (в герц), а Duration - время (в миллисекундах), в тече-
нии которого должен издаваться звук

Пример

SetBell (500,150);
RingBell;

Снижает частоту звука и увеличивает его продолжительность;
затем генерирует его.

           D.    OPMOUSE  :  ПРОГРАММЫ ДЛЯ РАБОТЫ С МЫШЬЮ

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

             Начало работы с OPMOUSE

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

       Программы OPMOUSE         "Эквиваленты" из OPCRT

       MousePressed               KeyPressed
       MouseKeyWord               ReadKeyWord
       InitializeMouse            ReinitCrt
       MouseWhereX                WhereX
       MouseWhereXAbs             WhereXAbs
       MouseWhereY                WhereY
       MouseWhereYAbs             WhereYAbs
       MouseWhereXY               WhereXY
       MouseGotoXY                GotoXY
       MouseWindow                Window
       RestoreMouseCoordinates    RestoreWindowCoordinates
       StoreMouseCoordinates      StoreWindowCoordinates
       NormalMouseCursor          NormalCursor
       FatMouseCursor             FatCursor
       BlockMouseCursor           BlockCursor
       HiddenMouseCursor          HiddenCursor
       GetMousePage               CurrentPage (global var)
       SetMousePage               SetVisiblePage





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

            Поддержка мыши другими модулями.

Как отмечалось  выше,  многие  объекты  Object   Professional
обеспечивают  связь  с мышью на базе программ модуля OPMOUSE:
меню, текстовые    редакторы, cписки, экраны : любые объекты,
использующие    CommandProcessor,  поддерживают мышь. Во всех
случаях  вы  можете  сделать   работу  с  мышью    возможной,
активизируя опцию  соответствующего     командного процессора;
например:
XxxCommands.cpOptionsOn (cpEnableMouse);
где  XxxCommands  - это  имя  подходящего  объекту командного
процессора.Во многих случаях, все, что от вас требуется перед
обеспечением  поддержки мыши - это выбрать, какой тип курсора
мыши вы хотите    использовать (смотрите раздел "Курсор мыши"
ниже). Вы также можете   захотеть увидеть курсор мыши, вызвав
ShowMouse, но это не всегда  необходимо.  Если поддержка мыши
остановлена, программы всех модулей  "видят"   курсор   мыши,
когда это им надо, и по завершению  работы    восстанавливают
остояние курсора.
Хотя вы обычно будете стремиться обеспечить свои собственные,
улучшенные  формы  поддержки  мыши, для написания  программы,
которая   позволяет  эффективно использовать мышь, достаточно
несколько   обращений  к функциям в начале программы. Если вы
разбираете демонстрационные программы EDITOR.PAS и ENTRY.PAS,
обратите внимание  на разделы с кодами  '{$IFDEF UseMouse}' и
'{$ENDIF}', и вы  увидите,   насколько   небольшие     усилия
требуются для обеспечения   поддержки мыши в этих программах.

               Курсор мыши.

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

     program  MouseCursor;
     uses OPCRT, OPMOUSE;
     begin
     if NotMоuseInstalled then Halt;
     NormalCursor;
     ClrScr;
     FastCenter('Click the left button to change
     cursors...',25,$07);
     EnableEventHandling;
     SoftMouseCursor($0000,(ColorMono($4f,$70) shl 8)+$04;
     ShowMouse;
     while MouseKeyWord <> MouseLft do {nothing}
     HideMouse;
     FastCenter('Click the left button to exit...',25,$0f);
     BlockMouseCursor;
     ShowMouse;
     while MouseKeyWord <> MouseLeft do {nothing}
     NormalCursor;
     end.

  Когда программа стартует, курсор мыши  будет  иметь  форму
бриллианта (красного  и  белого  в  цветной системе, и цвета,
противоположного фону, в монохромных системах), а "системный"
курсор будет мигать в левом верхнем углу экрана. Это - пример
"программного" курсора мыши,  курсора, сгенерированного прог-
раммно (драйвером мыши). Если  вы  один  раз  нажмете   левую
кнопку    мыши, бриллиант исчезнет, "системный курсор" станет
мигающим    блочным  курсором,  и любое движение мыши вызовет
движение курсора.  Это - пример "аппаратного" курсора, сгене-
рированного аппаратно (дисплейным адаптером).
  "Аппаратный" курсор мыши наиболее удобен в тех программах,
где он является   опцией.  К  сожалению, таких программ мало.
Большинство программ, использующих  мышь,  используют также и
"системный" курсор, и не могут ему позволить двигаться каждый
раз, когда пользователь двигает мышь.
  Но если вы работаете с программой, не требующей этого,  то
все, что вы должны сделать - это установить форму курсора. Вы
можете использовать программу   HardMouseCursor,      которая
позволит вам определить начальный и конечный пикселы курсора,
или вы    можете  воспользоваться  программами более высокого
уровня:     NormalMouseCursor,     FatMouseCursor         или
BlockMouseCursor.
  Одно предупреждение насчет аппаратного курсора.    Драйвер
мыши    вычисляет его позицию,   программируя контроллер CRT,
и не запоминает  область  данных  BIOS, поэтому вы не сможете
определить    позицию  курсора  с  помощью  WhereX,  WhereY и
подобных процедур.
Единственная   программа  модуля OPCRT,  возвращающая позицию
"аппаратного" курсора мыши, - это WhereXYdirect. По различным
причинам,  программы  модуля  OPCRT,  работающие  с  курсором
(GotoXY, GotoXY abs) не могут быть использованы для перемеще-
ния "аппаратного" курсора мыши.
  "Программный" курсор  используется  не  только  в случаях,
если   невозможно применение "аппаратного" курсора, но и если
вы хотите    достичь определенных  эффектов,  невозможных при
использовании "аппаратного" курсора. По умолчанию, курсор мыши
и немерцающий,    прозрачный,  альтернативного цвета, то есть
это небольшая    область, цвет которой изменяется всегда так,
чтобы не совпадать с  цветом символа в позиции, где находится
курсор. Как это достигается?
  Когда  вы  выбираете  "программный"  курсор  (   Используя
FatMouseCursor),  вы  должны  определить  "маску  экрана"  и
"маску курсора". Чтобы быстрее уяснить, для чего используются
эти значения, рассмотрим   пару  примеров.  Предположим,  что
курсор мыши движется к символу    'A' (ASCII #$41),   который
нарисован белым по черному    (с видеоатрибутом $OF).       В
видеопамяти этот символ выглядит как    слово,  старший  байт
которого занимает видеоатрибут: $OF41. Задавая маску   экрана
по умолчанию: $FFFF (=DefaultScreenMask),  и маску курсора по
умолчанию: $7700 (=DefauitCursorMask),   драйвер  мыши  затем
создает курсор, складывая логическим AND   значения символа и
маски экрана:
$OF41 AND $FFFF = $OF41 {no change}
и затем применяя XOR к результату и маске курсора:
$OF41 XOR $7700 = $7841 {attribute changed, character unchanged}
так,  курсор  в  позиции  символа  'A' будет альтернативного
цвета  (темно-серый на светло-сером). Теперь предположим, что
вы хотите получить немного другой результат -  изменить    не
только цвет, но и форму курсора, сделав его в виде бриллианта
(ASCII #$O4). В  этом  случае вы  должны  использовать  маску
экрана $FFOO, а маску  курсора - $7704:
$OF41 AND $FFOO = $OFOO {attribute unchanged,
{character wiped out}
$OFOO XOR $7704 = $7804 {attribute changed,
{new charader in low byte}
наконец, предположим, что вы хотите, чтобы цвет курсора   ос-
тавался постоянным, независимо от своего положения на экране:
вы хотите, чтобы он всегда появлялся со звуком (ASCII # $14),
и имел цвет белый-на красном ($4F). В  этом  случае вам нужна
маска экрана $OOOO и  маска курсора $4F14:
$OF41 AND $OOOO = $OOOO {attribute and character both wiped out}
{OOOO XOR $4F14 = $4F14 {new attribute, new character}

                   Считывание кнопок мыши

  Когда вы начинаете разрабатывать   поддержку мыши   вашими
программами,  вы  быстро  осознаете,  что задача вовсе не так
трудна, если у вас есть  правильная  ее  постановка.    Часто
достаточно знать     одну или две вещи: где находится мышь, и
такая из ее кнопок  была нажата. В этом разделе мы рассмотрим
кнопки мыши. Как было отмечено, OPMOUSE похож на модуль OPCRT.
Поэтому неудивительно,  что  двумя из наиболее важных функций
OPMOUSE являются   MousePressed и MouseKeyWord, которые имеют
такое же отношение   к  кнопкам  мыши,  как  и   KeyPressed и
ReadKeyWord к клавиатуре. MousePressed сообщает вам о нажатии
кнопки мыши, а MouseKeyWоrd  возвращает значение, по которому
можно понять, что нажато. Перед   тем, как пользоваться этими
программами, уясните для себя лишь   две вещи. Во-первых, эти
функции не могут   ничего     делать, пока    не      вызвана
PоuseEventHadling.    Почему,   мы   объясним   в    описании
"Контроль событий".   Во-вторых,   MouseKeyWord    возвращает
"псевдо скан-код" - слово, подобное скан-кодам,  возвращаемым
Read-KeyWord:
MouseLft = $EFOO; {Left Button}
MouseRt     =  $EEOO; {rigth button}
MouseBoth   =  $EDOO; {both buttons}
MouseCtr    =  $ECOO; {center button}
MouseLftCtr =  $EBOO; {left and center buttons}
MouseRtCtr  =  $EAOO; {rigth and center buttons}
MouseThree  =  $E900; {all three buttons}

  Как вы  можете видеть,  младший  байт  всегда 0, а старший
байт  показывает, какая кнопка (кнопки) нажата. Помимо других
вещей,    такая  система  упрощает обеспечение поддержки мыши
программами, которые уже поддерживают ввод с клавиатуры. (За-
метим, что эти псевдо-скан-коды можно посмотреть в справочной
программе DESKPOP).
Возникает вопрос: а не проще ли, если одна функция будет воз-
вращать и код клавиши, и код кнопки мыши?  Конечно,  да,    и
такая  функция  есть:  ReadKeyOrButton.  Эта программа просто
идет в цикле  ожидания  нажатия  клавиши  ( если  раньше была
нажата клавиша), либо  псевдо-скан-код  кнопки  мыши,    если
раньше была нажата кнопка.    (Она  возвращает  также,  через
глобальные переменные MouseKeyWordX и  MouseKeyWordY, позицию
курсора мыши и количество нажатий кнопки). Если ваша программа
использует ReadKeyWord для работы с клавиатурой,  вы  сможете
обеспечить в некоторой степени поддержку  мыши, заменив вызов
ReadKeyWord на ReadKeyOrButton и добавив  некоторые операторы
управления нажатием кнопок. (Вы также можете    заменить  все
вызовы KeyPressed на вызовы KeyOrButtonPressed).
И OPMOUSE  есть и другие программы, возвращающие информацию о
кнопках мыши, но эти две используются наиболее часто. Почему?
Потому что остальные программы могут лишь сообщить вам, какие
кнопки    были  нажаты  на  данный  конкретный момент. Они не
гарантируют того,  что эти кнопки были также и отжаты. Mouse-
KeyWord и ReadKeyOrButton    делают это, с помощью глобальной
переменной WaitForButtonRelease,  устанавливаемой   в   True.
Чтобы посмотреть, насколько важно    подождать   освобождения
кнопок, попробуйте    запустить    какие-нибудь    программы,
использующие   ReadKeyOrButton    с    WaitForButtonReleased,
остановленной в False.   Вы   увидите,  что будет  появляться
информация  лишь об одной из нажатых кнопок, даже если кнопки
были нажаты    строго  одновременно.  Только в редких случаях
требуется установить WaitForButtonRelease в False.

             Окна и координаты мыши

  По аналогии   с   OPCRT,   модуль   OPMOUSE  позволяет вам
устанавливать  "окна  мыши" (области  экрана, границы которых
должен распознавать  курсор мыши), и считывать с курсора мыши
текущие координаты  окна.
  Чтобы установить окно мыши, вам нужно вызвать одну из двух
программ : MouseWindow   и   FullMouseWindow.     MouseWindow
полностью    аналогична  Window.   Ее  входные  параметры - 4
однобайтовых величины  :   XLow,   YLow,   XHigh,      YHigh,
следовательно, чтобы, к  примеру,  создать  окно    80  x 25,
следует вызвать 'MouseWindow   (1,1,80,25);'. FullMouseWindow
является "программой-оболочкой" :  все, что она делает, - это
вызывает MouseWindow  с текущими  размерами экрана в качестве
параметров. Так как OPMOUSE сам    вызывает эту процедуру при
запуске программы, вам обычно не    требуется    вызывать эти
процедуры, кроме случаев, когда вы   хотите создать маленькое
окно, или если вы поменяли видеорежим, или включили/выключили
шрифт 8х8.
  Как было отмечено в разделе "Считывание кнопок мыши",   вы
можете определить положение курсора мыши в тот момент,  когда
нажата кнопка, с помощью MouseKeyWordX и MouseKeyWordY. Чтобы
узнать положение курсора в другой момент времени, у вас  есть
несколько  способов.  Один  -  это  использовать  MouseWhereX
и MouseWhereY, являющиеся аналогами WhereX и WhereY.   Второй
способ, иногда более эффективный, - это использование  Mouse-
WhereXY, которая возвращает сразу Х и У - координаты  курсора
и состояние кнопок мыши.
  В рассмотренном случае предполагается, что полученные коор-
динаты курсора будут измеряться относительно текущего    окна
мыши. Если же вы хотите получать в данный  момент  абсолютные
координаты курсора, используйте MouseWhereXAbs и  MouseWhere-
XAbs. Если вы желаете знать, где  находится  мышь  в   момент
нажатия кнопки,  вы  легко  можете  вычислить  ее  абсолютные
координаты :  добавив  MouseXLo  к  координате  X  (колонка),
хранящейся в MouseKeyWordX, и MouseYLo к координате  У  (ряд)
хранящейся в  MouseKeyWordY.  Вместе  с  MouseXHi и MouseYHi,
MouseXLo и  MouseYLo  хранят  текущие   размеры  окна   мыши.
MouseXLo и  MouseYlo  - неотрицательные числа,   означающие,
это  координаты   верхнего  угла  экрана - могут начинаться с
(0, а MouseXHi  и  MouseYHi - положительные числа.)

                  "Дроппинг" мыши

  Теперь - немного неприятной  информации.  Мыши не являются
аккуратными животными, поэтому их использование иногда бывает
неудачным,  особенно  при  программном  курсоре.   Рассмотрим
типичный пример.
  Курсор мыши перемещен в ряд 1, колонку 1. Перед самым  пе-
ремещением курсора драйвер мыши считал символ и его    видео-
атрибут с позиции 1,1 , и запомнил их. Перед   очередным  пе-
ремещением  курсора  драйвер  мыши  восстановит          пару
символ/атрибут.    Если содержимое экрана не менялось, то все
прекрасно, но что,  если  ваша  программа написала что-либо в
ряд 1, колонку 1, пока  там  находился  курсор?  Сам   курсор
будет, конечно,   закрыт новой записью. Это не слишком плохо,
так как после  перемещения  он   снова     появится.      Что
действительно плохо,    так  это  то,  что драйвер мыши затем
восстановит прежний символ    с прежним видеоатрибутом в 1,1.
В результате появится уже    ненужный символ ненужного цвета,
и, если вы не будете   аккуратны при программировании, такими
символами может     заполниться   весь экран.  Поскольку этот
эффект напоминает    дно  мышиной  клетки, его часто называют
бросками ("дроппингом")  мыши.
  Итак, вы хотите предотвратить  это,  аккуратно обращаясь с
экраном? Увы, единственный действительно надежный метод - это
прятать курсор мыши всякий раз, когда вы пишете что-либо   на
экран. Если вы собираетесь чистить, сдвигать,    закрашивать,
писать, сохранять, восстанавливать экран,    вы  должны перед
этим вызвать HideMouse или HideMousePrim,    и ShowMouse  или
ShowMousePrim после этого. Это - одна из    причин, почему мы
cоветовали вам использовать аппаратный     курсор, где только
это возможно.
  Хотя  OPMOUSE  ничем  не  может  вам  помочь  в  борьбе  с
дроппингом   мыши, мы по крайней мере можем дать вам полезный
совет. Если  ваша  программа  использует  много  обращений  к
экрану,    типа  FastWrite,  вы можете использовать следующую
программу-оболочку :
  Procedure MouseWrite (S : String; Row,Col,Attr : Byte);
  var SaveMouse : Boolean;
  begin
  HideMousePrim(SaveMouseCursor);
  FastWrite(S,Row,Col,Attr);
  ShowMousePrim(SaveMouseCursor);
  end;

  Используя подобную процедуру, вы сведете к минимуму  число
изменений в вашей программе.    Одна   глобальная   процедура
поиска и перемещения возьмет на   себя   заботы  о процедурах
FastWrite сразу во всем модуле. За   это  придется  заплатить
скоростью : дольше будет производится запись, и много времени
будет уходить на убирание/восстановление  курсора       мыши,
особенно если операций записи много. В случае, если    у вас,
к примеру, есть шесть обращений подряд к FastWrite, вы можете
спрятать курсор мыши перед первым обращением и   восстановить
его после шестого.

                Контроль событий

  Хотя  средства  высокого  уровня,  которые мы рассмотрели,
достаточны для многих прикладных  программ,   бывают  случаи,
когда надо знать, что  делает  мышь,  как  только   случилось
какое-то событие. (  Под   событием  понимаются  три вида си-
туаций : перемещение мыши, нажатие и освобождение ее кнопок).
Для получения   такой   информации   вам  следует    написать
программу контроля событий мыши.
  Звучит сложно, но OPMOUSE делает   эту   задачу     вполне
простой. Все, что вам надо сделать, это написать   глобальную
процедуру, объявленную как Far, без параметров,    и  вызвать
SetMouseEventHandler, чтобы модуль OPMOUSE знал,   что     вы
хотите вызывать его всякий раз, когда случается  событие :
  {$F+}
  Procedure MyEventHandler;
  begin
  {handle event}
  end;
  ...
  SetMouseЕventHandler(AllMouseEvents,@MyEventHandler);

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

  SetMouseEventHadler  имеет  два  параметра. Второй из них,
UserRountine, является   адресом   вашей   программы контроля
событий.    Первый,  -  EventMask,  это   байт,   описывающий
интересующее вас    событие.  Вы  можете устаноавить значение
этого байта, используя одну или более следующих констант:

  DisableEventHandler   = $00;
  MouseMoved            = $01;
  LeftButtionPressed    = $02;
  LeftButtionReleased   = $03;
  RigthButtionPressed   = $04;
  RightButtionReleased  = $05;
  CenterButtionPressed  = $06; {только для трехкнопочных мышей}
  CenterButtionReleased = $40; {только для трехкнопочных мышей}
  AllMouseEvents        = $7F;

  Например, вас интересует только левая кнопка мыши.   Тогда
мы должны установить 'LeftButtionPressed + LeftButtionReleased'
в   вашей  EventMask.   Если  вас  интересуют   все  события,
используйте   'AllMouseEvent'.  А  если  вы  почему-то хотите
отменить контроль    событий, установите 'DisableEventHadler'
(или установите  параметр  UserRountine в    'nil').     Если
контроль событий установлен, вы можете получать  всю   нужную
нам информацию о  состоянии   мыши,   проверяя      следующие
глобальные типизованные константы:
  MouseEvent  : MouseEventType = DisableEventHandler;
  MouseStatus : ButtionStatus  = NoButtion;
  MouseLastX  : Byte           = 1;
  MouseLastY  : Byte           = 1;

  MouseEvent -  однобайтное  число типа EventMask. Вы можете
установить проверку определенного события, например, движение
мыши, применив логическое AND к  MouseEvent и подходящий кон-
станте и оценив, не равен ли результат нулю:
  MouseWasMoved : = MouseEvent AND Mouse <> 0;
MouseStatus  сообщает   вам,   какие   кнопки   нажаты.   Она
объявляется, как перечислимый тип ButtionStatus:
  type
  ButtionStatus = (
  NoButtion, LeftButtion, RightButtion, BothButtions,
  {the following values are possible only on 3-buttion mouse}
  CenterButtion, LeftAndCenterButtions, RightAndCenterButtions,
  AII3Buttions);
  Если вы   хотите   определить положение   курсора  мыши  в
координатах  текущего   окна,   это  можно  сделать с помощью
МouseLastX и MouseLastY.    При  написании программы контроля
cобытий имейте в виду, что    события  могут  случаться очень
часто, по многу раз в секунду.  Поэтому программа должна быть
короткой и корректной; не использовать много стековой памяти;
и, конечно, не должна вызывать   никаких     нереентерабельных
процедур и функций: то есть большинство   программ DOS, части
библиотеки поддержки Турбо-Паскаля, и    ваши     собственные
программы, которые могут быть  сброшены,   если    неожиданно
изменится значение глобальной переменной.

                   Использование мыши в TSR

  Написание TSR, обеспечивающего поддержку мыши,   будет  не
слишком   сложным, если вы учтете несколько нюансов. Здесь мы
предполагаем, что у вас уже есть опыт написания TSR с помощью
модуля OPTSR или  OPSWAP. Если нет, то вам следует по крайней
мере ознакомиться с документацией OPTSR, перед тем как читать
дальше. Еще лучше, если вы вернетесь к этой теме, уже написав
хотя бы 1 TSR, и    будучи   готовыми   к   изучению проблемы
поддержки мыши. Если вы освоили TSR, что ж, давайте начнем.
Первое, что вам нужно учесть, это то, что ваш TSR должен быть
готов к перекрытию программы,   которая уже работает с мышью.
Чтобы    обеспечить  это,  вы  должны  быть  готовы сохранять
состояние драйвера    мыши  перед  перекрытием,  и  уметь его
восстанавливать после.   Программы, которые вам помогут - это
MouseStateBufferSize, SaveMouseState и RestoreMouseState.
MouseStateBufferSize -   это   функция,   возвращающая размер
буфера, необходимый для сохранения всех данных драйвера мыши.
Мы настоятельно рекомендуем вам вызвать ее сразу после старта
программы, а буфер разместить в памяти до того, как программа
станет резидентной. Причины этого вы поймете ниже. Назначение
SaveMouseState и RestoreMouseState ясно из их названий.
Вторая вещь,   которую   вам нужно уяснить, это то, что вы не
можете    установить мышь в желаемое вам состояние, пока ваша
программа   не станет резидентной, и не можете ждать, что она
установлена  так,   как   вам   надо,  до  начала перекрытия.
Программа, которую вы   перекрываете, может использовать свой
тип курсора или иметь   свое окно для мыши, например. Поэтому
нам нужно переустанавливать    параметры  мыши всякий раз при
перекрытии.    Наконец,   если   вам   нужно     использовать
ReadKeyOnButtion, MouseKeyPressed    или MouseKeyWord,    или
обеспечить поддержку мыши для других    объектов,  вам  нужно
вызвать EnableEventHandling в начале    вашего перекрытия.
Теперь давайте объединим эти нюансы  вместе.    Ниже приведен
схематичный план TSR, использующего OPMOUSE:

    Program MyTSR;
    uses
    Dos,OPCRT,OPMOUSE,OPINT,OPTSR;
    var
    MSP : MouseStatePtr;
    MSPsize : Word;

    {F+}
    Procedure PopupEntryPoint(var Regs : Registers);
    begin
    ReinitCrt;           {reinitialize OPCRT}
    {**save screen and cursor**}
    If MouseInstalled then begin
    SaveMouseState(MSP,False);  {save the state of driver}
    InitializeMouse;     {reinitialize mouse}
    EnableEventHandling;    {install event handler}
    {**set up the mouse window**}
    {**choose a mouse cursor and make it visible**}
    end;
    {**body of the popup goes here**}
    {**restore screen and cursor**}
    if MouseInstalled then
    RestoreMouseState(MSP,False); {restore state of driver}
    end;
    {$F-}
    begin
    {...}
    if MouseInstalled then begin
    MSPSize:=MouseStateBufferSize; {allocate mouse
                                    state buffer}
    {check for a reasonable buffer size}
    if (MSPSize = 0) or (MSPSize > 1000) then
    MouseInstalled:=False
    else
    GetMem(MSP,MSpSize);    {allocate the buffer}
    end;
    {...}
    end.

  Все,   о   чем   еще осталось здесь сказать,   это  порядок
действий, который вы должны соблюдать:
. Вызывать ReinitCrt перед сохранением содержимого экрана
. Сохранять состояние мыши после сохранения экрана, и
. Восстанавливать состояние мыши после восстановления экрана.
Если вы  перепутаете  порядок действий, что может легко случиться,
то ваш экран начнет   работать   с   программой,   которую вы
перекрыли.    Если вас  интересует  более  сложный пример, чем
описанный в MyTSR,  обратитесь  к   демонстрационной программе
ESKPOP.

                        Различие в драйверах мыши

  В добавлении к описанному в предыдущем параграфе,  есть еще
одна очень важная вещь, которая касается MouseStateBufferSizе,
SaveMouseState и RestoreMouseState. Функции, к которым    они
обращаются, выполняется не  всеми  типами   драйверов   мыши.
Microsoft не использовал этих функций, до тех пор пока не был
написан CodeView, который должен был поддерживать  программы,
работающие с мышью, поэтому ранние  версии   драйверов   мыши
Microsoft этих функций не содержат. Во всех относительно новых
версиях драйверов  эти  функции  есть,  но, конечно, не каждый
пользователь располагает новыми версиями.
  Вывод состоит в том, что вы должны использовать эти  функ-
ции осторожно (к этой же категории следует отнести  GetMouse-
Page и SetMousePage). Мы пытались сделать так, чтобы   Mouse-
StateBufferSize возвращала 0, если драйвер мыши не    может с
ней работать, но вам не стоит рассчитывать на нее.     Обычно
она возвращает значение в диапазоне 350-400,   поэтому  сове-
туем вам насторожиться, если значение будет не только   0,  а
и слишком большим (1000 или более, к примеру).   Итак,     вы
должны разъяснить  пользователям  вашей   программы,    когда
поддержка мыши может быть ненормальной, или сказать им,   что
ваша программа не гарантирует четкой работы  с  мышью     для
ранних версий драйверов.
  Подобные проблемы  иногда  возникают ( реже) с MouseGotoXY
(смотрите описание этой процедуры ниже). В общем,  запомните,
что если вашему  драйверу мыши больше  года,   то лучше   его
заменить.

                        Микки

  Последний     штрих   к   вводной  информации.  Наименьшее
расстояние,  "распознаваемое" мышью, называется "микки" - это
примерно    1/100 дюйма.  Когда  вы  двигаете  мышь по столу,
аппаратные    средства  мыши передают драйверу информацию, на
сколько была    сдвинута  мышь, и эта информация измеряется в
микки. Драйвер,    в свою  очередь,   должен   соответственно
передвинуть курсор, чтобы отобразить на экране движение мыши.
Определяя величину   сдвига мыши, драйвер вычисляет значение,
называемое отношением "микки/пиксел".
  Это соотношение  показывает,  насколько  нужно  сдвинуть 8
пикселов курсора, чтобы это  соответствовало  сдвигу  мыши на
пределенное число микки. На самом  деле  таких   соотношений
два : одно - для горизонтального   движения,   другое -   для
вертикального. По умолчанию они равны 8 и 16  соответственно.
В режиме 80 колонок, таким  образом,  значения  по  умолчанию
требуют, чтобы при сдвиге мыши на 8/100 дюйма по  горизонтали
курсор переместился  на  одну колонку, а при сдвиге мыши   на
16/100 дюйма по вертикали - на один ряд.
  Понятно? К счастью, вам не нужно  разбираться в аппаратном
устройстве мыши,  чтобы программно поддерживать работу с ней.
Этот параграф содержит  в  основном  базовый материал, касаю-
щийся GetMickeyCount и  SetMickeyToPixelRatio  -    программ,
описанных ниже, которые обычно не нужны пользователям.  (Если
вас интересует пример их использования,  посмотрите    модуль
MAKEMISC, используемый в MAKEMENU и MAKESCRN).

                        Типы

  ButtonStatus = (
     NoButton,LeftButton,RightButton,BothButtons,CenterButton,
     LeftAndCenterButtons,RightAndCenterButtons,All3Buttons);

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

  MouseEventType = DisableEventHandler...AllMouseEvents;

  Cобытие мыши (движение мыши, нажатие и отпускание кнопок)

  MouseState =
  record
     BufSize : Word;
     Buffer : array[1..400] of Byte;
     end;
     MouseStatePtr = ^MouseState;

  Эта структура данных используется для сохранения состояния
драйвера мыши. Buffer - это массив переменной размерности. Он,
если необходимо, может содержать и более 400 байт. BufSize -
это размер массива +2.

  MouseXlo : Byte;
  MouseXHi : Byte;
  MouseYLo : Byte;
  MouseYHi : Byte;

  Это - координаты текущего окна мыши. Как WindMin и WindMax
в модулях OPCRT и CRT, МouseXlo и MouseYLo - неотрицательные,
а MouseXHi и MouseYHi - положительные числа.

                    Константы

  DefaultScreenMask = $FFFF;
  DefaultCursorMask = $7700;

  Это - маски экрана и курсора для программного курсора мыши.

  DisableEventHandler : $00;
  MouseMoved          : $01;
  LeftButtonPressed   : $02;
  LeftButtonReleased  : $04;
  RightButtonPressed  : $06;
  RightButtonReleased : $08;
  CenterButtonPressed : $10;
  CenterButtonRelеased: $20;
  CenterButtonReleased: $40;
  AllMouseEvents      : $7f;

  Битовые маски для различных событий мыши

  MouseEvent  : MouseEventType = DisableEventHandler;
  MouseStatus : ButtonStatus = NoButton;
  MouseLastX  : Byte = 1;
  MouseLastY  : Byte = 1;

  Используется для передачи программе контроля событий,
установленной с помощью SetMouseEventHandler.

  MouseLft    = $ef00; {left button}
  MouseRt     = $ee00; {right button}
  MouseBoth   = $ed00; {both buttons}
  MouseCtr    = $ec00; {center button}
  MouseLftCtr = $eb00; {left and center buttons}
  MouseRtCtr  = $ea00; {right and center buttons}
  MouseThree  = $e900; {all three buttons}

  Это - псевдо-скан-коды, возвращаемые MouseKeyWord и Mouse-
KeyButton при нажатии кнопки (или комбинации кнопок)

  MouseRoutine : Pointer = nil;

  Если это значение не равно nil, то MouseRoutine становится
указателем программы контроля событий, заданной с помощью
SetMouseEventHandler.

  MouseRoutineEvent : MouseEventType = DisableEventHandler;

  Байт, показывающий, какое событие произошло, процедуре,
на которую указывает MouseRoutine.

  WaitForButtonRelease : Boolean = True;

  Если значение = True, то MouseKeyWord ждет освобождения
нажатой кнопки, и только затем выдает псевдо-скан-код.

                     Переменные

  MouseButtons : Byte;

  Число кнопок используемой мыши (0,2 или 3). Устанавлива-
ется InitializeMouse.

  MouseCursorOn : Boolean;

  Показывает, виден ли на экране в данный момент курсор мыши
или нет.

  MouseInstalled : Boolean;

  Показывает, установлена мышь или нет.

  MouseKeyWordX : Byte;
  MouseKeyWordY : Byte;

  Хранят координаты курсора мыши, начиная с момента последнего
вызова MouseKeyWord.

                  Процедуры и функции OPMOUSE


  Процедура BlockMouseCursor;

  Назначение

  Устанавливает пикселы  для блочного курсора мыши.

  Описание

  Эта программа выбирает аппаратный курсор мыши размером с
  большую печатную букву. Процедура является аналогом
  BlockCursor из OPCRT.

  Смотрите также

  BlockCursor (OPCRT)          HardMouseCursor
  ------------------------------------------------------------

  Процедура DisableEventHandling;

  Назначение

  Отменяет  контроль событий, установленный с помощью
  EnableEventHandling

  Описание

  Эта программа отменяет внутренний контроль событий  модуля
  OPMOUSE, который устанавливается при вызове   EnableEvent-
  Handling. В основном используется в TSR, где надо применять
  MousePressed и MouseKeyWord. Смотрите в качестве   примера
  описание EnableEventHandling.

  Смотрите также

  EnableEventHandling          SetMouseEventHandling

  ----------------------------------------------------------

  Процедура EnableEventHandling;

  Назначение

  Разрешает контроль событий для MousePressed и MouseKeyWord

  Описание

  Эта программа должна   вызываться   перед   использованием
  MousePressed и MouseKeyWord. Она активизирует   внутренний
  контроль событий модуля OPMOUSE,- программу, которая затем
  будет вызываться драйвером мыши всякий раз, когда сдвинется
  курсор или будет нажата/отпущена кнопка.
  Для более подробного изучения смотрите описание в разделах
  "Считывание кнопок мыши" и "Контроль событий"   в   начале
  секции описания OPMOUSE

  Пример
  EnableEventHanding;
  ...
  if MousePressed then begin
  PseudoKey : = MouseKeyWord;
  {handle command assignet to PseudoKey}
  end;
  Активизируется контроль событий, затем используется
  MousePressed  или MouseKeyWord для получения информации с
  кнопок мыши.

Cмотрите также

EnableEventHanding                 MousePressed
MouseKeyWord                        SetMouseEventHandler
-------------------------------------------------------------------

Процедура FatMouseCursor;

Назначение

Устанавливает увеличенный размер курсора мыши для текущего
видеорежима

Описание

Эта программа выбирает аппаратный курсор мыши, который
немного больше стандартного  двухпикселного.  Эта  процедура
является аналогом FatCursor из OPCRT
смотрите также
FatCursor (OPCRT)  HardMouseCursor
-----------------------------------------------------------------------

Процедура FullMouseWindow

Назначение

Устанавливает окно мыши размером с целый экран

Описание

Эта программа выбирает в качестве текущего окна весь   экран.
Заметим, что  нет  необходимости  вызывать  эту  процедуру  в
начале    программы, так как она уже вызывается при установке
мыши.

Пример

SetFont8x8 (true);
FullMouseWindow;

Переход в 43/50 - строчный  режим  и установка координат окна
мыши.

Смотрите также

MouseWindow
-----------------------------------------------------------------------
Процедура GetMiскeyCount (var Horizontal, Vertical: integer);

Назначение

Возвращает  счетчик  "микки"  по горизонтали и  вертикали   с
момента  последнего вызова этой процедуры

Описание

Эта программа  возвращает  значения,  показывающие, насколько
была    сдвинута  мышь   с   момента   последнего      вызова
GetMiскeyCount.   Отрицательные числа означают движение вверх
(по вертикали) или    влево (по горизонтали), положительные -
вниз (по вертикали) или  вправо (по горизонтали).
GetMiскeyCount используется в основном тогда, когда вам нужно
определить, двигал ли  пользователь  мышь,  даже если позиция
курсора мыши не изменялась, поскольку курсор может находиться
на   краю окна  мыши.  Например,  курсор  находится в ряду 1,
колонке 1,   A  GetMieKeyCount  возвращает  Horizontal  =  0,
Vertical = -16,    значит, вы видите, что пользователь двигал
мышь вверх.    Смотрите для уяснения термина "микки" описание
"Микки" в  начале главы OPMOUSE.

Смотрите также

MouseWhereXY     SetMieKeyToPixelRatio
--------------------------------------------------------------------
Функция GetMousePage : Byte;

Назначение

Возвращает номер видеостраницы, которая работает с мышью.

Описание

Эта программа возвращает номер видеостраницы, где  в   данный
момент  находится курсор мыши.    Предупреждение: эта функция
поддерживается не всеми драйверами    мыши.   Для   получения
подробностей смотрите описание MouseStateBufferSize.

Пример

SaveMousePage := GetMousePage;
GetMousePage (NewMousePage);
...
GetMousePage (SaveMousePage);

Сохраняется текущая  видеостраница,  переключается  на  новую
страницу, затем восстанавливается сохраненная страница.

Смотрите также

GetMousePage
---------------------------------------------------------------------
Процедура HardMouseCursor (StartLine, EndLine : Word);

Назначение

Устанавливает использование мышью аппаратного курсора

Описание

Эта программа делает две вещи: выбирает  аппаратный,   а   не
программный курсор мыши (как это   делает   по  умолчанию   и
драйвер мыши), и   позволяет вам определить размеры курсора с
помощью StartLine и  EndLine. Это - программа низкого уровня,
и в большинстве случаев    вам,  наверно,  больше  понравятся
аналогичные программы высокого    уровня из модуля OPMOUSE  :
ClockMouseCursor,   FatMouseCursor,   HiddenMouseCursor   или
FormalMouseCursor. Для   получения   подробностей    смотрите
параграф "Курсор мыши" в начале OPMOUSE

Пример

if Font8x8Selected or (CurrentMode <>7) then
HardMouseCursor (0,7)
else
HardMouseCursor (0,12);

Подобно  программе  BlockMouseCursor,   здесь  будет   выбран
аппаратный курсор блочной формы.

Смотрите также

СlockMouseCursor              NormalMouseCursor
FatMouseCursor                SoftMouseCursor
HiddenMouseCursor
-----------------------------------------------------------------
Процедура HiddenMouseCursor;

Назначение

Устанавливает невидимый курсор мыши

Описание

Эта программа выбирает аппаратный курсор,   который   невидим
(временно).    Это - аналог  процедуры HiddenCursir из OPCRT.
Заметим, что эта  программа   делает   не   то  же самое, что
HideMouse, которая может  прятать   как   аппаратный,  так  и
рограммный курсор.

Смотрите также

HardMouseCursor          HiddenCursor (OPCRT)
---------------------------------------------------------------

Процедура HideMouse;

Назначение

Прячет курсор мыши

Описание

Эта программа прячет курсор мыши, независимо  то  его  вида и
формы. В основном она используется в случаях, когда   имеется
программный курсор, и надо либо осуществить скроллинг экрана,
либо сделать копию экрана (к примеру, программами из OPWINDOW)
для получения подробностей смотрите раздел "Курсор  мыши"   в
начале секции OPMOUSE.

Пример

HideMouse;
write to the screen, scroll display, save an image of display,
{chatever}
ShowMouse;

Смотрите также

InitializeMouse        ShowMouse
-------------------------------------------------------------

Процедура HideMousePrim (var MouseState : Boolean);

Назначение

Сохраняет тип курсора в MouseState и прячет его.

Описание

Эта программа используется вместе с ShowMousePrim. Она   сох-
раняет текущее значение глобальной переменной MouseCursorOn в
MouseState, затем, если нужно, прячет курсор. Последующий вы-
зов ShowMousePrim с параметром MouseState восстановит  курсор
мыши в то состояние (видимое или нет), в котором он находился
перед вызовом HideMousePrim.

Пример

Var MouseState : Boolean;
...
HideMOusePrim(MouseState);
{write to the screen, scroll display, save the screen, whatever}
ShowMousePrim(MouseState);

Прячет курсор мыши, что-то делает с экраном, затем восстанав-
ливает тип курсора, который был перед вызовом HideMousePrim.

Смотрите также

ShowMousePrim
------------------------------------------------------------

Процедура InitializeMouse;

Назначение

Переустанавливает мышь и устанавливает MouseInstalled

Описание

Эта программа переустанавливает мышь и устанавливает   Mouse-
Installed. Хотя она вызывается автоматически при запуске про-
граммы, бывают случаи, когда вам понадобиться включать/выклю-
чать мышь в течение работы программы. В процессе   "переуста-
новки" мыши делается следующее :
. Прячется курсор мыши
. Выбирается программный скрытый курсор мыши с экранной мас-
сой $ffff (DefaultScreenMask) и маской курсора $7700 (Default-
CursorMask).
. Выбирается окно мыши 80 х 25 (в режиме 40 колонок - 40х25)
. Курсор перемещается в центр этого окна.
. Выбирается соотношение "микки/пиксел" : 8,16 ; и
. Запрещается любой установленный пользователем контроль со-
бытий.

Пример

SaveMouseState(MSP,False);
InitializeMouse;
EnableEventHandling;
SlockMouseCursor;
ShowMouse;
...
RestoreMouseState(MSP,False);

Типичный набор операторов TSR, использующего мышь :  сохране-
ние состояния драйвера мыши, переустановка мыши, выбор  аппа-
ратного курсора мыши и установка видимого курсора. Затем вос-
станавливается сохраненное состояние драйвера мыши.

Смотрите также

HideMouse              ShowMouse
------------------------------------------------------------

Функция KeyOrButtonPressed : Boolean;

Назначение

Возвращает True, если нажата клавиша или кнопка мыши.

Описание

Эта программа просто вызывает KeyPressed  и  MousePressed   и
возвращает True, если кто-то из них возвращает True.

Смотрите также

MousePressed
-----------------------------------------------------------

Функция MouseButtonPressed(Button:ButtonStatus;Var Count:Word;
                          Var LastX,LastY:Byte):Boolean;

Назначение

Возвращает True, если нажата определенная кнопка мыши.

Описание

Эта программа позволяет вам определить, была ли нажата опре-
деленная кнопка Button. Если да, то Count  возвратит   число
нажатий (с момента последнего вызова MouseButtonPressed),  а
LastX и LastY возвратят позицию курсора в момент  последнего
нажатия.
Вообще говоря, эту функцию, а также MouseButtonReleased,  мы
рекомендуем вам использовать при контроле событий. Эти   две
функции откроют тогда вам широкие возможности.

Пример

if MouseButtonReleased(LeftButton,Count,LastX,LastY) then
writeln('The left mouse button has been pressed',Count,'times');

Выдает число нажатий левой кнопки мыши

Смотрите также

MouseWhereXY
--------------------------------------------------------------

Функция MouseButtonReleased (Button : ButtonStatus;
            var Count : Word; var LastX,LastY : Byte):Boolean;

Назначение

Возвращает True, если отпущена кнопка Button.

Описание

Эта программа позволяет вам определить, была ли отпущена  оп-
ределенная кнопка Button. Если да, Сount сообщит вам, сколько
раз отпускалась эта кнопка со   времени   последнего   вызова
MouseButtonReleased, а LastX и LastY будут содержать  позицию
курсора мыши на момент, когда кнопка была отпущена  последний
раз.

Пример

if MouseButtonReleased(LeftButton,Count,LastX,LastY) then
writeLn ('The left mouse button has been released',
         Count,'times');

Показывает, сколько раз была отпущена левая кнопка мыши
-----------------------------------------------------------

Процедура MouseGotoXY(MouseX,MouseY : Byte);

Назначение

Устанавливает позицию мыши

Описание

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

Пример

MouseWindow(5,5,75,20);
MouseCotoXY(1,1);

Перемещает курсор мыши в ряд 5, колонку 5.

Смотрите также

MouseWindow
------------------------------------------------------------

Функция MouseInWindow(Xlo,Ylo,XHi,YHi : Byte) : Boolean;

Назначение

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

Пример

MouseWindow(5,5,75,20);
...
if MouseInWindow(1,1,3,3) then {do something}

Проверяет, не находится ли курсор мыши в первых   трех  рядах
и первых трех колонках текущего окна мыши.
------------------------------------------------------------

Функция MouseKeyWord: Word;

Назначение

Возвращает псевдо-скан-код нажатой кнопки мыши

Описание

Эта программа аналогична функции ReadKeyWord из модуля OPCRT.
Предполагая, что вызван EnableEventHandling, программа устана-
вливает цикл ожидания нажатия кнопки, и возвращает    псевдо-
скан-код    из  набора MouseLft...MouseThree, показывающий,
какая кнопка (кнопки) нажата. Если вызова EnableEventHandling
не было, то программа возвратит $FFFF.
Когда нажимается  кнопка  мыши,  MouseKeyWord  делает одну из
двух вещей, в  зависимости  от  текущего значения WaitForBut-
tonReleased.   Если  эта  переменная  установлена в FAlse, то
программа тотчас же     вернет псевдо-скан-код нажатой кнопки
(или комбинации кнопок).     Если True, то MouseKeyWord будет
продолжать высвечивать состояние кнопок мыши до тех пор, пока
все они не будут отпущены. В любом из этих случаев, на выходе
программа возвращает текущее  положение курсора мыши в Mouse-
KeyWordX и MouseKeyWordY.
Смотрите раздел  "Считывание кнопок мыши"   в  начале  секции
OPMOUSE.

Пример

ScanCode: = $FFFF;
repeate
if KeyPressed then
ScanCode: = ReadKeyWord
else if MousePressed then
ScanCode: = ReadKeyWord
until ScanCode <> $FFFF;

Цикл, пока не будет нажата клавиша или кнопка мыши. (Здесь
делается то же, что и в ReadKeyOrButtion).

Смотрите также

EnableEventHandLing           ReadKeyOrButtion
-----------------------------------------------------------------
Функция MousePressed: Boolean;

Назначение

Возвращает True, если в данный момент нажата кнопка мыши

Описание

Эта программа аналогична функции KeyPressed из CRT и  OPCRT.
Она сообщает вам, была ли только что нажата кнопка мыши. Как
и MouseKeyWord, она не работает (то есть всегда   возвращает
False), если  не  был  вызван  EnableEventHadling.  Смотрите
описание MouseKeyWord в качестве примера.

Смотрите также

EnableEventHadling         KeyOrButtionPressed
-------------------------------------------------------------------
Функция MouseStateBufferSize: Word;

Назначение

Сообщает необходимое количество памяти для сохранения текуще-
го  состояния драйвера мыши.

Описание

Эта функция возвращает размер буфера, необходимый для сохра-
нения  состояния драйвера мыши. Она в основном предназначена
для использования  в  TSR  для  обеспечения  поддержки мыши.
Возвращаемые    значения зависят от драйвера, но должны быть
в диапазоне 350-400  (байт). Если мышь не установлена, возв-
ращается 0.
Предупреждение:  Эта  программа использует аппаратную функцию
мыши, поддерживаемую не всеми драйверами. Программа написана
так, что  должен  возвращаться   0,  если  эта  функция   не
поддерживается, но   гарантировать возврат нуля всегда мы не
можем. Таким образом,    Вам следует: 1) Проверить, не равно
ли нулю возвращаемое   значение, 2) проверить, не возвратила
ли функция слишком большое значение (например, 1000),  и  3)
информировать пользователей о возможных проблемах. Если про-
блема возникнет, лучшим ее решением   будет найти подходящий
драйвер.

Пример использования этой программы можно увидеть во вводной
части "Использование мыши в TSR"

Смотрите также

RestoreMouseState            SaveMouseState
---------------------------------------------------------------------
Функция MouseWhereX: Byte;

Назначение

Эта программа аналогична функции CRT и OPCRT WhereX. Она воз-
вращает текущую Х-координату (колонку) курсора мыши, относи-
тельно  текущего  окна.  Чтобы  получить  абсолютное значение
координаты,  используйте MouseWhereXAbs

Смотрите также

MouseWhereXAbs              MouseWindow
MouseWhereY
---------------------------------------------------------------------
Функция MouseWhereXabs: Byte;

Назначение

Возвращает абсолютную Х-координату мыши

Описание

Эта программа аналогична функции WhereXabs  модуля OPCRT.  В
отличие от MouseWhereX, она возвращает абсолютную  Х-коорди-
нату (колонку) курсора мыши.

Смотрите также

MouseWhereX             WhereXabs(OPCRT)
-----------------------------------------------------------------------
Процедура MouseWhereXY (var MouseX, MouseY: Byte; var
                       Status: ButtionStatus);

Назначение

Возвращает координаты мыши и состояние кнопок.

Описание

Эта программа возвращает текущее положение курсора  мыши.  В
координатах текущего окна, MouseX и MouseY. (Чтобы  получить
абсолютные  значения координат мыши, используйте MouseWhere-
XYabs).   Текущее состояние кнопок мыши записывает в Status.
Эта программа  особенно  удобна  в  случаях, когда вам нужно
определить, какая кнопка  (кнопки) нажата, и выполнить опре-
деленные действия, зависящие от положения курсора.

Пример

MouseWhereXY (MouseX, MouseY, Status);
case Status of
LeftButtion: HadleLeftButtion; {Left Buttion pressed}
RigthButtion: HadleRightButtion; {rigth Buttion pressed}
BothButtions: HadleBothButtions; {left and rigth buttions
                                  both pressed}

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

Смотрите также

MouseWhereX                MouseWindow
MouseWhereY
-------------------------------------------------------------------------

Процедура MouseWhereXYabs (var MouseX, MouseY: Byte;
                           var Status: ButtionStatus);

Назначение

Возвращает позицию мыши в абсолютных координатах и состояние
кнопок

Описание
Эта программа идентична MouseWhereXY,  только   возвращаемые
координаты MouseX и MouseY - абсолютно, а не текущие оконные.

Пример

Смотрите пример в описании MouseWhereXY

Смотрите также

MouseWhereXabs                    MouseWhereYabs
MouseWhereXY
------------------------------------------------------------------
Функция MouseWhereY : Byte;

Назначение

Возвращает текущую Y-координату мыши

Описание

Эта программа - аналог функций WhereY модулей CRT  и  OPCRT.
Она     возвращает текущую Y-координату (ряд) курсора мыши в
относительных координатах текущего окна. Чтобы узнать  абсо-
лютную координату,  добавьте MouseYlo к возвращаемому значе-
нию.

Смотрите также

MouseWhereX                MouseWhereXabs
MouseWhereXY
---------------------------------------------------------------------
Функция MouseWhereYabs: Byte;

Назначение

Возвращает текущую абсолютную Y-координату мыши.

Описание

Эта программа - аналог функции  WhereYabs  модуля  OPCRT.  В
отличие   от MouseWhereY, она возвращает абсолютное значение
Y-координаты (ряда) курсора мыши.

Смотрите также

MouseWhereY                   WhereYabs(OPCRT)
--------------------------------------------------------------------
Процедура MouseWindow (XLow, Ylow, XHigh, YHigh: Byte);

Назначение

Устанавливает координаты окна, с которым работает мышь.

Описание

Эта программа подобна процедуре Window модулей CRT и  OPCRT.
Она   устанавливает  минимальные/максимальные вертикальные и
горизонтальная  позиции  экрана  для  курсора мыши. Величины
координат  должны  подчиняться  тем  же  правилам,  что  и в
процедуре  Window :  XLow/YLow  не  должны  быть  больше чем
XHigh/YHigh, XHigh  не должен превышать ScreenWidth, а YHigh
- ScreenHeigth. Если      хотя бы одна из заданных координат
некорректна, программа ничего   делать не будет. Если же все
задано правильно, то курсор мыши будет перемещен внутрь окна
(если перед этим он был не там), а     новые координаты окна
будут храниться в MouseXLo, MouseXH, MouseYLo, MouseYHi.  По
умолчанию размеры окна мыши - целый экран, они устанавливают-
ся при запуске программы. Если в  течении  работы  программы
размеры  окна  меняются, вы можете восстановить их с помощью
FullMouseWindow.

Пример

Window (1,1,80,25);
if MouseInstalled then
MouseWindow (1,1,80,25);

Создаются окно и окно мыши размером 80 х 25. Заметим, что окно
мыши не создается, если MouseInstalled не вернет значение True.

Смотрите также

FullMouseWindow
--------------------------------------------------------------------
Процедура NormalMouseCursor;

Назначение

Устанавливает нормальный размер курсора мыши для текущего
видеорежима.

Описание

Эта программа выбирает аппаратный курсор мыши высотой в  два
пиксела, то есть тип   курсора,   аналогичный   NormalCursor
модуля OPCRT.

Смотрите также

HardMouseCursor               NormalCursor (OPCRT)
-------------------------------------------------------------------
Функция ReadKeyOrButtion: Word;

Назначение

Возвращает код нажатой клавиши или кнопки мыши

Описание

Эта программа предназначена как для внутренних нужд, так   и
для удобства пользователя. Она входит в цикл ожидания нажатия
клавиши или кнопки мыши, а затем возвращает  либо   скан-код
нажатой клавиши, либо псевдо-скан-код нажатой кнопки   мыши.
Допустим, что первой была нажата кнопка мыши, тогда  текущее
положение курсора мыши будет   сохранено  в  MouseKeyWordX и
MouseKeyWordY.
ReadKeyOrButton использует MousePressed и MouseKeyWord   для
получения информации о состоянии кнопок мыши,  поэтому   это
накладывает некоторые ограничения при ее использовании : пе-
ред попыткой получать информацию о кнопках мыши должен  быть
вызван EnableEventHandling.
Смотрите  раздел "Считывание с кнопок мыши"  в начале секции
OPMOUSE.

Пример

Var
I : Word;
...
I:=ReadKeyOrButton;
if lo(I)=0 then
case I of
$0000 : {^Break was pressed};
...
MouseLft : {Left mouse button was pressed};
end;

Считывается код нажатой клавиши или кнопки мыши и выполняется
определенное действие.

Смотрите также

EnableEventHandling       ReadKeyWord(OPCRT)
MouseKeyWord
---------------------------------------------------------------

Процедура RestoreMouseCoordinates(WC : WindowCoordinates);

Назначение

Восстанавливает сохраненные ранее координаты мыши

Описание

Эта программа аналогична программе  RestoreWindowCoordinates
модуля OPCRT, предназначена для  использования  совместно  с
StoreMouseCoordinates в случаях, когда нужно временно  изме-
нить координаты окна мыши, а затем восстановить прежние. Пе-
ременная WC типа WindowCoordinates (описанная в OPCRT),  со-
держит четыре координаты окна мыши.

Пример

Var
WC : WindowCoordinates;
...
StoreMouseCoordinates(WC);
FullMouseWindow;
...
RestoreMouseCoordinates(WC);

Сохраняет текущие координаты окна  мыши,   переустанавливает
окно мыши, затем восстанавливает прежние координаты окна.

Смотрите также

RestoreWindowCoordinates(OPCRT)         StoreMouseCoordinates
------------------------------------------------------------

Процедура RestoreMouseState(var MSP : MouseStatePtr;
                            Deallocate : Boolean);

Назначение

Восстанавливает состояние драйвера мыши, и убирает буфер из
памяти, если необходимо.

Описание

Восстанавливает состояние драйвера мыши. Она   предназначена
в основном для использования в TSR, которые должны поддержи-
вать мышь. MSP является указателем буфера, содержащего восс-
танавливаемые данные. Если Deallocate=True, буфер после вос-
становления данных выгружается из памяти, а  MSP   принимает
значение nil. Если мышь не установлена, или MSP   изначально
равен nil, то RestoreMouseState не будет делать ничего.
Предупреждение : эта программа поддерживается не всеми типа-
ми драйверов мыши. Смотрите описание MouseStateBufferSize.
Для примера, как использовать эту программу, cмотрите раздел
"Использование мыши в TSR".
-------------------------------------------------------------

Процедура SaveMouseState (var MSP : MouseStatePtr;
                          Allocate : Boolean);

Назначение

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

Описание

Эта процедура сохраняет информацию  о  драйвере   мыши.  Она
предназначена для использования в основном  в  TSR,  которые
должны поддерживать мышь. МSP - это указатель  на  буфер,  в
котором содержатся сохраняемые данные.  Если  Allocate=True,
то MSP  после завершения работы этой процедуры будет  указы-
вать на буфер, размещенный в памяти ранее. Если мышь не  ус-
тановлена, или же MouseStateBufferSize возвратит 0 при   за-
просе о необходимом размере буфера, MSP будет установлен   в
nil.
Предупреждение : эта программа поддерживается не всеми типами
драйверов мыши. Смотрите описание MouseStateBufferSize.
Пример использования этой программы смотрите в разделе " Ис-
пользование мыши в TSR."

Смотрите также

MouseStateBuffersize
--------------------------------------------------------------

Процедура SetMickeyToPixelRatio (Horizontal,Vertical:Integer);

Назначение

Устанавливает соотношение микки/пиксел

Описание

Чтобы уяснить термины "микки" и "соотношение  микки/пиксел",
смотрите раздел "Микки" в начале секции OPMOUSE.
Эта программа позволяет вам установить соотношение   "микки/
/пиксел". Хотя соотношения по умолчанию - 8 и 16 (соответст-
венно Horizontal и Vertical) часто приемлемы,   могут   быть
случаи, когда их требуется увеличить или уменьшить. Установ-
ка соотношения 16,32,  к  примеру,  "замедлит"  реагирование
курсора мыши в ответ на ее  движение,  а  4,8 -  "убыстрит",
увеличив чувствительность курсора к движению мыши.
Параметры Horizontal и Vertical обязаны быть целыми  числами
в диапазоне от 1 до 32767 (MaxInt).

Примеры

SetMickeyToPixelRatio(4,8);

Убыстряет реакцию курсора

SetMickeyToPixelRatio(16,32);

Замедляет реакцию курсора
------------------------------------------------------------

Процедура SetMouseЕventHandler(EventMask:MaskEventType;
                               UserRoutine:Pointer);

Назначение

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

Описание

В отличие от часто упоминаемой программы EnableEventHandling
основная цель этой программы - не активизировать  внутренний
контроль событий модуля OPMOUSE (хотя, еcли необходимо,  это
будет сделано), а определить программу, написанную пользова-
телем, которую надо вызывать, когда происходит  определенное
событие. Если UserRoutine - не nil, то он указывает на  про-
цедуру без параметров, объявленную как Far, которая является
глобальной ( то есть, она может не включаться в другую  про-
цедуру). Информацию о случившемся событии Event можно  полу-
чить, проверив глобальные переменные MouseEvent, MouseStatus,
MouseLastX и MouseLastY. Если UserRoutine установлен   в nil
(или EventMask-DisableEventHandler), то любой пользовательс-
кий контроль событий становится невозможным.
ЕventMask - это  байт,   содержимое   которого   информирует
OPMOUSE, когда нужно вызвать вашу программу. К примеру, если
вы хотите вызывать программу, только  когда  нажимается  или
отпускается    левая     кнопка,    то   EventMask     будет
'LeftButtonPressed+LeftButtonReleased'. Если вы хотите отсле-
живать все события мыши, используйте AllMouseEvents.
Заметим, что OPMOUSE выполняет всю "черновую" работу,  необ-
ходимую для контроля событий : сохраняет содержимое регистров
CPU, устанавливает в регистре DS указатель на сегмент данных
вашей программы, вызывает UserRoutine, затем восстанавливает
регистры CPU по завершении контроля событий.
Для более подробной информации смотрите раздел "Контроль со-
бытий мыши" в начале секции OPMOUSE.

Смотрите также

DisableEventHandling            EnableEventHandling
------------------------------------------------------------

Процедура SetMousePage (Page : Byte);

Назначение

Устанавливает страницу видеопамяти, которая работает с мышью.

Описание

Эта программа аналогична программе   SetVisiblePage   модуля
OPCRT, она сообщает драйверу мыши, какая страница видеопамя-
ти используется при работе с мышью.
Предупреждение : эта программа поддерживается не всеми типа-
ми драйверов мыши. Для детальной информации смотрите описание
MouseStateBufferSize.

Пример

SetVisiblePage(3);
SetMousePage(CurrentPage);

Переключает как дисплейный курсор, так и курсор мыши на рабо-
ту с видеостраницей 3. Заметим, что SetMousePage  использует
CurrentPage, если не удается вызвать SetVisiblePage.

Смотрите также

SetMousePage          SetVisiblePage(OPCRT)

------------------------------------------------------------

Процедура ShowMouse;

Назначение

Показывает курсор мыши.

Описание

Эта программа используется для обнаружения   курсора   мыши,
будь то программный или аппаратный курсор. Для более  дета-
льной информации смотрите раздел  "Курсор  мыши"  в   начале
секции OPMOUSE.

Пример

BlockMouseCursor;
ShowMouse;
...
HideMouse;

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

Смотрите также

HideMouse        InitMouse
-------------------------------------------------------------

Процедура ShowMousePrim(MouseState : Boolean);

Назначение

Прячет или высвечивает курсор мыши

Описание

Эта программа предназначена для использования   совместно  с
HideMousePrim. Ее работа заключается в восстановлении состо-
яния курсора мыши (скрытого или видимого), которое было  пе-
ред вызовом HideMousePrim. Конкретнее, она будет делать кур-
сор мыши видимым, ("показывать" его), если MouseState =True,
и прятать его, если MouseState = False.

Пример

Смотрите пример в описании HideMousePrim
------------------------------------------------------------

Процедура SoftMouseCursor (ScreenMask, CursorMask : Word);

Назначение

Устанавливает использование программного курсора мыши.

Описание

Эта программа делает две вещи : 1) Выбирает программный кур-
сор (как и по умолчанию), а не аппаратный курсор, и 2)  Поз-
воляет вам определить по своему виду форму и размер курсора.
Для информации о типах курсоров мыши, о масках экрана и кур-
сора, смотрите раздел "Курсор мыши" в начале секции OPMOUSE.

Примеры

SoftMouseCursor(DefaultScreenMask,DefaultCursorMask);

Выбирает тип курсора по умолчанию : программный курсор,  не-
мерцающий, с цветом, зависящим от текущей позиции.

SoftMouseCursor($00ff,$1f04);

Выбирает мерцающий блочный курсор альтернативного (черный на
белом) цвета.

SoftMouseCursor($0000,$1f04);

Выбирает курсор в форме белого бриллианта (ASCII 4) на синем
фоне.

Смотрите также

HardMouseCursor
--------------------------------------------------------------

Процедура StoreMouseCoordinates (var WC : WindowCoordinates);

Назначение

Cохраняет координаты окна мыши в переменной WC.

Описание

Эта программа аналогична программе    StoreWindowCoordinates
модуля OPCRT, и предназначена для использования совместно  с
RestoreMouseCoordinates в случаях, когда координаты окна мы-
ши надо временно изменить, а затем восстановить  предыдущие.
WC - переменная типа WindowCoordinates (описанного в OPCRT),
будет содержать текущие координаты окна мыши.

Пример

Смотрите пример из описания RestoreMouseCoordinates

Смотрите также

RestoreMouseCoordinates       StoreWindowCoordinates(OPCRT)
