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

Ракитин Р.Ю. ООП в Turbo Delphi

.PDF
Скачиваний:
55
Добавлен:
18.03.2015
Размер:
3.59 Mб
Скачать

181

var

CalcThread: TCalcThread;

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

constructor Create (CreateSuspended: boolean);

Параметр CreateSuspended определяет, следует ли создать поток в неактивном состоянии. Если конструктору передается значение False, то поток немедленно после создания запускается и работает, пока не закончится метод Execute. Если же поток создан в приостановленном состоянии, то его можно принудительно запустить, использовав метод Resume:

procedure Resume;

Для того чтобы приостановить поток, с возможностью повторного запуска в последствии, следует воспользоваться методом Suspend:

procedure Suspend;

Если необходимо запускать и останавливать поток, то нужно использовать свойство Suspended. Установив свойство его в значение True, получается тот же результат, что и при вызове метода Suspend приостановка потока. Наоборот, установка свойства Suspended в значение False возобновляет выполнение потока, как и вызов метода Resume.

Для синхронизации потоков часто используется метод WaitFor, который позволяет одному потоку дождаться момента, когда завершится другой поток. Например, если внутри потока FirstThread пишите код:

Code := SecondThread.WaitFor;

то это означает, что поток FirstThread останавливается до момента завершения потока SecondThread. Метод WaitFor возвращает код завершения ожидаемого потока.

Свойство ReturnValue (тип integer) позволяет узнать и установить значение, возвращаемое потоком по его завершении. Эта величина полностью определяется пользователем. По умолчании поток возвращает ноль, но если программист захочет вернуть другую величину, то простая переустановка

свойства ReturnValue внутри потока позволит получить эту информацию другим потокам.

Разрушение потоков

Для решения проблемы разрушения объекта потока в классе TThread предусмотрен механизм, который делает это автоматически. Для включения данного механизма следует установить значение True свойству

FreeOnTerminate, описанному в классе TThread: property FreeOnTerminate: boolean;

182

Установку значения свойства FreeOnTerminate можно выполнить в любом месте программы при условии, что поток еще не завершен. Если потоковый объект создается в приостановленном состоянии, то установить значение можно в вызывающем фрагменте сразу же после создания:

...

CalcThread:= TCalcThread.Create(True); CalcThread.FreeOnTerminate:=True;

...

Если же поток начинает работу немедленно после создания, то установку

значения свойству FreeOnTerminate можно выполнить в начале метода Execute самого объекта:

procedure TCalcThread.Execute;

...

begin

FreeOnTerminate:=True;

...

end;

Для завершения потока можно воспользоваться методом Terminate, описанным в классе TThread:

procedure Terminate;

При вызове данного метода не производится каких-либо действий, реально влияющих на выполнение потока, а просто устанавливается значение свойства Terminated, которое может быть проверено методом Execute, который должен самостоятельно решить, как следует завершить свое выполнение:

property Terminated: boolean;

Получение результата работы потока

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

1.Использование VCL

Теоретически, поток может использовать ссылки на интерфейсные компоненты для того, чтобы отображать в них свои внутренние данные. Однако библиотека визуальных компонентов (VCL) реализована таким образом, что

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

объекта из основного потока для получения доступа к визуальным компонентам, в классе TThread предусмотрен метод Synchronize:

183

procedure Synchronize (Method: TThreadMethod) ;

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

type TThreadMethod = procedure of object;

2.Использование обработчика OnTerminate

Обработчик события OnTerminate является удобным местом для получения результатов работы потока, так как вызывается после завершения метода Execute, но до разрушения экземпляра потокового класса. В обработчике доступны свойства потокового объекта, в которых и должны храниться результаты работы потока.

Так как обработчик события OnTerminate принадлежит основному потоку, то из нею возможен доступ к визуальным компонентам.

3.Использование дополнительных событий

Если поток должен взаимодействовать с другим потоком для передачи ему текущих данных, то использовании обработчика события OnTerminate невозможно, так как он вызывается после завершения потока. Однако

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

Приоритеты потоков

Для указания приоритетов потоков используется свойство Priority,

определяющее приоритет данною потока относительно других потоков приложения:

property Priority: TThreadPriority;

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

Приоритет

Описание

 

 

tpIdle

Поток выполняется только если система не выполняет каких-

 

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

 

приоритетом не может прервать выполнения других потоков

tpLowest

Поток имеет приоритет существенно ниже среднего

tpLower

Поток имеет приоритет ниже среднего

tpNormal

Поток имеет нормальный приоритет

tpHigher

Поток имеет приоритет выше среднего

tpHighest

Поток имеет приоритет существенно выше среднего

tpTimeCritical

Поток является наиболее приоритетным

184

Практическое задание

Рассмотрим пример использования потоков, в котором в рамках программы,

содержащей формы с двумя областями рисования (TPaintBox), запускаются два потока, каждый из которых выполняет

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

1. Создадим новое приложение. Подготовим

форму с двумя квадратными областями для

рисования TPainBox. Разметим так же на форму кнопку для создания и запуска потоков (ButRun) и для пуска и остановки потоков (ButPause1 и ButPause2). Разместим два объекта TComboBox для изменения приоритетов потоков.

2. Добавим в проект класс-поток. В диалоговом окне ввода названия класса укажем TPaintThread. Возникнет пустой модуль, назовем его UnitThread. В интерфейсной части модуля Unit1 добавим ссылку на модуль UnitThread, а в разделе реализации модуля UnitThread ссылку на модуль Unit1.

3. В главном модуле в классе TForm1 опишем новый метод CPaint, который получает в качестве параметра холст и рисует на нем квадрат размером 20x20 пиксель. Место расположения квадрата и его цвет выбирается случайным образом.

procedure TForm1.CPaint(Cv:TCanvas); var

b:byte;

c:TColor;

r:TRect; begin

//устанавливаем тип линии квадрата

Cv.Brush.Style:=bsSolid; //задаем случайный цвет c:=random(256); b:=random(256);

c:=c or (b shl 8); b:=random(256); c:=c or (b shl 16);

//устанавливаем цвет линии квадрата

Cv.Brush.Color:=c; //определяем положение квадрата

r.Left:=random(PaintBox1.Height);

r.Top:=random(PaintBox1.Height);

r.Right:=r.Left+10;

r.Bottom:=r.Top+10;

185

//рисуем на холсте квадрат

Cv.Rectangle(r); end;

4. Добавим еще два метода, которые будут обращаться к процедуре CPaint для вывода квадрата либо на холст объекта PaintBox1, либо на холст объекта

PaintBox2.

procedure TForm1.Paint1; begin

CPaint(PaintBox1.Canvas); end;

procedure TForm1.Paint2; begin

CPaint(PaintBox2.Canvas); end;

Эти процедуры необходимы, чтобы вызвать их из класса-потока с использованием процедуры Synchronize.

5. Для того чтобы внутри потока определить, какой из методов Paint1 или Paint2 необходимо вызвать, добавим в класс TPaintThread переменную Box.

...

public

Box: boolean; end;

При создании экземпляра потока занесем в эту переменную значение True, если необходимо вызвать метод Paint1.

6. Переопределим метод Execute. Для этого перейдем в модуль

UnitThread.

procedure TPaintThread.Execute; begin

//необходима для корректного завершения потока

FreeOnTerminate:=true;

//если поток не завершается, делать while not Terminated do

//проверяем какой квадрат необходимо перерисовать if Box then Synchronize(Form1.Paint1)

else Synchronize(Form1.Paint2)

end;

7. Добавим в описание класса TForm1 две новые переменные два будущих потока.

TForm1 = class(TForm)

...

public

T1, T2: TPaintThread;

186

end;

8.Опишем обработчик щелчка на кнопке ButRun.

procedure TForm1.ButRunClick(Sender: TObject); begin

T1:=TPaintThread.Create(true); //создаем поток T1.Box:=true;

//устанавливаем приоритет потока

T1.Priority:=tpLower;

T2:=TPaintThread.Create(true);

T2.Box:=false;

T2.Priority:=tpLowest;

T1.Resume; //запускаем поток

T2.Resume; end;

9. Для изменения приоритета потоков в объектах ComboBox опишем основные приоритеты: tpIdle, tpLowest, tpLower, tpNormal. И обработаем событие onChange.

procedure TForm1.ComboBox1Change(Sender: TObject); begin

case ComboBox1.ItemIndex of

0:T1.Priority:=tpIdle;

1:T1.Priority:=tpLowest;

2:T1.Priority:=tpLower;

3:T1.Priority:=tpNormal; end;

end;

Аналогично, запишем обработчик для ComboBox2, изменив название потока.

10. Для запуска и остановки потока, опишем обработчик нажатия клавиш «Стоп/Пуск». Для первого потока получим:

procedure TForm1.ButPause1Click(Sender: TObject); begin

T1.Suspended:=not(T1.Suspended); end;

187

Лабораторная работа № 1. Объектно-ориентированное моделирование

Цель: Описать иерархию классов и объектов

Задания:

1.Создать иерархию объектов с использованием виртуальных правил, статических и динамических методов.

2.Иерархию классов изобразите на листке бумаге, в виде графа.

3.При создании иерархии необходимо использовать, как минимум один абстрактный класс (класс для которого не может быть создан объект, он используется только для создания других классов).

4.При создании классов использовать наследование и полиморфизм.

5.Количество уровней в иерархии не менее 4.

6.Общее число классов не менее 7.

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

Варианты заданий к лабораторной работе:

1.Создать иерархию объектов «Машины»;

2.Создать иерархию объектов «Животный мир»;

3.Создать иерархию объектов «Дома»;

4.Создать иерархию объектов «Ёмкости»;

5.Создать иерархию объектов «Мебель»;

6.Создать иерархию объектов «Еда»;

7.Создать иерархию объектов «Сфера обслуживания»;

8.Создать иерархию объектов «Водные ресурсы»;

9.Создать иерархию объектов «Летательные аппараты»;

10.Создать иерархию объектов «Средства передвижения»;

11.Создать иерархию объектов «Средства передвижения по воде»;

12.Создать иерархию объектов «Программное обеспечение»;

13.Создать иерархию объектов «Живущие в воде»;

14.Создать иерархию объектов «Живущие на суше»;

15.Создать иерархию объектов «Люди»;

16.Создать иерархию объектов «Орудия труда»;

17.Создать иерархию объектов «Оружие;

18.Создать иерархию объектов «Бытовая техника»;

19.Создать иерархию объектов «Электронные устройства»;

20.Создать иерархию объектов «Игры»;

21.Создать иерархию объектов «Строения»;

22.Создать иерархию объектов «Система образования»;

23.Создать иерархию объектов «Системы административно-территориального деления государства»;

24.Создать иерархию объектов «Структурные подразделения ВУЗа»;

25.Создать иерархию объектов «Растительный мир».

188

Лабораторная работа № 2. Изучение стандартных компонентов Delphi

Цель: Реализовать программу, эмулирующую внешний вид заданной экранной формы.

Задания:

1.Проанализировать заданную форму и выделить основные визуальные и не визуальные компоненты используемые в ней;

2.Используя стандартные компоненты Delphi, как можно ближе, повторить внешний вид диалоговых окон или приложений;

3.Полученная эмуляция окна должна быть полностью работоспособной (то есть меню отображаться, кнопки нажиматься, пункты выбираться);

4.Необходимо эмулировать не только главную форму, но и все подчиненные;

5.Окна с отображением файлов, наполнять по своему усмотрению;

6.После реализации экранной формы, уметь описать работу каждого из используемых компонентов.

Варианты заданий к лабораторной работе:

1.Эмуляция OpenOffice Write: Файл → Окно печати;

2.Эмуляция OpenOffice Write: Файл → Свойства Документа;

3.Эмуляция OpenOffice Write: Формат → Символы;

4.Эмуляция OpenOffice Write: Формат → Абзац;

5.Эмуляция OpenOffice Write: Сервис → Автозамена;

6.Эмуляция OpenOffice Write: Сервис → Настройка;

7.Эмуляция OpenOffice Write: Сервис → Параметры (Внешний вид);

8.Эмуляция OpenOffice Write: Сервис → Параметры (Загрузка/сохранение);

9.Эмуляция OpenOffice Write: Сервис → Параметры (Writer);

10.Эмуляция OpenOffice Write: Сервис → Параметры (Writer/Web);

11.Эмуляция Delphi: Project Options;

12.Эмуляция Delphi: Run Parameters;

13.Эмуляция Delphi: Run Load Process;

14.Эмуляция Delphi: Tools Options Environment Options;

15.Эмуляция Delphi: Tools Options Editor Options;

16.Эмуляция: Сервис → Свойства папки;

17.Эмуляция: Экран-свойства;

18.Эмуляция: Звуки и аудиоустройства;

19.Эмуляция: Эмуляция «свойства ярлыка»;

20.Эмуляция: Свойства: Дата и время;

21.Эмуляция: Свойства системы (Мой компьютер свойства);

22.Эмуляция: Язык и региональные стандарты;

23.Эмуляция: Подключение к удаленному рабочему столу;

24.Эмуляция: Вид программы «Дефрагментация диска»;

25.Эмуляция: Окно настройки сетевого подключения.

189

Лабораторная работа № 3. Событийная модель

Цель: Используя компоненты Кнопки, изучить событийную модель Delphi

Задания:

1.Разместить на форме четыре кнопки (компоненты TButton, TBitBtn, TSpeedButton использовать в произвольном порядке).

2.Щелчок на форме и <ALT-I> восстанавливают начальное состояние кнопок.

3.Двойной щелчок и <ALT-X> закрывают форму. Предусмотреть вывод подтверждения закрытия.

4.Для каждой кнопки определить подсказку (Hint), описывающую функцию кнопки, причем подсказка появляется не стандартным образом, а вместе с

именем и заголовком кнопки в специальной области формы при попадании указателя мыши на кнопку и гаснет при уходе указателя с кнопки.

5.C каждой из кнопок связать определенное действие, описанное ниже.

1-я кнопка

a.прячет / показывает 2-ю;

b.блокирует / включает 2-ю;

c.переключает видимость 2-й и 3-й (видна только одна из кнопок по очереди);

d.переключает блокировку 2-й и 3-й (активна только одна из кнопок по очереди);

e.меняет подсказки 2-й и 3-й.

2-я кнопка (учесть реальные ограничения, связанные с размером формы)

a.сдвигает первую кнопку на 10 пикселей вверх;

b.сдвигает первую кнопку на 10 пикселей вниз;

c.сдвигает первую кнопку на 10 пикселей вправо;

d.сдвигает первую кнопку на 10 пикселей влево;

e.сжимает форму на 5 пикселей со всех сторон;

f.раздвигает форму на 5 пикселей во все стороны.

3-я кнопка (1 – сама по себе, 2 – с Shift, 3 – c Ctrl)

a.1-увеличивает, 2-уменьшает, 3-переключает по кругу (из 3-х) шрифты на форме;

b.вкл/выкл 1-полужирн., 2-накл., 3-подчерк. стили шрифтов на форме

c.переключает цвет формы по кругу (из 5-и) 1 – в одну сторону, 2 – в др., 3 – включает белый цвет.

4-я кнопка

a.вкл./выкл. системную кнопку;

b.вкл./выкл. кнопку развернуть”;

c.вкл./выкл. кнопку свернуть”;

d.перебирает тип курсора (по кругу из 5-ти);

e.перебирает тип рамки (по кругу из 5-ти).

190

6. Действия, связанные с кнопками определить согласно вашему варианту:

Вар

1

2

3

4

Вар

1

2

3

4

Вар

1

2

3

4

 

кн

кн

кн

кн

 

кн

кн

кн

кн

 

кн

кн

кн

кн

1

a

a

a

a

11

a

e

c

c

20

e

b

b

c

2

b

b

a

b

12

b

f

c

d

21

a

c

b

e

3

c

c

a

c

13

c

a

a

e

22

b

d

a

a

4

d

d

a

d

14

d

b

b

a

23

c

e

a

b

5

e

e

b

e

15

e

c

b

b

24

d

f

a

c

6

a

f

b

b

16

a

d

c

d

25

e

a

c

d

7

b

a

b

c

17

b

e

c

e

 

 

 

 

 

8

c

b

b

d

18

c

f

c

a

 

 

 

 

 

9

d

c

c

e

19

d

a

c

b

 

 

 

 

 

10

e

d

c

a

20

e

b

b

c

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7.Предусмотреть подтверждение закрытия приложения.

8.В модальном окне вывести информацию о создателе программы.