![]() |
|
|
|
|
#1
|
|||
|
|||
|
использую компонент sevenzip.
процедура распаковки выглядит так Код:
function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
begin
if total then
form1.ProgressBar1.Max := value else
form1.ProgressBar1.Position := value;
Result := S_OK;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
arhives:tstringlist;
begin
arhives.create;
arhives.add:='test.7z';
arhives.add:='test2.7z';
with CreateInArchive(CLSID_CFormat7z) do
for i:=0 to archives.count=-1 do
begin
OpenFile(arhives[i]);
SetProgressCallback(nil, ProgressCallback);
ExtractTo('c:\1');
end;
end;как сделать обший прогресс бар на все архивы и как сделать лабел с именем извлекаемого файла ? |
|
#2
|
|||
|
|||
|
1. Делаешь приведение total к 100%
2. Max у прогрессбара ставишь на [кол-во архивов]*100. 3. Запоминаешь номер обрабатываемого архива. 4. Текущее значение распаковки конкретного рахива будет (N-1)*100 + value Алгоритм даст тебе общий прогрессбар, но его части будут заполняться неравномерно. Можно выяснить размеры архивов и пересчитывать total и value с соотв. коэф. Вопрос, оно тебе нужно? |
|
#3
|
|||
|
|||
|
нужно)
я в делфи не сильно силён, поподробней)) Код:
if total=100 then
form1.ProgressBar1.Max := archives.count*100 else
form1.ProgressBar1.Position := archives[i]-1;
Result := S_OK;в каком направлении копать чтоб сделать плавный прогрессбар? есть ещё пример для архиватора Freearc. там тоже как ни крутил не получалсоь общий прогрессбар. приду домой скину пример. |
|
#4
|
||||
|
||||
|
Там спецом передается аргумент "total: boolean", если он true, значит в value значение общего прогресса, иначе прогресс текущего файла.
|
|
#5
|
|||
|
|||
|
если ставлю total в false вообще ничё не показывает.
http://rghost.ru/49750502 тут прмер исползование unarc.dll. тож самое, не могу настроить общий прогрессбар. максимум что получилось это он останавливается там где должен след архив начаться. |
|
#6
|
|||
|
|||
|
Цитата:
Нет, не так. Как-то так: Код:
if total then
form1.ProgressBar1.Max := archives.count*100 else
form1.ProgressBar1.Position := (i-1)*100 + value;
Result := S_OK; |
|
#7
|
|||
|
|||
|
Цитата:
всё равно показует каждый архив в отдельности, только ещё хуже) сразу прогрес заполняется и приложение подвисает до след архива. подскажи лучше как сделать через размеры архивов. может напрямую через 7z.dll будет проще? да кстате если сделать лабел с именем архива так label2.Caption:='извлекается архив '+archives.strings[i]; то имя появляется только на последнем архиве. Последний раз редактировалось Deep88, 27.10.2013 в 21:48. |
|
#8
|
|||
|
|||
|
Цитата:
Имя появляется только в конце по другой причине, тк пока идет обработка, у тебя не обрабатывается очередь сообщений, соотв. не проходит отрисовка. Ты для начала сделай, что бы у тебя нормально отрабатывалось в общем случае, потом уже будешь биться над сглаживанием. Еще раз. Код:
type
TForm1 = class(TForm)
public
// Текущий архив
ArcNum : Integer;
// Total текущего архива
ArcLen : Integer;
...
function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
begin
if total
then form1.ArcLen := value
else form1.ProgressBar1.Position := ArcNum*100 + 100*value/ArcLen;
Result := S_OK;
// Даем отрисоваться обновлению
Application.ProcessMessages;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
arhives:tstringlist;
begin
arhives.create;
arhives.add:='test.7z';
arhives.add:='test2.7z';
// инициализируем прогресс бар
ProgressBar1.Max := archives.count*100;
ProgressBar1.Position := 0;
ArcNum := 0;
ArcLen := 0;
with CreateInArchive(CLSID_CFormat7z) do
for i:=0 to archives.count-1 do
begin
OpenFile(arhives[i]);
SetProgressCallback(nil, ProgressCallback);
ExtractTo('c:\1');
Inc(ArcNum);
end;
end;ЗЫ. Кстати, а чем тебя не устроит вариант с 2мя прогресс барами. Один показывает прогресс извлечения из текущего архива, второй - общий, по кол-ву обработанных архивов. |