На нашем сайте ежедневно публикуются десятки качественных и свежих материалов, которые Вы можете скачать абсолютно бесплатно. Рекомендуем Вам добавить Наш сайт в закладки, а также подписаться на RSS ленту, чтобы не пропускать интересных новостей.
Пример многооконого (MDI) многопоточного приложения
Пример многооконого (MDI) многопоточного приложения
Создадим многооконное приложение, в каждом окне которого отдельный поток будет рисовать случайные отрезки. Создайте заготовку MDI-приложения (File->New->Other, перейдите на вкладку Projects и выберите MDI Application). Откроется диалоговое окно, в котором вы должны указать проекта и нажать ОК. Delphi создаст не просто заготовку, а «действующую модель» MDI-приложения – текстового редактора, которую можно сразу же собрать и запустить. Мы ее только немного подправим. Напомню, что все дочерние окна, в которых во время работы приложения открываются документы, являются объектами класса TMDChild. Этот класс объявлен и реализован в файле CHILDWIN.PAS, автоматически созданном Delphi в рамках проекта MDI. Чтобы открыть этот файл в Редакторе кода , выберите в меню Delphi команду View->Units. Откроется диалоговое окно со списком модулей, составляющих приложение. Выберите из списка CHILDWIN и нажмите ОК. Откройте форму дочернего окна (Windows-> MDI Child), удалите с нее компонент Memo, а вместо него поместите на форму компонент Image. Откройте обьект Image1 в Инспекторе обьектов и дайте его свойству Align значение alClient. Перейдите в окно редактора кода на вкладку MAIN. Последняя строка в теле метода TMainForm.CreateMDIChild служила для загрузки текстового файла в только что удаленный из дочернего окна обьект Memo. Удалите эту строку. Вернитесь в окно Редактора кода , открытое на вкладке CHILDWIN. Займемся программированием поведения дочернего окна. Мы хотим чтобы при создании каждого нового дочернего окна запускался новый экземпляр рабочего потока, который будет в бесконечном цикле генерировать случайные координаты и цвет отрезка и рисовать этот отрезок в своем собственном окне. И окно, и поток должны «знать» друг о друге, то есть среди атрибутов окна должен быть обьект потока, а среди атрибутов потока – обьект области рисования Image:
Код:
Код
type TMDIWorkThread = class (TThread) private Image: TImage; X1, X2, Y1, Y2:Integer; Color:TColor; protected procedure Execute; override; procedure DrawLine; public constructor Create(AImage: TImage); end; type TMDIChild = class(TForm) Image1: TImage; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure formCreate (Sender: TObject); private WorkThread: TMDIWorkThread; public end;
Напишем конструктор TMDIWorkThread.Create так, чтобы он создавал поток в запущенном состоянии, устанавливал значение атрибута Image равным своему аргументу, а приоритет потока равным tpLowest. Код:
Код
constructor TMDIWorkThread.Create(AImage: TImage); begin inherited Create (False); Image:=AImage; Priority:=tpLowest; end; procedure TMDIWorkThread.Execute; begin repeat X1:=Random(Image.Width); Y1:=Random(Image.Height); X2:=Random(Image.Width); Y2:=Random(Image.Height); Color:=TColor(Random($00FFFFFF)); Synchronize(DrawLine); until Terminated; end; procedure TMDIWorkThread.DrawLine; begin Image.Canvas.Pen.Color:=Color; Image.Canvas.MoveTo(X1, Y1); Image.Canvas.LineTo(X2, Y2); end;
На этом класс TMDIWorkThread реализован полностью. Осталось обработать событие формы MDIChildOnCreate, чтобы при создании нового экземпляра дочернего окна сразу же создавался обслуживающий его поток. Выберите в меню форму дочернего окна (Windows-> MDI Child), откройте ее в Инспекторе объектов (Window->Object Inspector) и добавьте обработчик события OnCreate обычным способом:
Код:
Код
procedure TMDIChild.FormCreate(Sender: TObject); begin DoubleBuffered:=True; WorkThread:=TMDIWorkThread.Create(Image1); end;
Последнее, что нужно сделать, это обеспечить завершение потока и уничтожение его объекта при закрытии дочернего окна. Метод TMDIChild.FormClose уже реализован, и осталось только добавить его в тело две команды, которые пошлют потоку требование завершиться и освободят память:
Код:
Код
procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction); begin Action:=caFree; WorkThread.Terminate; WorkThread.Free; end; end.