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

Вниз

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

 
qwerty2   (2003-05-21 18:49) [0]

При выполнении какого нибудь проолжительного действия например выполнение запроса нужно отобразить ProgressBar с произвольно движущимся указателем. Как этого можно добится ведь весь процесс занят выполнением запроса и никакие другие события (например OnTimer) не срабатывают?


 
Юрий Зотов ©   (2003-05-21 18:51) [1]

Запускаете продолжительное действие в отдельном потоке, при этом ProgressBar работает в основном.


 
Переяслов Григорий ©   (2003-05-21 19:04) [2]

А ProcessMessages в цикле запроса не поможет?


 
Юрий Зотов ©   (2003-05-21 19:09) [3]

Поможет. Если у запроса есть цикл.
:о)


 
qwerty2   (2003-05-22 10:56) [4]

А как можно сделать, чтоб этот отдельный поток уведомил основной, что он завершился? например
procedure TForm1.Button1Click(Sender: TObject);
...
Form1.Timer1.Enabled:=true;
thr1:=thr.create;// поток в котором происходит длительное действие
...// действия которые нужно выполнить только когда поток завершится ...

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+2;//во время выполнения потока движется указатель Progressbara
end;



 
qwerty2   (2003-05-22 10:56) [5]

А как можно сделать, чтоб этот отдельный поток уведомил основной, что он завершился? например
procedure TForm1.Button1Click(Sender: TObject);
...
Form1.Timer1.Enabled:=true;
thr1:=thr.create;// поток в котором происходит длительное действие
...// действия которые нужно выполнить только когда поток завершится ...

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+2;//во время выполнения потока движется указатель Progressbara
end;



 
Юрий Зотов ©   (2003-05-22 10:58) [6]

F1 - TThread.OnTerminate.


 
qwerty2   (2003-05-22 23:12) [7]

И опять проблема...
я в отдельном потоке выполняю открытие некоего COM сервера (напр. Worda) которое занимает много времени а пользователю пустить ProgressBar
и что удмвительно:
в момент выполнения этой строчки CreateOleObject("Word.Application"); происходит ошибка времени выполнения - Не был произведен вызов CoInitialize. То же самое если использовать раннее связывание и явный вызов того самого CoInitialize.
вот полный текст программы
unit UniThr;
interface
uses
Windows, Messages, ComObj, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
ProgressBar1: TProgressBar;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
public
end;

type thr=class(TThread)
constructor create;
public
procedure Execute; override;
procedure SPr;
procedure ProcThr;
end;

var
Form1: TForm1;
thr2:thr;

implementation
{$R *.dfm}
constructor thr.create;
begin
inherited create(false);
end;

procedure thr.execute;
begin
spr;
end;

procedure thr.SPr;
begin
ProcThr;
end;

procedure thr.ProcThr;
var i,j,x:integer;
vv:variant;
begin
x:=0;
CreateOleObject("Word.Application");
for i:=0 to 100000 do
for j:=0 to 25000 do
inc(x);
Form1.Edit1.Text:=inttostr(x);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Timer1.Enabled:=true;
thr2:=thr.create;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Progressbar1.Position:=Progressbar1.Position+5;
end;
end.

Ошибки не возникает если вызов ProcThr обернуть в synchronize. Но желанный эффект с ProgressBarом при этом конечно же больше не наблюдается.


 
Тих   (2003-05-22 23:28) [8]

В CoInitialize(0) надо вызывать в конструкторе потока.




 
AbrosimovA   (2003-05-23 11:19) [9]

В своей программе я пользуюсь компонентом Gauge, но суть задачи
была такая же, как и у qwerty2. Когда я считывал большие объемы
данных из файла и записывал их в таблицу Excel, то видел что
часы в программе(в основной форме) останавливались, а это выглядело не очень.
Для решения этой проблемы, я создал отдельную форму под именем GaugeForm с Gauge посередине.

Для чтения данных из файла:

procedure TMainForm.ReadClick(Sender: TObject);
begin
GaugeForm.Caption:="Чтение данных из файла";
GaugeForm.Gauge1.Progress:=0;
GaugeForm.Show;
GaugeForm.Update; //Без Update на экран всплывает окно без Gauge
MainForm.Hide;//Скрываю гланую форму
ReadDataFromFile; //Длительн. процедура чтения данных из файла
Flag:=true;//Разрешить запись в Excel
SplashForm.Hide;
MainForm.Show;
end;


Для записи в Excel:

procedure TMainForm.SaveClick(Sender: TObject);
begin
GaugeForm.Caption:="Создание документа";
GaugeForm.Gauge1.Progress:=0;
GaugeForm.Show;
GaugeForm.Update;
MainForm.Hide;
SaveDataToExcel;//Длительн.процедура записи данных в Excel
GaugeForm.Hide;
MainForm.Show;
end;


Так как при чтении(или записи) выполняются только процедура ReadDataFromFile(или SaveDataToExcel) и таймеры стоят, то
формирование процента выполненной работы и заливки Gauge я запихал именно в работающую в данный момент процедуру.

Если логика будет не совсем понятна, то пиши.


 
Boris K.   (2003-05-23 17:13) [10]

Я почти так же сделал в своей программе - вызывается процедура копирования огромного файла, и в ней после BlockRead обновляется Gauge... Но! Пока читается блок - всё замерло. Эту проблему никак не побороть? (просьба - "Application.ProcessMessages" и change "BlockSize" не предлагать !!!) :)


 
AbrosimovA   (2003-05-26 11:10) [11]

Привожу кусочек кода чтения из файла, в котором идет также формирование процентов для Gauge и все работает:

procedure FileParam;
begin
FullPath:=Dir+"\"+NameFile;
AssignFile(FTrnH,FullPath);
Reset(FTrnH,1);
BlockRead(FTrnH, H, SizeOf(H), Count);
SizeB:=H.SizeBlock;
SizeTr:=H.SizeTrend;
end;

function TMainForm.Gauge(I: integer):integer;
begin
SplashForm.Update;
Inc(Progr);
Inc(S);
Result:=(S+1)*G;
SplashForm.Gauge1.Progress:=Progr;
end;

procedure TMainForm.ReadValue;
var I,J,K: integer;
begin
Value1:=TStringList.Create;
Value1.Clear;
FileParam;
G:=Round(0.01*SizeTr);
M:=G;
S:=0;
for J:=0 to SizeTr-1 do begin
BlockRead(FTrnH, V, H.SizeRec, Count);
for I:=1 to SizeB do begin
Str2:=IntToStr(I)+") "+FloatToStrF(V.ValuePar[I],
ffFixed,8,2);
Value1.Add(Str2);
end;
if J=M then M:=Gauge(J);
end;
CloseFile(FTrnH);
end;




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

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

Наверх




Память: 0.5 MB
Время: 0.021 c
3-13099
alxx
2003-05-19 11:34
2003.06.05
Backup Интербейзовой базы


1-13190
Quasar
2003-05-25 01:31
2003.06.05
Вставка символов в позиции курсора в RichEdit


1-13214
MegaVolt
2003-05-20 15:10
2003.06.05
Как сделать моё приложение активным и вынести вперёд всех окон?


14-13431
Кузькина мать
2003-05-17 12:03
2003.06.05
Supreme 2 набирает популярность


14-13467
Анат
2003-05-18 13:01
2003.06.05
Графический редактор.