Диалоговое окно
На рис.23.2 показан вид диалогового окна, которое создается и используется в рассматриваемом ниже примере.
Рис.23.2. Диалоговое окно со строкой ввода и кнопками
Если диалог завершен командой «Установить», на экране разворачивается окно, в котором сообщаются полученные из диалогового окна параметры - текст из строки ввода и настройка кнопок. Если диалог завершен командой «Не изменять», окно сообщений содержит строку
Команда 'Не изменять',
если диалог завершен по клавише Esc, на экран не выводится никаких сообщений.
Пример иллюстрирует использование строки ввода, зависимых и независимых кнопок и нестандартных команд.
Для задания начальных параметров и чтения параметров, установленных в результате диалога, используется поле TDialog.Data. Это поле содержит данные, используемые в ходе диалога, в виде записи, поля и тип которой строго соответствуют порядку и типу вставляемых в окно терминальных элементов. В нашем примере (см. текст программы) первым в окно вставляется статический текст, однако этот терминальный элемент не имеет параметров, которые можно было бы изменить в ходе диалога, поэтому в записи Data ему не отводится место. Второй по счету в окно вставляется строка ввода TInputLine. Этот объект характеризуется длиной L строки, указываемой вторым параметром обращения к TInputLine.Init, поэтому для него в Data выделяется поле, длинойL+1 байт. Каждому кластеру с кнопками выделяется поле WORD, что дает возможность задать в кластере до 16 независимых кнопок и до 65536 зависимых: каждая независимая кнопка связана с соответствующим разрядом 16-битного поля (первая кнопка - с младшим разрядом), а каждой зависимой кнопке соответствует свое число (первой кнопке соответствует число 0, второй - 1 и т.д.). Установка данных в поле TDialog.Data осуществляется методом TDialog.SetData, получить данные после диалога можно с помощью метода TDialog.GetData.
{$Х+}
Uses Objects , App , Drivers , Dialogs,Menus,Views,MsgBox ;
type
MyApp = object (TApplication)
Procedure InitStatusLine; Virtual;
Procedure HandleEvent (var Event: Tevent) ; Virtual;
Procedure GetDialog;
end;
PMyDialog = TMyDialog;
TMyDialog = object (TDialog)
Procedure HandleEvent (var Event: Tevent); Virtual;
end;
const
cm0 = 200;
cm1 = 201;
cm2 = 202;
{-------------------}
Procedure MyApp.InitStatusLine;
{Создает строку статуса}
var
R: TRect;
begin
GetExtent(R) ;
R.A.Y := pred(R.B.Y) ;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef (0,$FFFF,
NewStatusKey ( ' ~Alt-X~ Выход' , kbAltX, cmQuit,
NewStatusKey ( ' ~F1~ Вызов окна', kbF1,cm0, NIL)),
NIL) ) )
end {MyApp.InitStatusLine} ;
{-----------------}
Procedure MyApp.HandleEvent;
{Обрабатывает нестандартную команду cm0}
begin
Inherited HandleEvent (Event) ;
case Event . Command of
cm0 : GetDialog
else
ClearEvent (Event)
end
end {MyApp . HandleEvent} ;
{------------------}
Procedure MyApp.GetDialog;
{Создает и использует диалоговое окно}
var
R: TRect; {Координаты элементов}
D: PMyDialog; {Диалоговое окно}
I: PInputLine; {Строка ввода}
RB: PRadioButtons; {Зависимые кнопки}
СВ: PCheckBoxes; {Независимые кнопки}
s : String; {Для вывода сообщения}
const
L = 120; {Длина строки ввода}
type
TDialogData = record {Параметры диалогового окна}
I_Data: String [L]; {Текст в строке ввода}
CB_data: Word; {Независимые кнопки}
RB_Data: Word {Зависимые кнопки}
end;
const
st: array [0..2] of String = ('Первое','Второе','Третье ');
Data : TDialogData =( {Начальные параметры диалога}
I_Data : 'Начальный текст';
CB_Data: 3; {1-я и 2-я кнопка}
RB_Data: 2); {3-е продолжение}
begin
R.Assign(5,3,75,18); {Координаты диалогов ого окна}
D := New(PMyDialog,Init(R,'Пример диалогового окна'));
with D do
begin
R.Assign(1,1,69,3);
Insert(New(PStaticText, {Вставляем статический текст}
Init(R,#3'Это статический текст')));
R.Assign(20,3,60,4) ;
I := New(PInputLine, Init(R, L));
Insert (I); {Вставляем строку ввода}
R.Assign(1,3,20,4);
Insert(New(PLabel, {Вставляем метку строки ввода}
Init(R,'~l~ Строка ввода:',I)));
R.Assign(60,3,62,4);
Insert(New(PHistory, {Вставляем список ввода}
Init(R,I,0))) ;
R.Assign(10,6,30,9) ;
CB := New (PCheckBoxes, Init(R,
NewSItem('Первая кнопка',
NewSItem('Вторая кнопка',
NewSItem('Третья кнопка', NIL)))));
Insert(CB); {Вставляем независимые кнопки}
R.Assign(6,5,30,6);
Insert(New(PLabel, {Вставляем метку кнопок}
Init(R,'~2~ Независимые кнопки',CB)));
R.Assign(40,6,63,9);
RB := New(PRadioButtons, Init(R,
NewSItem('Первое продолжение',
NewSItem('Второе продолжение',
NewSItem('Третье продолжение', NIL)))));
Insert(RB); {Вставляем зависимые кнопки}
R.Assign(36,5,63,6) ;
Insert(New(PLabel, {Вставляем метку кнопок}
Init(R,'~3~ Зависимые кнопки',RB)));
R.Assign(14,11,32,13) ;
Insert(New(PButton, {Вставляем кнопку "Установить"}
Init(R,'~4~ Установить',cm1,bfNormal)));
R.Assign(40,11,58,13);
Insert (New(PButton, {Вставляем кнопку "Не изменять"}
Init(R,'~5~ He изменять',cm2,bfNormal)));
SetData(Data) {Устанавливаем начальные значения}
end;
{Помещаем окно на экран и получаем команду завершения}
case DeskTop.ExecView(D) of
cm1:
begin {Была команда "Установить":}
D.GetData(Data); {Получаем новые значения}
with Data do
begin {Готовим сообщение}
s := #3'Параметры диалогового окна:'+
#13'Текст :'+I_Data+#13'Кнопки: ';
if CB_Data and 1 <> 0 then
s := s+' Первая';
if CB_Data and 2 <> 0 then
s := s+' Вторая';
if CB_Data and 4 <> 0 then
s := s+' Третья';
s :=s+#13'Продолжение: '+st[RB_Data]
end
end ;
cm2: s := #3'Команда "Не изменять"';
else
s := ' ' ;
end; {case}
if s <> '' then
MessageBox(s,NIL,0)
end {MyApp.GetDialog};
{--------------}
Procedure TMyDialog.HandleEvent;
{Обрабатывает нестандартные команды cm1 и cm2}
begin
Inherited HandleEvent(Event);
if Event.What = evCommand then
case Event.Command of
cm1:EndModal (cm1);{Завершить с командой cm1}
cm2:EndModal (cm2){Завершить с командой cm2}
end;
ClearEvent (Event) {Очистить другие события}
end {TMyDialog.HandleEvent} ;
{---------------}
var
P: MyApp;
begin
P.Init;
P. Run;
P . Done
end.
Для использования нестандартных команд cm0, cm1 и cm2 перекрываются обработчики событий строки статуса и диалогового окна. Чтобы завершить диалог с выдачей нестандартной команды, в обработчике событий окна вызывается метод EndModal, в результате чего метод ExecView возвращает значение соответствующей команды. Заметим, что стандартная для Turbo Vision команда cmCancel (закрыть окно по клавише Esc) обрабатывается стандартным методом TDlalog.HandleEvent.