18.5. Команды Турбо Паскаль В.В. Фаронов

Поскольку события обычно связаны с какими-то действиями пользователя программа должна, как правило, реагировать на эти действия изменением видимого изображения. С точки зрения Turbo Vision это означает, что обработчики событий должны преобразовывать события в действия, связанные с реакцией на произошедшее событие. Для реализации этих действий в Turbo Vision предусмотрены команды.
Команда - это просто целое число без знака, кодирующее определенную последовательность действий. В Turbo Vision предусмотрен ряд стандартных команд для реализации многих стандартных действий. Например, команда cmQuit реализует завершение работы программы и выход в ДОС, cmClose закрывает активное окно, cmZoom распахивает окно на весь экран или возвращает ему прежние размеры и т.д. Идентификаторы стХХХХ являются идентификаторами предопределенных констант, которые кодируют стандартные действия (например, cmQuit = 1, cmZoom = 5 и т.д.).
В своей программе Вы можете наряду со стандартными командами определить и использовать собственные команды для реализации специфических действий. Для этого необходимо создать свою константу-команду и в нужный момент сообщить видимым элементам о необходимости выполнить ее. Разумеется, Вы можете использовать произвольный идентификатор для вновь определяемой команды, однако Ваша программа станет намного понятнее, если при образовании новых идентификаторов Вы будете следовать каким-то правилам. В этом смысле использование префикса cm в идентификаторах новых команд кажется вполне логичным.
18.5.1. Преобразование активных событий в команды
Как указать на необходимость выполнения команды? Для этого в Turbo Vision Вы просто создаете событие-команду (evCommand), в поле Command которой помещаете код нужной команды. Например:
const
cmMyCommand =100;
.....
{Ниже показан фрагмент обработчика событий:}
Event.What := evCommand; {Определяем событие-команду}
Event.Command := cmMyCommand; {Указываем код команды}
Event.InfoPtr := NIL; {Признак активного события}
PutEvent(Event); {Создаем событие}
В этом фрагменте событие-команда создается обращением к методу PutEvent. Заметим, что поле Event.InfoPtr должно содержать NIL, если событие активно; если событие уже обработано, для его очистки используется стандартный метод ClearEvent, который помещает в поле What признак evNothing, а в поле InfoPtr - указатель @Self (указатель на таблицу виртуальных методов объекта). Подробнее об использовании поля Event.InfoPtr см.п.18.7.
Вновь созданное событие вернется модальному элементу, который должен знать, как его обрабатывать. Например, часто событие-команда создается обработчиком событий строки статуса как реакция на нажатие предусмотренной в этой строке командной клавиши или отметку мышью соответствующего поля. В этом случае обработчик событий программы может иметь такой вид:
Procedure MyProgram.HandleEvent(var Event);
.....
begin
Inherited HandleEvent(Event);
case Event.What of
evCommand:
begin {Обработать команды:}
case Event.Command of
cmMyCommand: MyProcedure; {Выполнить действия, связанные с командой cmMyCommand}
.....
else
exit {He обрабатывать непредусмотренные команды}
end; {case}
ClearEvent(Event) {Очистить событие}
end;
.....
end;
Часто модальным элементом является диалоговое окно с несколькими кнопками. Если Вам необходимо связать с кнопками свои команды и получить выбранную в диалоге команду, Вы можете закрыть окно с помощью вызова EndModal, передав этому методу в качестве параметра код команды.
В следующем примере создается диалоговое окно с двумя кнопками. При нажатии кнопки «Команда cmPrint» окно закроется и на экран будет выведена строка
Действие команды cmPrint
Если нажать кнопку «Выход» или закрыть окно клавишей Esc, эта строка не появится.
Uses CRT,App,Dialogs,Objects,Drivers,Views;
type
PProg = ^TProg;
TProg = object (TApplication)
Constructor Init;
end;
PDial = ^TDial;
TDial = object (TDialog)
Procedure HandleEvent(var Event: TEvent); Virtual;
end;
const
cmPrint = 100; Constructor TProg.Init;
var
R: TRect;
Dia: PDial;
begin
Inherited Init;
R.Assign(20,9,60,17);
Dia := New(PDial, Init(R,''));
R.Assign(3,4,22,6) ;
DiaA.Insert(New(PButton,
Init(R,'Команда cm~P~rint',cmPrint,bfDefault)));
R.Assign(23,4,35,6);
DiaA.Insert(New(PButton,Init(R,'Выход',cmCancel,bfNormal)));
if ExecView(Dia) = cmPrint then
begin
{Вывод сообщения "в лоб", с помощью стандартных средств Турбо Паскаля. В.- TurboVision есть более удобные способы вывода сообщений}
GotoXY(30,12);
TextColor(Black);
TextBackground(White);
Write (' Действие команды cmPrint ')
end
end; {TProg.Init}
Procedure TDial.HandleEvent(var Event: TEvent);
begin
Inherited HandleEvent(Event);
if (Event.What = evCommand) and
(Event.Command = cmPrint) then EndModal(cmPrint)
end; {TDial.HandleEvent)
var
Prog: TProg;
begin
Prog.Init;
Prog.Run;
Prog.Done
end.
В обработчике событий диалогового окна TDial.HandleEvent вначале вызывается стандартный обработчик TDialog.HandleEvent. Это дает возможность кнопке «Команда cmPrint» преобразовать событие, связанное с ее выбором, в команду cmPrint. Вновь созданное событие возвращается обработчику TDialHandleEvent, т.к. именно он является обработчиком событий модального элемента. Возвращаемая модальным элементом команда служит значением стандартной функции ExecView. Для упрощения программы вывод сообщения реализуется стандартными средствами Турбо Паскаля. В Turbo Vision имеется процедура MessageBox, обеспечивающая более удобный вывод сообщений.
18.5.2. Запрещение и разрешение команд
В качестве значения константы-команды можно использовать любое число в диапазоне от О до 65535, однако следует учесть, что диапазоны 0...99 и 2S6...999 Turbo Vision резервирует для стандартных команд и их не следует использовать для определения команд пользователя. Два диапазона зарезервированных команд выбраны потому, что команды с кодами 0...255 можно временно запретить, в то время как остальные команды запретить невозможно. Для запрещения или разрешения команд используется глобальный тип TCommandSet, представляющий собой множество чисел в диапазоне 0...256 (мощность множеств в Турбо Паскале не может превышать 256, вот почему запретить можно только первые 256 команд). Команды запрещаются обращением к методу DisableCommands, а разрешаются обращением к EnableCommands. Диалоговые элементы, связанные с запрещенными командами, выделяются оттенком и их нельзя выбрать мышью или командными клавишами. Например, если в конструкторе TProgJnit (см. предыдущий пример) перед оператором
if ExecView(Dia) = cmPrint then
вставить оператор
DisableCommand([cmPrint]);
кнопка «Команда cmPrint» будет выведена цветом фона окна и станет недоступна для диалога.