Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.28;
Скачать: CL | DM;

Вниз

Универсальный ProgressBar   Найти похожие ветки 

 
DimDim ©   (2006-05-08 16:10) [0]

Уважаемые Мастера, что я неправильно делаю?
В проекте есть несколько длинных процедур. Сделал для них универсальную форму со свойством 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?


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

DimDim ©   (08.05.06 16:10)

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


 
DimDim ©   (2006-05-08 16:40) [2]

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

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

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


 
Loginov Dmitry ©   (2006-05-08 17:21) [3]

DimDim ©   (08.05.06 16:40) [2]


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


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


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


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


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


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

FormProgres.ShowModal;


 
DimDim ©   (2006-05-08 21:37) [5]

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

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


 
TUser ©   (2006-05-08 21:44) [6]

Application.Forms


 
DimDim ©   (2006-05-08 22:05) [7]

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


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

> [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) для всех форм, кроме указанной.


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


> 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.


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

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

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;


 
TUser ©   (2006-05-09 10:12) [11]

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


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

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


 
Kolan ©   (2006-05-09 12:53) [13]

Algol   (09.05.06 11:06) [12]



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


DimDim ©   (08.05.06 16:10)


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

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


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


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


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


 
Kolan ©   (2006-05-09 13:35) [15]

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

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


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


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


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

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



Страницы: 1 вся ветка

Текущий архив: 2006.05.28;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.042 c
11-1127201931
BMouradov
2005-09-20 11:38
2006.05.28
KolTrayIcon


1-1145478752
Andrey.Ru
2006-04-20 00:32
2006.05.28
Список всех COM+ приложений


2-1147187088
AlexanderMS
2006-05-09 19:04
2006.05.28
Проблема с PopupMenu в ListBox


2-1147187480
tigra
2006-05-09 19:11
2006.05.28
Сумма целых чисел от 1 до....


5-1132651701
nikolas
2005-11-22 12:28
2006.05.28
Текущая дата в TDateEdit из RxLib