КОМПЬЮТЕРНЫЕ КУРСЫ "ПОИСК"
[Главная страница] [Delphi] [Контакты]
Поместите на главную форму три компонента TProgressBar, присвоив всем трем вертикальную ориентацию Orientation = pbVertical. Свойству Max, описывающему максимальное значение шкалы, назначим значение 1000. Под каждым компонентом TProgressBar поместите элемент управления TCheckBox (флажок). В правой части формы разместите три элемента TTrackBar (ползунок). У соответствующих компонентов TCheckBox и TTrackBar поменяйте значение свойства tag:
Последние три компонента проекта – метки TLabel – разместите над шкалами TProgressBar
Последние три компонента проекта – метки TLabel – разместите над шкалами TProgressBar
При помощи элементов управления TTrackBar мы будем изменять приоритеты соответствующих потоков. Одновременно выберите все компоненты TTrackBar и их свойству Max присвойте значение 3. Значение 0 будет соответствовать минимальному приоритету tpIdle, значение 3 – нормальному приоритету tpNormal.
С настройкой элементов управления покончено. Займемся потоками. Для этого выберите пункт меню File → New → Other.
В окне New Items в разделе Delphi Files выберите пиктограмму Thread Object и нажмите ОК. Назовите класс создаваемого потока TMyThread. Вновь созданный модуль с шаблоном кода потока сохраните под именем ThreadUnit.pas.
В соответствии с приведенным ниже листингом внесите изменения в модуль ThreadUnit:
Листинг 1.
unit ThreadUnit; interface uses Classes, Windows, SysUtils, StdCtrls, ComCtrls; type TMyThread = class(TThread) private { Private declarations } procedure UpdateControls; protected procedure Execute; override; public ProgressBar: TProgressBar; //поле потока для подключения к TProgressBar Lbl: TLabel; //поле потока для подключения к информационной метке end; implementation { TMyThread } procedure TMyThread.Execute; var i: Integer; begin while Terminated = False do begin i := 0; while i < 2000000 do Inc(i); // единственная задача цикла – // занять процессорное время ReturnValue := ReturnValue + 1; Synchronize(UpdateControls); // синхронизируемся с методами VCL end; end; procedure TMyThread.UpdateControls; begin ProgressBar.Position := ProgressBar.Position + 1; if ProgressBar.Position >= ProgressBar.Max then ProgressBar.Position := 0; Lbl.Caption := IntToStr(ReturnValue); end; end.
В секции public потока опубликованы два поля ProgressBar : TProgressBar и Lbl : TLabel, предназначенные для организации взаимодействия потока с размещенными на главной форме шкалой и меткой. Основной метод Execute() выполняется до тех пор, пока он не будет разрушен вызовом функции Terminate. Внутри метода реализован цикл while I<2000000 do INC(I), предназначенный только для «пожирания» времени процессора. В заключение из тела метода Execute() вызывается функция Synchronize(UpdateControls), организующая обновление данных в принадлежащих потоку шкале и метке.
Вернемся к главной форме проекта и опишем ряд методов. В обработчике события OnCreate() формы поместите строки кода, создающие и запускающие все три потока.
Листинг 2.
var Thread1, Thread2, Thread3: TMyThread; procedure TForm1.FormCreate(Sender: TObject); begin Thread1 := TMyThread.Create(True); Thread1.Priority := tpIdle; Thread1.ProgressBar := ProgressBar1; Thread1.Lbl := Label1; Thread2 := TMyThread.Create(True); Thread2.Priority := tpIdle; Thread2.ProgressBar := ProgressBar2; Thread2.Lbl := Label2; Thread3 := TMyThread.Create(True); Thread3.Priority := tpIdle; Thread3.ProgressBar := ProgressBar3; Thread3.Lbl := Label3; Thread1.Resume; Thread2.Resume; Thread3.Resume; end;
В момент создания потоков мы связываем их с элементами управления TProgressBar и TLabel. Обращаю внимание, что все три экземпляра потоков создаются приостановленными и стартуют практически вместе после того, как к ним будут применены все настройки.
Чтобы не забыть, сразу опишем событие закрытия формы, в которой последовательно разрушим все три потока:
Листинг 3.
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Thread1.Terminate; Thread2.Terminate; Thread3.Terminate; end;
Настал час элемента управления TTrackBar. Задача компонента устанавливать приоритет для соответствующего потока. Выберите любой из этих компонентов и следующим образом опишите его обработчик события OnChange():
Листинг 4.
procedure TForm1.TrackBar1Change(Sender: TObject); var Priority: TThreadPriority; begin {преобразуем позицию ползунка в значение приоритета} case (Sender as TTrackBar).Position of 0 : Priority := tpIdle; // фоновый 1 : Priority := tpLowest; // выше фонового 2 : Priority := tpLower; // низкий 3 : Priority := tpNormal; // нормальный end; {по tag элемента управления выясняем, какому из потоков требуется изменить приоритет} case (Sender as TTrackBar).Tag of 1: Thread1.Priority := Priority; 2: Thread2.Priority := Priority; 3: Thread3.Priority := Priority; end; end;
Назначьте описанный выше обработчик события OnChange() общим для всех компонентов TTrackBar.
Опишите обработчик события OnClick() любого из компонентов TCheckBox в соответствии с указанным ниже кодом и сделайте его общим для всех компонентов-флажков. Задача этой процедуры – приостановить/продолжить выполнение потока.
Листинг 5.
procedure TForm1.CheckBox1Click(Sender: TObject); var Suspended: Boolean; begin Suspended := (Sender as TCheckBox).Checked; case (Sender as TCheckBox).Tag of 1: Thread1.Suspended := Suspended; 2: Thread2.Suspended := Suspended; 3: Thread3.Suspended := Suspended; end; end;
Сделайте этот обработчик общим для всех элементов TCheckBox. Приложение готово.
Источник: Д.Осипов - Delphi. Профессиональное программирование.
Исходный код примера здесь. Выполнен на Delphi XE.