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

Технологии программирования. Программирование графических интерфейс

.pdf
Скачиваний:
3
Добавлен:
15.11.2022
Размер:
2.24 Mб
Скачать

clr – цвет, которым закрашивается сектор; angle1 – начальный угол;

angle2 – конечный угол; msg – текст в секторе.

5. Откомпилировать и выполнить приложение. Должно получиться изображение, подобное показанному на рис. 11.3.

Рис. 11.3

6.Изменить высоту и ширину компонента PaintBox1 и установить их неодинаковыми. Посмотреть, к чему это приведет.

7.Добавть в диаграмму еще один сектор.

Вопросы для самоконтроля

1.Какие компоненты, свойства, методы и обработчики событий используются при программировании графики?

2.Как использовать графический редактор для создания изображения bmp-файла?

3.Каким образом компонент TImage связывается с bmp-

файлом?

4.Как показать и скрыть изображение?

181

5.Как создать таймер на этапе разработки приложения? Как создать таймер на этапе выполнения программы?

6.Как уничтожить таймер?

7.Как установить начальную частоту таймера?

8.Как изменить частоту таймера на этапе выполнения программы? В обработчике какого события можно изменить частоту таймера?

9.Какие способы изображения графических фигур вы

знаете?

10.Какие объекты необходимо создать для рисования? Как они создаются?

11.Объект какого класса играет роль «холста»?

12.Какой объект содержит инструменты рисования (кисть, перо, шрифт)?

13.В обработчике какого события можно выполнить рисование?

14.НачтовлияетсвойствоTransparent компонентаTLabel?

15.Какое свойство компонента TImage содержит изображение?

16.Что надо сделать, если вы хотите выделить на форме несколько областей рисования?

17.Каким образом заставить изображение перемещаться по экрану?

18.КакимобразомможноинициироватьсообщениеOnPaint?

19.Как обработать сообщения от клавиатуры?

20.Перечислите все события, связанные с клавиатурой. От какого класса компоненты наследуют эти события?

21.Напишите фрагмент программы для определения десятичного кода нажатой клавиши.

22.Напишите фрагмент программы, обрабатывающей нажатие клавиши F1 так, чтобы при ее нажатии цвет окна приложения менялся на красный, а при отпускании восстанавливался прежний цвет.

182

12.СОХРАНЕНИЕ ОБЪЕКТОВ

12.1.Сохранение объектов в коллекциях

Класс TList

Класс-список TList представляет собой динамический массив нетипизированных указателей на размещенные в динамической памяти элементы. В списке могут храниться данные разных типов, в том числе и объекты.

Свойства:

property Count: Integer;

Содержит количество элементов в списке.

property Items[Index: Integer]: Pointer; default;

Возвращает указатель на элемент, хранящийся в списке по его индексу.

Методы:

function Add(Item: Pointer): Integer;

Вставляет новый элемент в конец списка.

procedure Clear; virtual;

Удаляет все элементы из списка

procedure Sort(Compare: TListSortCompare);

Сортирует список по заданному критерию.

type TListSortCompare = function (Item1, Item2: Pointer): Integer;

12.2. Сохранение объектов в файлах-сериализация

Классы TStream и TFileStream

В Delphi имеется абстрактный класс TStream, который используется для потокового ввода/вывода. В специализированном потомке этого класса определены методы Write, Read и Seek, позволяющие записывать и считывать данные из дискового файла.

183

Для сохранения объекта в потоке и последующего его восстановления используются методы WriteComponent и Read-

Component.

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

Регистрация классов выполняется в процедурах

procedure RegisterClass(AClass: TPersistentClass);

или

procedure RegisterClasses(AClasses: array of

TPersistentClass);

Создается поток вызовом конструктора

constructor Create(const FileName: string; Mode: Word); overload;

12.3. Форма

Форма в Delphi – это синоним окна. Любая программа имеет, как минимум, одну форму – она появляется на экране в момент старта программы. Для подключения новой формы к проекту достаточно обратиться к репозиторию и выбрать нужную разновидность формы. Доступ к репозиторию открывает опция меню File|New. Помимо универсальной пустой формы Form (страница New репозитория) репозиторий содержит и специализированные формы.

Подключение новой формы к проекту приводит к тому, что менеджер проекта размещает ее в списке автоматически создаваемых форм (окно Project Option, страница Forms, список Auto-create forms). Для того чтобы форма не создавалась автоматически в момент старта программы, необходимо перенести ее в список Available forms. В этом случае форма создается по мере необходимости следующим образом:

184

if not Assigned(Form2) then Form2:=TForm2.Create(self);

if Form2.ShowModal=mrXXXX then…//используем форму В момент старта программы на экране показывается толь-

ко одна – главная форма. Каждое следующее окно становится видно только после вызова его метода Show или ShowModal.

Самым первым событием, которое возникает при создании формы, является OnCreate : TNotifyEvent. При визуализации формы возникает событие OnShow : TNotifyEvent. После отрисовки форма получает фокус ввода сообщений от системных устройств, т.е. становится активной. В момент активизации возникает событие OnActivate : TNotifyEvent.

Метод Hide дает возможность сделать форму невидимой (изменяется свойство visible). При исчезновении формы с экрана возникает событие OnHide : TNotifyEvent. С помощью пары методов Show/Hide обычно управляют из главной формы показом прочих форм. В случае модального окна вмеcто Show используют ShowModal.

Основной способ, используемый для закрытия формы, – это вызов метода procedure Close; Внутри метода Close в первую очередь вызывается метод function CloseQuery:boolean; Для закрытия формы необходимо, чтобы он вернул True. Для проверки на возможность закрытия он вызывает обработчика собы-

тия OnCloseQuery: TCloseQueryEvent;

TCloseQueryEvent=procedure(Sender:TObject;Var CanClose:

boolean) of object;

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

CanClose.

Последним при уничтожении формы инициируется событие OnDestroy: TNotifyEvent. Здесь программист может предусмотреть необходимые действия, например, записать значения в файл.

Компонент TForm может играть роль диалогового (модального) окна. Для этого нужно вызвать метод function Show-

185

Modal:integer. Этот метод реализует весь жизненный цикл модальной формы. Он показывает форму на экране, активизирует ее и запрещает переключение на другие формы. Начинается обработка сообщений, которая происходит до тех пор, пока свойство ModalResult: TModalResult не изменит своего первоначально нулевого значения. Это свойство меняется непосредственно с помощью некоторых видов, принадлежащих форме кнопок. Если для модальной формы вызывается метод Close, его единственным действием является то, что ModalResult присваивается значение mrCancel(= 2).

Для закрытия модального окна вызывается метод Hide или Close. Следует учесть, что метод Close всегда помещает

вModalResult значение 2, в то время как Hide не меняет значение этого свойства, отсюда если программист хочет передать

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

ModalResult:=MyResult;

Hide;

В момент закрытия диалога модальное окно должно поместить число, соответствующее решению пользователя, в свое свойство ModalResult. Некоторые стандартные кнопки, например Ok, Yes, No, Cancel, выполняют эти действия автоматически: помещают нужное значение в ModalResult и закрывают окно.

Вызывающая программа получает значение ModalResult как значение, возвращаемое функцией ShowModal, и может его проанализировать, например:

if Form2.ShowModal=mrXXXX then…

или

Form2.ShowModal;

if Form2.ModalResulr=mrXXXX then…

186

12.4.Создание меню

ВDelphi для создания главного меню используется компонент TMainMenu, расположенный на странице Standard Палитры компонентов. На этапе конструирования главное меню создается при помощи встроенного конструктора меню

(Menu Designer).

Каждый элемент меню представляет собой объект класса

TMenuItem.

Кроме главного меню, связанного с формой приложения, имеется компонент TPopupMenu, предназначенный для создания контекстного меню. Контекстное меню может быть создано для любого оконного элемента управления. Для вызова контекстного меню необходимо поместить курсор мыши на оконный элемент и нажать правую кнопку мыши. Для установления связи между оконным элементом и компонентом TPopupMenu используется свойство PopupMenu оконного элемента, в котором следует указать имя соответствующего компонента TPopupMenu.

Контекстное меню также создается при помощи конструктора меню на этапе конструирования формы.

12.5. Пример создания диалоговой программы для работы с объектами

Агоритм работы следующий:

1.Определить в отдельном модуле иерархию пользовательских классов.

2.На главную форму поместить компонент TMainMenu, два списка TListBox для просмотра объектов (для каждого типа объектов свой список), две кнопки TButton сортировки списка TList по разным критериям, а также компоненты стандарт-

ных диалогов TOpenDialog и TSaveDialog.

3. С помощью редактора меню создать следующее меню:

187

File

Work

|

|

Сохранить

Добавить

Загрузить

Просмотр

Выход

 

Для меню «Добавить» создать подменю, уточняющее, объект какого класса должен быть создан и добавлен в списки.

4.Определить в модуле Unit1 переменную типа TList.

5.Реализовать обработчик события OnCreate для главного окна. В этом обработчике создается объект TList.

6.Создать диалоги для ввода значений полей объектов пользовательских классов. В соответствующих диалоговых окнах разместить поля ввода TEdit с пояснениями TLabel и двумя кнопками: OK и Cancel.

7.Написать обработчики команд меню «Добавить».

8.Создать диалог для просмотра объектов пользовательского класса. В диалоговом окне разместить две кнопки: «Сле-

дующий» и «Закончить».

9.Написать обработчик команды меню «Просмотр».

10.В пользовательских классах определить виртуальный метод (Show) для показа объекта в диалоговом окне.

11.Создать диалоги для редактирования объектов пользо-

вательских классов. В диалоговых окнах разместить поля TEdit

спояснениями TLabel и две кнопки: OK и Cancel.

12.Написать обработку двойного щелчка по строке в списках TListBox. Соответствующий обработчик должен обеспечить редактирование объекта с выделенной в списке TListBox строкой.

13.Написать обработчик команды меню «Сохранить объекты».

14.Написать обработчик команды меню «Загрузить объекты».

15.Написать обработчики кнопок «Сортировать».

188

12.6. Методические указания для программирования диалогов

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

2.Для доступа к закрытым полям пользовательского класса следует использовать свойства property, которые должны быть помещены в секцию published.

3.Не забудьте зарегистрировать ваши классы процедурой

RegisterClasses.

4.В обработчике команды меню «Создать объект» при завершении диалога кнопкой OK данные считываются с полей TEdit, создается объект пользовательского класса, который добавляется в список TList. Одновременно в список TListBox заносится ключевая строка. В качестве ключевой строки следует выбрать поле объекта, однозначно его идентифицирующее (например, имя).

5.Обработчик команды меню «Просмотреть объекты» выбирает из списка TList первый объект (его индекс 0) и вызывает его виртуальный метод Show.

6.Обработчик кнопки «Следующий» диалога просмотра объектов увеличивает индекс на единицу, выбирает из списка TList соответствующий объект и вызывает его виртуальный метод Show, предварительно закрывая предыдущее окно просмотра методом Hide.

7.Виртуальный метод Show создает немодальный диалог просмотра полей объекта.

8.Следует предусмотреть просмотр объектов по «кругу», т.е. после показа последнего объекта показывать первый.

9.Кнопка «Закончить» диалога просмотра объектов прекращает просмотр, закрывая окно.

189

10.Необходимо предусмотреть глобальную переменную Modified, которой следует присваивать значение True при модификации объектов в списке TListBox.

11.При редактировании объекта должна модифицироваться и соответствующая строка в списке TListBox.

12.Следует учитывать, что тип возвращаемого функцией ReadComponent значения TComponent, поэтому необходимо выполнять преобразование типов с помощью оператора as.

13.При загрузки объекта из потока функцией ReadCom-

ponent объект добавляется в список TList и одновременно в свой TListBox. При этом необходимо определить тип прочитанного объекта. Это можно сделать с помощью оператора is. Необходимо перед загрузкой объектов очистить списки. Для проверки выхода из цикла чтения объектов из потока TStream следует использовать его свойства Position и Size.

14.Сортировка списка TList выполняется методом Sort, которому передается адрес функции сравнения. Операция взятия адреса в Pascal @. Функции сравнения вы пишете сами в зависимости от выбранных критериев. Для сравнения строк можно использовать функцию CompareText. Типы формальных параметров функции сравнения должны быть типа базового класса. Соответственно, сортировать можно только по полям, наследуемым от базового класса.

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

лога кнопкой OK нужно обновить соответствующий объект в списках TList и TListBox, однако индексы одинаковых объектов в этих списках, естественно, не совпадают. Индекс редактируемого объекта в TListBox мы определяем через свойство ItemIndex , а в TList – функцией IndexOf. Обновляются объекты в списках TListBox через векторное свойство Objects, в списке TList – через векторное свойство Items.

190