КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Interface. Можно написать другой вариант решения данного примера, воспользовавшись особенностью компонента TCanvas
End. End. ИСПОЛЬЗОВАНИЕ БЛОКИРОВКИ В ПРИМЕРЕ 27 Можно написать другой вариант решения данного примера, воспользовавшись особенностью компонента TCanvas. Дело в том, что этот компонент содержит два метода Lock и UnLock, которые позволяют блокировать вывод на канву с последующей разблокировкой. Естественно, при использовании этих методов канвы отпадает необходимость синхронизации работы потоков с помощью метода Synchronize. Код программы приводится далее. Из текста кода основного модуля приводится только один обработчик TForm1. FormMouseDown, в который внесены изменения. Отметим, что код потока немного упростился. unit MyTread2; interface uses Classes; type TPaintThread = class(TThread) protected procedure Execute; override; end; implementation uses Unit27_2, Graphics; procedure TPaintThread.Execute; var x,у:integer; begin randomize; Repeat x:=random(250); y:=random(Form1.ClientHeight); with Form1.Canvas do begin Lock; try Pixels[x,y]:=clPurple; finally UnLock; end; end; until Terminated; end; unit Unit27_2; ……………………. procedure TForm1.FormMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer), begin Canvas.Lock; try Canvas.Pen.Color:= Color; Canvas.Brush.Color:= Color; Canvas.Ellipse (x - 30, у - 30, x + 30, у + 30); finally Canvas.Unlock; end; end; Нельзя не заметить, что второй вариант примера работает значительно быстрее. Но, к сожалению, не для любых потоков можно применить подобные приемы блокировки. МНОГОПОТОЧНОЕ ПРИЛОЖЕНИЕ В ПРИМЕРЕ 28 В данном примере создаются три потока, которые закрашивают разными цветами один и тот же прямоугольник, как и в примере 27. Однако способ закраски в примере 28 отличается тем, что используется сканирование прямоугольной области. В варианте, который приводится ниже, используется встроенная в класс TThread система безопасности с помощью метода синхронизации. Следует отметить, что данный подход не спасает приложение и компьютер от зависания, поэтому этот вариант примера лучше запускать из среды Delphi, чтобы можно было воспользоваться клавишами Ctrl+F2. Правда, вероятность зависания зависит от установленных приоритетов для каждого потока. В примере используются новые компоненты: TTrackBar - для изменения приоритета потоков и TProgressBar - для визуального контроля скорости работы того или иного потока. Компонент TTrackBar применяется, когда требуется изменять значения в заданном диапазоне. Текущее значение определяется свойством Position, диапазон значений задается свойствами Min и Мах. В примере задано Min=0, Max=3. Второй компонент (TProgressBar на странице Win32 - индикатор хода работ) показывает графическую полосу хода выполнения какой-либо операции. Текущая позиция индикатора определяется свойством Position, свойства Min и Мах задают диапазон индикатора. В примере задано Min=0, Max определяется свойством формы ClientHeight, т.е. в данном случае числом дисплейных строк. Число участков, на которое делится весь диапазон, задано равным 10. Это число определяет величину шага сканирования диапазона, которое записывается в свойстве Step. Ниже приводится программный код примера. Отметим, что в обработчике TrackBar1Change используются свойства Tag компонентов TtrackBar, которые соответственно необходимо с помощью инспектора объектов установить равными 1, 2, 3. unit MyThread3; interface uses Classes, Graphics, ComCtrls; type TPaintThread = class(TThread) private x,у:integer; FColor:TColor; FProgressBar:TProgressBar; public constructor InitColor(nColor:TColor); property ProgressBar:TProgressBar write FProgressBar; procedure DisplayProgress; protected procedure Execute; override; procedure Paint; end; implementation uses Unit28; constructor TPaintThread.InitColor(nColorrTColor); Fcolor:=nColor; end; procedure TPaintThread.DisplayProgress; begin FprogressBar.Position:=y; end; procedure TPaintThread.Paint; var j: Integer; begin for j:=0 to 250 do begin x: = j; Form1.Canvas.Pixels[x,y]:=FColor; end; end; procedure TPaintThread.Execute; var i: Integer; begin repeat for i:=0 to Form1.ClientHeight do begin y:=i; Synchronize(DisplayProgress); Synchronize(Paint); end; until Terminated; end; end. unit Unit28; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ComCtrls, MyThread3; Type TForm1 = class(TForm) TrackBar1: TTrackBar; TrackBar2: TTrackBar; ТгаскВагЗ: TTrackBar; BitBtnl: TBitBtn; CheckBox1: TCheckBox; CheckBox2: TCheckBox; CheckBox3: TCheckBox; ProgressBar1: TProgressBar; ProgressBar2: TProgressBar; ProgressBar3: TProgressBar; procedure CheckBox1Click(Sender: TObject); procedure TrackBar1Change(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); public PT: array [1..3] of TPaintThread; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.CheckBox1Click(Sender: TObject); begin Form1.Canvas.Lock; if (Sender as TCheckbox).Checked then PT [(Sender as TCheckbox).Tag].Resume else PT [(Sender as TCheckbox).Tag].Suspend; Form1.Canvas.UnLock; end; procedure TForm1.TrackBar1Change(Sender: TObject); begin PT [(Sender as TTrackBar).Tag].Priority:= TThreadPriority ((Sender as TTrackBar).Position); end; procedure TForm1.FormCreate(Sender: TObject); begin PT [1]:= TPaintThread.Create (true); PT [2]:= TPaintThread.Create (true); PT [3]:= TPaintThread.Create (true); PT[1].InitColor(clRed); PT[2].InitColor(clBlue); PT[3].InitColor(clGreen); ProgressBar1.Max:=Form1.ClientHeight; ProgressBar2.Max:=Form1.ClientHeight; ProgressBar3.Max:=Form1.ClientHeight; ProgressBar1.Step:=Form1.ClientHeight div 10; ProgressBar2.Step:=Form1.ClientHeight div 10; ProgressBar3.Step:=Form1.ClientHeight div 10; PT[1].ProgressBar:=ProgressBar1; PT[2].ProgressBar:=ProgressBar2; PT[3].ProgressBar:=ProgressBar3; end; procedure TForm1.FormMouseDown(Sender: TObj ect; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Canvas.Lock; try Canvas.Pen.Color:= Color; Canvas.Brush.Color:= Color;
Canvas.Ellipse (x - 30, у - 30, x + 30, у + 30); finally Canvas.Unlock; end; end; end. Результат решения примера приводится на рис. 64 (показаны установки приоритетов, обеспечивающие достаточно надежную работу приложения). Рис. 64 В примере создается массив рт из трех потоков. Цвет закраски прямоугольной области задается с помощью вызова конструктора initcolor. Разделение общих ресурсов, используемых потоками, обеспечивается методом Synchronize. Для ускорения работы синхронизируется работа не каждого доступа к канве по изменению цвета пиксела (Pixels [x,y]), а только очередной дисплейной строки. Можно попытаться синхронизировать доступ к каждому пикселу, возможно, это обеспечит более надежную работу (но замедлится работа приложения). Надежной работы данной программы можно добиться, используя методы блокировки канвы, как это было применено в примере 27. Далее для этого случая приводится код модуля, в котором объявлен поток (код основного модуля не изменился по сравнению с предыдущим примером). unit MyThread3_1; uses Classes, Graphics, ComCtrls; type TPaintThread = class(TThread) private FColor:TColor; FProgressBar:TProgressBar; public constructor InitColor(nColor:TColor); property ProgressBar:TProgressBar write FProgressBar; protected procedure Execute; override; end; implementation uses Unit28_1; constructor TPaintThread.InitColor (nColor:TColor); begin Fcolor:=nColor; end; procedure TPaintThread.Execute; var x,y: Integer; begin repeat for y:=0 to Form1.ClientHeight do begin FprogressBar.Position:=y; Form1.Canvas.Lock; try for x:=0 to 250 do Form1.Canvas.Pixels[x,y]:=FColor; finally Form1.Canvas.UnLock; end; end; until Terminated; end;
Дата добавления: 2014-12-29; Просмотров: 500; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |