Формирование строки статуса
Стандартный вид экрана, показанный на рис. 15.1, можно изменять. Попробуем придать ему некоторый специфический для нашей программы вид. Например, заменим в строке статуса стандартное сообщение
Alt-X Exit
на русифицированное
Alt-X Выход
Таким образом, нам необходимо модифицировать стандартное поведение объекта Notebook. Для этого мы должны отыскать в типе TApplication метод, ответственный за создание строки статуса. Если мы обратимся к прил.П6, то обнаружим, что объект типа TApplication содержит методы Init и Done, с помощью которых создаются и уничтожаются экземпляры объекта, но в нем нет метода, ответственного за строку статуса. Однако из таблицы наследования нетрудно определить, что этот метод (InitStatusLine) он наследует от своего родителя TProgram. Как изменить работу метода? В рамках объектно-ориентированной библиотеки для этого поступают следующим образом: объявляется объект-потомок от стандартного объекта, поведение которого необходимо изменить, и в новом объекте описывается свой метод, ответственный за это поведение.
Изменим программу следующим образом;
Uses Арр, Objects, Menus, Drivers, Views;
type
TNotebook = object (TApplication) {Создаем объект-потомок от TApplication}
Procedure InitStatusLine; Virtual; {Перекрываем старый метод InitStatusLine новым}
end;
{-----------}
Procedure TNotebook. InitStatusLine;
{Описание нового метода, с помощью которого создается строка статуса}
var
R: TRect; {Границы строки статуса}
begin
GetExtent (R) ; {Получаем в R координаты всего экрана}
R.A.Y := pred(R.B.Y) ; {Помещаем в R координаты строки статуса}
{Создаем строку статуса:}
StatusLine := New(PStatusLine, Init(R,
{Определяем один вариант строки статуса:}
NewStatusDef (0, $FFFF, {Устанавливаем для этого варианта максимальный диапазон контекстной справочной службы}
{Определяем единственную клавишу Alt-X: }
NewStatusKey('~Alt-X~ Выход' , kbAltX, cmQuit,
NIL), {Нет других клавиш}
NIL) {Нет других строк статуса}
))
end; {TNotebook. InitStatusLine}
{---------}
var
Notebook: TNotebook;{Изменен тип переменной!}
begin
Notebook. Init;
Notebook. Run;
Notebook. Done
end .
Как видим, программа сразу же усложнилась. Во-первых, в ней используются идентификаторы, которые определены в других модулях Turbo Vision, - эти модули мы перечислили в предложении Uses. Во-вторых, нам потребовалось объявить новый объект TNotebook как потомок от объекта TApplication. Объект-потомок наследует от своего объекта-родителя все поля и методы и при необходимости может их дополнять своими полями и методами, а также перекрывать методы родителя. Как раз для того, чтобы перекрыть унаследованный от TProgram стандартный метод InitStatusLine, ответственный за создание строки статуса, нам и понадобилось объявление нового типа TNotebook. Строка
Procedure InitStatusLine; Virtual;
в объявлении этого типа указывает, что новый объект будет пользоваться одноименным, но иным, чем объект-родитель, методом. Возможность замены методов на одноименные, но с другим содержанием называется полиморфизмом.
Процедура TNotebookJnitStatusLine раскрывает суть нового метода. В ней используется обращение к методам NewStatusDef vi NewStatusKey, с помощью которых создается динамический объект типа TStatusLine. Программа TApplication обращается к методам этого объекта для обслуживания строки статуса.
Turbo Vision позволяет определять несколько вариантов строки статуса. Каждый вариант создается с помощью метода NewStatusDef. В зависимости от текущего состояния программы (от контекста программы) Turbo Vision автоматически помещает в строку статуса нужный вариант. Так как в нашей программе используется единственный вариант строки статуса, мы указали максимально возможный диапазон контекста программы при обращении к методу NewStatmDef.
С помощью метода NewStatusKey в строке статуса определяется очередная командная клавиша. При обращении к методу сначала указывается текст, высвечиваемый в строке статуса, причем символом «~» выделяется та часть сообщения, которая будет подсвечена в строке статуса другим цветом: таким способом в Turbo Vision указываются командные клавиши. Идентификатор kbAltX задает комбинацию клавиш, а cmQuit - связанную с ней команду.
В программе объявляется переменная R типа TRect. С помощью такого типа переменных программист задает координаты прямоугольного участка экрана. Эта переменная необходима нам для указания того места на экране, где будет помещено сообщение
Alt-X Выход
определяющее командные клавиши Alt-X. Для правильного задания этих координат мы использовали два предложения:
GetExtent(R);
R.A.Y := pred(R.B.Y);
В первом вызывается стандартный метод Turbo Vision GetExtent, с помощью которого в R помещаются координаты доступной в данный момент части экрана. Во втором - номер той строки (строки статуса), куда будет выводиться сообщение. В Turbo Vision тип TRect объявляется в виде следующей записи:
type
TRect = record
A: record {Координаты верхнего левого угла}
X: Byte; Y: Byte
end;
В: record {Координаты правого нижнего угла}
X: Byte; Y: Byte
end
end;
Таким образом, второе предложение лишь уменьшает на единицу вертикальную координату самой нижней доступной строки и устанавливает полученное значение в поле R.A. Y (это поле задает вертикальную координату верхнего левого угла прямоугольного участка). Заметим, что в Turbo Vision минимальные координаты задаются значением 0, в то время как в стандартном модуле CRT Турбо Паскаля минимальные координаты имеют значение 1.
Обратите внимание на характерный прием, широко используемый в Turbo Vision: при обращении к методам NewStatusDef и NewStatusKey последним параметром указывается переменная типа Pointer. Внутри методов эта переменная трактуется как ссылка на новый метод, что позволяет организовать цепочку последовательных определений. Вложенная последовательность вызовов заканчивается зарезервированной константой NIL, указывающей на конец цепочки. Если бы мы, например, захотели добавить в строку статуса определение клавиши F10, связав ее с закрытием активного окна, мы могли бы использовать такую конструкцию:
NewStatusDef(0, $FFFF,
NewStatusKey('~Alt-X~ Выход', kbAltX, cmQuit,
NewStatusKey('~F10~ Закрыть окно', kbFl0, cmClose,
NIL)), {Нет других клавиш}
NIL) {Нет других определений}
Описанный пример позволяет нам сделать очень важный вывод:
Чтобы модифицировать стандартное поведение объекта, необходимо создать объект-потомок от этого объекта и перекрыть в нем нужный метод.