Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лабораторные на Pasca (Кудрявцев)l

.pdf
Скачиваний:
32
Добавлен:
18.03.2015
Размер:
1.63 Mб
Скачать

Диалоговые окна

303

 

 

Статический текст

Добавим, прежде всего, в диалоговое окно некоторое сообщение. Для этого нам придется использовать объект TStaticText, который является потомкомот TView. Это видимый элемент, который просто отображает строку, переданную в него. Строка представляет собой слово, располагаемое внутри прямоугольника видимого элемента с переносом. Текст будет центрироваться, если строка начинается с Ctr-C, она может быть разбита с помощью Ctr-М. По умолчанию

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

procedure TMyApp.NewDialog; var

Bruce: PView; Dialog: PDemoDialog; R: TRect;

C: Word; s: string; begin

R.Assign(20, 6, 60, 19);

Dialog := New(PDemoDialog, Init(R, 'Demo Dialog')); s:='Это простое диалоговое окно';

with Dialog^ do begin

R.Assign(6, 6, 35, 7); Bruce:=New(PStaticText,Init(R,s)); Insert(Bruce);

end;

C := DeskTop^.ExecView(Dialog); Dispose(Dialog, Done);

end;

Кнопки

Кнопки это объекты TButton. Они работают во многом аналогично элементам строки статуса: это закрашенная область с текстовой меткой и, если Вы отметите ее, она генерирует команду. На экране видна тень от кнопки, так что при ее нажатиисоздается эффект движения. Большинство диалоговых окон имеет, по крайней мере, одну или две кнопки. Наиболее общие кнопки ОК (обозначающая «Я все сделал». Вы можете закрыть диалоговое окно и использо- вать результаты) и Cancel (означающая «Я хочу закрыть диалоговое

304

Лабораторная работа № 27

 

 

окно и игнорировать изменения, сделанные в нем»). Кнопка Cancel по умолчанию генерирует ту же команду cmCancel, что и закры- вающая кнопка.

Модуль Dialogs определяет пять стандартных диалоговых команд, которые могут быть связаны с TButton: cmOK, cmCancel, cmYes, cmNo, cmDefault. Первые четыре команды также закрывают диало- говое окно, вызывая метод EndModel из TDialog, который восстанав- ливает предыдущий модальный видимый элемент в статус модаль- ности. Естественно, что кнопки могут использоваться и для генера- ции команд, специфичных для Вашей программы.

Из предыдущего примера должно быть ясно, как следует модифи- цировать метод TMyApp.NewDialog, для того, чтобы добавить в диа- логовое окно кнопки OK и Cancel:

procedure TMyApp.NewDialog; var

Bruce: PView; Dialog: PDemoDialog; R: TRect;

C: Word; s: string; begin

R.Assign(20, 6, 60, 19);

Dialog := New(PDemoDialog, Init(R, 'Demo Dialog')); s:='Это простое диалоговое окно';

with Dialog^ do begin

R.Assign(6, 6, 35, 7); Bruce:=New(PStaticText,Init(R,s)); Insert(Bruce);

R.Assign(15, 10, 25, 12);

Insert(New(PButton, Init(R, '~O~k', cmOK, bfDefault))); R.Assign(28, 10, 38, 12);

Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal))); end;

C := DeskTop^.ExecView(Dialog); Dispose(Dialog, Done);

end;

Как Вы видите, создание кнопки требует задание четырех парамет- ров в конструкторе Init:

Диалоговые окна

305

 

 

1.Область, закрываемая кнопкой (не забудьте оставить место для тени!).

2.Текст, который появляется в кнопке.

3.Команда, связанная с кнопкой.

4.Флаг типа кнопки (нормальная или по умолчанию).

Заметим, что нет смысла окрашивать букву Св слове Cancel”, поскольку уже определена горячая клавиша (Esc) для этой коман- ды.

Создавая кнопку, Вы устанавливаете ее флаг bfNormal или bfDefault. Большинство кнопок являются нормальными (bfNormal). Кнопка, помеченная как bfDefault, будет кнопкой по умолчанию, то есть она «нажимается», когда Вы нажимаете клавишу Enter. Turbo Vision не проверяет, используете ли Вы только одну кнопку по умолчанию, – за это отвечаете Вы. Если Вы назначили более чем одну кнопку по умолчанию, результат будет непредсказуемым. Обычно кнопка ОК в диалоговом окне это кнопка по умолчанию, и пользователь про- сто нажимает Enter, чтобы закрыть диалоговое окно и использовать сделанные изменения.

Когда диалоговое окно открыто, один из элементов управления всегда подсвечен это активный элемент управления. Активизация

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

строку ввода, только если она активна.

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

него представления объекты поддерживаются в диалоговом окне в циклически связанном списке, с последним вставленным элемен- том, связанным с первым.

По умолчанию активизируется последний вставленный объект. Вы

можете активизировать другой элемент управления либо используя метод SelectNext диалогового окна, либо прямо вызывая метод

306

Лабораторная работа № 27

 

 

Select элемента управления. SelectNext позволяет Вам передвигать- ся вперед или назад по списку элементов управления. SelectNext(False) передвигает Вас вперед по циклическому списку (в порядке Tab); SelectNext(True) передвигает в обратном направлении.

Создание кластеров

Обычно выбор, который Вы хотите предложить пользователю в диалоговом окне, это не просто выбор, обрабатываемый индивиду- альными кнопками. Turbo Vision обеспечивает несколько полезных стандартных функций управления для выбора ряда опций. Две наи- более полезных это зависимые и независимые кнопки. Эти две функции в основном идентичны за тем исключением, что Вы може- те задать несколько независимых, но только одну зависимую кноп- ку. Идентичность зависимых и независимых кнопок связана с тем, что они являются потомками одного и того же объекта TClaster. Для того, чтобы ознакомиться с концепцией зависимых и независимых кнопок, Вы можете посмотреть меню Options в интегрированной среде Turbo Pascal. Многие диалоговые окна в этом меню исполь- зуют такие кнопки.

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

R.Assign(3, 3, 18, 6);

Bruce := New(PCheckBoxes, Init(R, NewSItem('~H~varti', NewSItem('~T~ilset', NewSItem('~J~arlsberg',

nil)))

));

Insert(Bruce);

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

Диалоговые окна

307

 

 

лей на строки, завершаемый nil, которые будут показаны в следую- щих независимых кнопках).

Приведенный код создает набор независимых кнопок с тремя вы- борами. Заметьте, что Вы не дали указание по установке каждого элемента в списке. По умолчанию они все не установлены. Часто Вам потребуется установить все или некоторые элементы незави- симых кнопок. Turbo Vision предоставляет способ легко устанавли- вать и сохранять значения (его мы рассмотрим ниже).

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

Добавим теперь набор из трех зависимых кнопок. Для этого пона- добится следующий код:

R.Assign(22, 3, 34, 6);

Bruce := New(PRadioButtons, Init(R, NewSItem('~S~olid', NewSItem('~R~unny', NewSItem('~M~elted',

nil)))

));

Insert(Bruce);

Главное отличие между зависимыми и независимыми кнопками в том, что Вы можете выбрать только одну зависимую кнопку в

группе и что первый элемент в группе зависимых кнопок выбран по умолчанию.

Поскольку Вам не требуется знать состояние каждой зависимой кнопки (достаточно знать, какая именно кнопка выбрана), данные о зависимых кнопках не побитовые. Это означает, что Вы можете ис- пользовать более 16 зависимых кнопок. Данные о зависимых кноп- ках хранятся в слове и в Вашем распоряжении 65536 зависимых кнопок на один кластер. Значение 0 указывает, что выбрана первая зависимая кнопка, 1 – вторая и так далее.

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

308

Лабораторная работа № 27

 

 

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

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

Чтобы пометить независимые кнопки, добавьте следующий код сразу после вставки независимых кнопок в диалоговое окно:

R.Assign(2, 2, 10, 3);

Insert(New(PLabel, Init(R, 'C~h~eeses', Bruce)));

Вы теперь можете активизировать набор независимых кнопок, от- метив слово Cheeses (или нажав Alt + h). Это слово предоставляет информацию и об элементах в данном окне. Аналогично добавля- ется метка к зависимым кнопкам:

R.Assign(21, 2, 33, 3);

Insert(New(PLabel, Init(R, 'Cons~i~stency', Bruce)));

Строка ввода

Существует еще один тип элемента управления, который Вы може- те добавить в диалоговое окно TInputLine, называемый строкой ввода. Работа строки ввода чрезвычайно сложна, но с Вашей точки зрения как программиста, это очень простой для использования объект.

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

R.Assign(3, 8, 37, 9);

Bruce := New(PInputLine, Init(R, 34)); Insert(Bruce);

R.Assign(2, 7, 24, 8);

Insert(New(PLabel, Init(R, 'Delivery instructions', Bruce)));

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

Диалоговые окна

309

 

 

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

Установка и получение данных

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

Вы должны иметь возможность:

1)установить начальные значения элементов управления при открытии диалогового окна;

2)прочитать значения, когда диалоговое окно закрывается.

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

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

Для копирования данных в видимый элемент и из него использу- ются методы SetData и GetData. Каждый видимый элемент имеет эти методы. Когда группа (такая как TDialog) инициализируется с помощью вызова SetData, она передает данные дальше, вызывая методы SetData для каждого из его подэлементов. (Заметим, что ко- гда Вы вызываете SetData для группы, Вы передаете ему запись данных, которая содержит данные для каждого из видимых элемен- тов в группе. Вам необходимо расположить данные для них в том же порядке, в каком они были вставлены в группу).

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

310

Лабораторная работа № 27

 

 

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

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

После выполнения диалогового окна Ваша программа должна убе- диться вначале, что диалоговое окно не было отменено, затем вы- звать GetData для передачи информации в Вашу программу. Так в Вашем примере Вы инициализируете по порядку кластер незави- симых кнопок, метку, кластер зависимых кнопок, метку, строку ввода до 128 символов, метку и две кнопки (ОК и Cancel). Таблица 6.1 приводит все требуемые для этого данные.

 

Таблица 6.1

Данные для элементов управления диалогового окна

 

 

Элементы управления

Требуемые данные

 

 

Независимые кнопки

Word

Метка

Нет

Зависимые кнопки

Word

Метка

Нет

Строка ввода

string[128]

Метка

Нет

Кнопка

Нет

Кнопка

Нет

 

 

Видимые элементы, которые не имеют данных (такие, как метки и кнопки), используют метод GetData, который они наследуют от TView и который ничего не делает. Это означает, что когда Вы по-

Диалоговые окна

311

 

 

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

Вы можете установить запись данных для диалогового окна в гло- бальном типе:

type

DialogData = record CheckBoxData: Word; RadioButtonData: Word; InputLineData: string[128];

end;

Теперь все, что Вам необходимо сделать, – это инициализировать запись при запуске программы (например, в MyApp.Init), установить данные, когда Вы входите в диалоговое окно, и прочитать их, когда диалоговое окно успешно закрыто. Это проще сказать в Паскале, чем по-русски! После того, как Вы объявите тип, Вы объявляете глобальную переменную:

var

DemoDialogData: DialogData;

затем добавляете одну строку до выполнения диалогового окна и одну после:

Dialog^.SetData(DemoDialogData);

C := DeskTop^.ExecView(Dialog);

if C <> cmCancel then Dialog^.GetData(DemoDialogData);

и добавляете шесть строк в метод TMyApp.Init, чтобы установить на- чальные значения для диалогового окна:

with DemoDialogData do begin

CheckboxData := 1;

RadioButtonData := 2; InputLineData := 'Phone home.';

end;

Сейчас все изменения, которые Вы сделаете в диалоговом должны сохраниться, когда Вы снова его откроете, если только клавиша Cancel не отменила диалог.

312

Лабораторная работа № 27

 

 

Другие элементы управления

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

Просмотр списка. TListViewer выводит список в одну или несколь- ко колонок, и пользователь может выбрать элемент из этого списка. TListViewer может взаимодействовать с двумя полосами скроллинга. Он предназначен для построения блока и не используется отдельно. Он может обрабатывать список, но сам списка не содержит. Его аб- страктный метод GetText загружает элементы списка для его метода Draw. Наследник TListViewer должен перекрывать GetText для за- грузки актуальных данных.

Окно списка. TListBox наследуется от TListViewer. Он владеет TCollection, который должен быть указателем на строки. TListBox на- следует только одну полосу скроллинга. Примером окна списка яв- ляется список выбора файлов в интегрированной среде Turbo Pascal. При получении и установке данных окна списка удобно пользоваться типом записи TListBoxRec, который хранит указатель на список строк и слово, указывающее на текущий выбранный эле- мент списка.

История. THistory реализует объект, который работает со строкой ввода и связанным окном списка. Нажимая на символ стрелки, стоящей после строки ввода, пользователь вызывает список преды- дущих значений для этой строки и может выбрать любой из них. Это предотвращает повторный набор.

Стандартные диалоговые окна. Модуль StdDlg содержит предо-

пределенное диалоговое окно, называемое TFileDialog. Вы исполь- зуете это окно в интегрированной среде, когда открываете файл. TFileDialog использует ряд других объектов из модуля StdDlg, кото- рые могут быть полезны:

TFileInputLine=object(TInputLine)

TFileCollection=object(TSortedCollection)

TSortedListBox=object(TListBox)

TFileList=object(TSortedListBox) TFileInfoPane=object(TView).