КОМПЬЮТЕРНЫЕ КУРСЫ "ПОИСК"
[Главная страница] [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.