1. Запустите среду разработки Delphi, откройте новый проект через главное меню File|New|Application либо воспользуйтесь проектом, созданным по умолчанию.
2. Расположите на форме две кнопки с надписями «Start» и «Stop», для задания надписей используйте свойство Caption, для вызова страницы свойств (Object Inspector) используйте клавишу F11 (рис. 1).
Рис. 1
3. Создайте для формы обработчик события MouseDown (нажатие кнопки мыши), рисующий на форме круг в текущем положении курсора мыши. Для этого в окне Object Inspector, предварительно выделив форму, выберете закладку Events, на которой найдите событие OnMouseDown. Создайте обработчик события двойным щелчком мыши по полю.
Рис. 2
4. В обработчике события введите следующий программный код.
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Canvas.Pen.Color:=clYellow;
Canvas.Brush.Color:=clYellow;
Canvas.Ellipse (x - 30, y - 30, x + 30, y + 30);
end;
5. Запустите приложение на выполнение, нажав клавишу F9.
6. Добавьте константу с именем Radius и замените ей непосредственное значение радиуса 30.
7. Добавьте программный поток, выполняющий фоновую закраску формы. Для этого выполните команду File|New|Other…, на экране появится окно с шаблонами, в котором следует выбрать элемент Thread Object.
Рис. 3
8. Задайте имя создаваемого класса – TPaintThread.
Рис. 3
9. В созданном модуле (Unit2) добавьте ссылку на модуль с главной формой (Unit1) и на модуль Graphics. Для этого добавьте ключевое слово uses в разделе implementation.
…
implementation
uses Unit1,Graphics;
…
10. В модуле формы (Unit1) добавьте ссылку на модуль с потоком (Unit2), дополнив список уже используемых модулей в разделе uses.
11. Добавьте непосредственно исполняемый код потока в метод Execute класса TPaintThread.
procedure TPaintThread.Execute;
var
X, Y: Integer;
begin
Randomize;
repeat
X:= Random (Form1.Button1.Left-10);
Y:= Random (Form1.ClientHeight);
with Form1.Canvas do
begin
Lock;
Pixels [X, Y]:= clBlue;
UnLock;
end;
until Terminated;
end;
В данном случае объект Canvas (полотно для рисования на форме) будет являтся разделяемым ресурсом, т.к. к нему одновременно будут обращаться несколько потоков. Объект Canvas формы имеет встроенные средства синхронизации для предотвращения конфликтов при доступе – Lock и UnLock. В общем случае при обращении к форме из разных потоков необходимо использовать метод Synchronize.
12. Добавьте вызов методов Lock и UnLock при обращении к объекту Canvas в главной форме.
13. Объявите переменную для работы с потоком в модуле формы.
…
var
Form1: TForm1;
PT: TPaintThread;
…
14. Добавьте обработчики события Click кнопок Start и Stop.
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled:=False;
Button2.Enabled:=True;
PT:= TPaintThread.Create(False);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
PT.Terminate;
PT.Free;
Button1.Enabled:=True;
Button2.Enabled:=False;
end;
15. Запустите приложение на выполнение, нажав клавишу F9.
16. При завершении основного потока должны завершиться и все дочерние потоки, для этого в событии FormDestroy нужно завершить и уничтожить поток аналогично тому, как это делается при нажатии на кнопку Stop.
17. Перепишите код обращения к объекту Canvas с использованием метода Synchronize вместо вызовов методов блокировки.