![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ProcessStatus [D7, WinXP]
liver © (2005-05-31 11:41:00)Нужна форма которая будет показывать состояние выполнения процесса.
Как реализовать ?
Slym (2005-05-31 12:29:00) [1]Я делаю так... Но есть теоретически проблемы типа DeadLock
unit ThreadProgress;
interface
uses
Windows, Messages,SysUtils, Classes, Forms, StdCtrls,ComCtrls, Controls;
type
TProgressForm = class(TForm)
Text: TLabel;
ProgressBar: TProgressBar;
Cancel: TButton;
end;
TThreadProgress=class;
TCustomThread=class;
TOnExecute=procedure(Progress:TThreadProgress) of object;
TCustomThread = class(TThread)
private
FThreadProgress:TThreadProgress;
FOnExecute:TOnExecute;
protected
procedure Execute; override;
public
property ThreadProgress:TThreadProgress read FThreadProgress write FThreadProgress;
property OnExecute:TOnExecute read FOnExecute write FOnExecute;
end;
TThreadProgress = class(TComponent)
private
FCaption:TCaption;
FText:TCaption;
FCancelEnabled:boolean;
FPosition:integer;
FMax:integer;
FOnExecute:TOnExecute;
FProgressForm:TProgressForm;
FUpdateCount:integer;
FBeginTime:DWORD;
FThread:TCustomThread;
procedure SetCaption(Value:TCaption);
procedure SetText(Value:TCaption);
procedure SetPosition(Value:integer);
procedure SetMax(Value:integer);
procedure SetCancelEnabled(Value:boolean);
Function GetTerminated:boolean;
procedure SetTerminated(Value:boolean);
protected
procedure DoUpdateForm;virtual;
procedure OnTerminate(Sender:TObject);
public
constructor Create(AOwner: TComponent);override;
destructor Destroy; override;
function Run:integer;
procedure BeginUpdate;
procedure EndUpdate;
published
property Caption:TCaption read FCaption write SetCaption;
property CancelEnabled:boolean read FCancelEnabled write SetCancelEnabled;
property Text:TCaption read FText write SetText;
property Position:integer read FPosition write SetPosition;
property Max:integer read FMax write SetMax;
property OnExecute:TOnExecute read FOnExecute write FOnExecute;
property Terminated:boolean read GetTerminated write SetTerminated;
end;
procedure Register;
implementation
{$R *.dfm}
procedure Register;
begin
RegisterComponents('Samples', [TThreadProgress]);
end;
{ TCustomThread }
procedure TCustomThread.Execute;
begin
if assigned(FOnExecute) then
try
FOnExecute(FThreadProgress);
except
ApplicationHandleException(self);
end;
end;
{ TThreadProgress }
constructor TThreadProgress.Create(AOwner: TComponent);
begin
inherited;
FOnExecute:=nil;
FProgressForm:=nil;
FCaption:='Подождите';
FText:='Работаю...';
FPosition:=0;
FMax:=100;
FCancelEnabled:=true;
FUpdateCount:=0;
end;
destructor TThreadProgress.Destroy;
begin
inherited;
end;
procedure TThreadProgress.DoUpdateForm;
begin
if not assigned(FProgressForm) then exit;
if FUpdateCount > 0 then Exit;
{if (FMax>0) and (FPosition>0) then
FText:=IntToStr(Round((GetTickCount-FBeginTime)*(FMax-FPosition)/FPosition));}
if FProgressForm.Caption<>FCaption then
FProgressForm.Caption:=FCaption;
//if FProgressForm.Text.Caption<>FText then
FProgressForm.Text.Caption:=FText;
//if FProgressForm.ProgressBar.Position<>FPosition then
FProgressForm.ProgressBar.Position:=FPosition;
//if FProgressForm.ProgressBar.Max<>FMax then
FProgressForm.ProgressBar.Max:=FMax;
//if FProgressForm.Cancel.Enabled<>FCancelEnabled then
FProgressForm.Cancel.Enabled:=FCancelEnabled;
//FProgressForm.Update;
end;
procedure TThreadProgress.BeginUpdate;
begin
Inc(FUpdateCount);
end;
procedure TThreadProgress.EndUpdate;
begin
Dec(FUpdateCount);
if FUpdateCount = 0 then DoUpdateForm;
end;
procedure TThreadProgress.OnTerminate(Sender: TObject);
begin
if assigned(FProgressForm) then
begin
if fsModal in FProgressForm.FormState then
FProgressForm.ModalResult:=mrOk;
PostMessage(FProgressForm.Handle,WM_NULL,0,0);
end;
end;
function TThreadProgress.Run:integer;
begin
FBeginTime:=GetTickCount;
FProgressForm:=TProgressForm.Create(nil);
try
DoUpdateForm;
FThread:=TCustomThread.Create(true);
try
FThread.ThreadProgress:=self;
FThread.OnExecute:=OnExecute;
FThread.OnTerminate:=OnTerminate;
FThread.Resume;
result:=FProgressForm.ShowModal;
if not FThread.Terminated then
begin
FThread.Terminate;
FThread.WaitFor;
end;
finally
FreeAndNil(FThread);
end;
finally
FreeAndNil(FProgressForm);
end;
end;
procedure TThreadProgress.SetCancelEnabled(Value: boolean);
begin
if FCancelEnabled=Value then exit;
FCancelEnabled:=Value;
DoUpdateForm;
end;
procedure TThreadProgress.SetCaption(Value: TCaption);
begin
if FCaption=Value then exit;
FCaption:=Value;
DoUpdateForm;
end;
procedure TThreadProgress.SetMax(Value: integer);
begin
if FMax=Value then exit;
FMax:=Value;
DoUpdateForm;
end;
procedure TThreadProgress.SetPosition(Value: integer);
begin
if FPosition=Value then exit;
FPosition:=Value;
DoUpdateForm;
end;
procedure TThreadProgress.SetText(Value: TCaption);
begin
if FText=Value then exit;
FText:=Value;
DoUpdateForm;
end;
function TThreadProgress.GetTerminated: boolean;
begin
if assigned(FThread) then
result:=FThread.Terminated
else
result:=true;
end;
procedure TThreadProgress.SetTerminated(Value: boolean);
begin
if assigned(FThread) then
if Value then
FThread.Terminate;
end;
end.
Использовать:
...
ThreadProgress1.OnExecute:=ThreadProgress1Execute;
ThreadProgress1.Run;
...
procedure TForm1.ThreadProgress1Execute(Progress: TThreadProgress;
Thread: TCustomThread);
var i:integer;
begin
for i:=0 to 100 do
begin
Progress.Position:=i;
Sleep(100);
if (i mod 20)=0 then Sleep(100);
end;
end;
liver (2005-05-31 12:27:00) [2]ShowModal не катит, так как пока не будет ModalResult код дальше выполняться не будет.
liver (2005-05-31 12:26:00) [3]нет, не в потоке.
а уведомлять как, да передавать продцедуре, текущее значение цикла и максимальное. ну и все, прогресс сам отрисует проценты.
Erik1 (2005-05-31 12:20:00) [4]Ты уже знаеш как будеш уведомлять форму о выполненом проценте обработаных данных?
И как ты собираешся даные обаратывать? В отдельнм потоке или как?
_silver (2005-05-31 12:18:00) [5]liver (31.05.05 12:15) [7]
ShowModal?
liver (2005-05-31 12:15:00) [6]есть массив определенной длины...
вот и хочу показывать пользователю состояние обработки...
короче говоря проценты.
Формачка статуса с прогрессбаром...
чтоб показывалась форма с бегущим статусбаром, а форма из которой вызвана была эта форма была неактивной
Игорь Шевченко (2005-05-31 12:11:00) [7]
> чёт я не понял...
Это пройдет. Когда поймешь, что вопросы нужно задавать так, чтобы их смысл был понятен не только тебе. Иначе это не вопрос, а флуд.
liver (2005-05-31 12:10:00) [8]http://softwarer.ru/Describe/describe_splash.html
то что мне нужно, но форма неактивная...с ней нельзя работать...
liver (2005-05-31 12:09:00) [9]ну как форму скриэйтить я в курсе...
как форму, с которой была вызвана форма статуса, залочить...
ну а потом соответственно сделать доступной...
Enable := False не предлагать...
liver (2005-05-31 12:07:00) [10]чёт я не понял...
Anatoly Podgoretsky (2005-05-31 12:07:00) [11]CreateForm/TFormX.Create
Игорь Шевченко (2005-05-31 12:02:00) [12]TProgressBar ?
TGauge ?
Поискать в папке Demos по этим словам ?