Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Универсальный ProgressBar [D7, XP]


DimDim ©   (2006-05-08 16:10:00) 

Уважаемые Мастера, что я неправильно делаю?
В проекте есть несколько длинных процедур. Сделал для них универсальную форму со свойством FormStyle=fsStayOnTop с ProgressBar-ом.
В самих процедурах:
begin
FormProgres.Show;
for I:=1 to X do
 begin
 ... // что-то там делаем
 FormProgres.ProgressBar1.Position:=I;
 FormProgres.Update;
 end;
FormProgres.Close;
end;

Все хорошо работает и показывает, если в процессе выполнения ничего не трогать. Если пользователь пытется перевести фокус на другое окно, или передвинуть FormProgres, то внешне ProgressBar останавливается и форма FormProgres после выполнения не закрывается. Что неправильно?
А может системные прогресы есть, типа Application.MessageBox?


Пусик   (2006-05-09 13:39:00) [1]


> Kolan ©   (09.05.06 13:35) [15]
>
> Пусик ©   (09.05.06 13:19) [14]
> FormProgres.ProgressBar1.Position:=I;
> Предпологает использование TProgressBar...


А что, обязательно, TProgressBar использовать из комплекта VCL.

Создается на Win32API окно и ProgressBar. Всё это в отдельном потоке. И все прекрасно будет работать.


Kolan   (2006-05-09 13:35:00) [2]

Пусик ©   (09.05.06 13:19) [14]
FormProgres.ProgressBar1.Position:=I;

Предпологает использование TProgressBar...


Пусик   (2006-05-09 13:19:00) [3]


> Kolan ©   (09.05.06 12:53) [13]
>
> VCL компоненты лучьше не использовать в доп потоке, тк большинство
> из них непотокобезопасны.


ДЛя того, чтобы сделать бегунок в отдельном потоке, не обязательно использовать VCL.


Kolan   (2006-05-09 12:53:00) [4]

Algol   (09.05.06 11:06) [12]



VCL компоненты лучьше не использовать в доп потоке, тк большинство из них непотокобезопасны.


DimDim ©   (08.05.06 16:10)


В доп. потоке лучьше делать вычисления. А ProgressBar изменять в главном потоке.

Читать про TThread, Synchronize...


Algol   (2006-05-09 11:06:00) [5]

А вообще-то прогресс бар лучше делать в отдельном потоке...


TUser   (2006-05-09 10:12:00) [6]

Можно заменить Screen.Forms[i].Enabled на EnableWindow (Screen.Forms[i].Handle, false/true)


TUser   (2006-05-09 10:11:00) [7]

> А подробнее?

procedure TForm4.Button1Click(Sender: TObject);
var i: integer;
begin
 for i:=0 to Screen.FormCount-1 do
   if Screen.Forms[i] <> Self then
     Screen.Forms[i].Enabled:=false;
end;

procedure TForm4.Button2Click(Sender: TObject);
var i: integer;
begin
 for i:=0 to Screen.FormCount-1 do
   Screen.Forms[i].Enabled:=true;
end;


Пусик   (2006-05-09 01:53:00) [8]


> DimDim ©   (08.05.06 16:10)


Можно сделать примерно так:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ComCtrls;

type

 TProgressForm=class
 private
   FForm: TForm;
   FProgressBar: TProgressBar;
   function GetPosition: Integer;
   procedure SetPosition(const Value: Integer);
 public
   constructor Create(MinPos,MaxPos: Integer);
   destructor Destroy; override;
   procedure Show;
   property Position: Integer read GetPosition write SetPosition;
 end;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

{ TProgressForm }

constructor TProgressForm.Create(MinPos, MaxPos: Integer);
var
 i: Integer;
begin
 FForm := TForm.Create(Application);
 FProgressBar := TProgressBar.Create(FForm);
 FForm.Position := poScreenCenter;
 FForm.BorderStyle := bsToolWindow;
 FForm.BorderIcons := [];
 FForm.Width := 300;
 FForm.Height := 35;
 FProgressBar.Parent := FForm;
 FProgressBar.Align := alClient;
 FProgressBar.Position := 0;
 FProgressBar.Min := MinPos;
 FProgressBar.Max := MaxPos;
 for i := 0 to Screen.FormCount-1 do
 begin
   if Screen.Forms[i]<>FForm then Screen.Forms[i].Enabled := False;
 end;
end;

destructor TProgressForm.Destroy;
var
 i: Integer;
begin
 for i := 0 to Screen.FormCount-1 do
 begin
   Screen.Forms[i].Enabled := True;
 end;
 FForm.Free;
end;

function TProgressForm.GetPosition: Integer;
begin
 Result := FProgressBar.Position;
end;

procedure TProgressForm.SetPosition(const Value: Integer);
begin
 FProgressBar.Position := Value;
 if (FProgressBar.Position mod 10)=0 then Application.ProcessMessages;
end;

procedure TProgressForm.Show;
begin
 FForm.Show;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 i: Integer;
 f: TProgressForm;
begin
 f := TProgressForm.Create(0,1000000);
 f.Show;
 for i := 0 to 1000000 do
 begin
   f.Position := i;
 end;
 f.Free;
end;

end.


Джо   (2006-05-09 00:46:00) [9]

> [7] DimDim ©   (08.05.06 22:05)
> А подробнее? Раздел форума всетаки "Начинающим"...

procedure EnableAllBut (ThisForm: TForm; AState: Boolean);
var
 I: Integer;
begin
 for I := 0 to Screen.FormCount-1 do
   if Screen.Forms[I] <> ThisForm then
     Screen.Forms[I].Enabled := AState
end;

Делает enable/disable (зависит от параметра AState) для всех форм, кроме указанной.


DimDim   (2006-05-08 22:05:00) [10]

> Application.Forms
А подробнее? Раздел форума всетаки "Начинающим"...


TUser   (2006-05-08 21:44:00) [11]

Application.Forms


DimDim   (2006-05-08 21:37:00) [12]

> С помощью свойства Enabled формы
Процедура запускается с различных форм. Тогда надо по меньшей мере знать из какой конкретно формы она запускается. Сделать конечно можно, но думал что есть что попроще.

> FormProgres.ShowModal;
ShowModal останавливат процедуру до закрытия дочерней формы.


Algol   (2006-05-08 20:02:00) [13]


> А как сделать безусловную блокировку остальных форм?

FormProgres.ShowModal;


Loginov Dmitry   (2006-05-08 17:21:00) [14]

DimDim ©   (08.05.06 16:40) [2]


> 1. Заметно замедляет работу.


Так не нужно вызывать этот метод при каждой итерации.


А как сделать безусловную блокировку остальных форм?


С помощью свойства Enabled формы.


DimDim   (2006-05-08 16:40:00) [15]

>Встать в тело цикла Application.ProcessMessages;

1. Заметно замедляет работу.
2. Если поменять фокус на другое приложение, то все равно остается болтаться "плавающая" форма с прогрессом.
3. Появляется возможность управлять нижними формами, а это не желательно. Т.е. пользователь, например, может управлять таблицей, из которой в данный момент выполняется выборка записей.

А как сделать безусловную блокировку остальных форм?


Loginov Dmitry   (2006-05-08 16:12:00) [16]

DimDim ©   (08.05.06 16:10)

Встать в тело цикла
Application.ProcessMessages;


Наверх

Титульная страница Поиск, карта сайта Написать письмо