Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Компоненты и классы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.10.2013, 01:17
Deep88 Deep88 вне форума
Прохожий
 
Регистрация: 27.10.2013
Сообщения: 8
Версия Delphi: xe4
Репутация: 10
По умолчанию 7z архивы

использую компонент 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  
Старый 27.10.2013, 06:01
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

1. Делаешь приведение total к 100%
2. Max у прогрессбара ставишь на [кол-во архивов]*100.
3. Запоминаешь номер обрабатываемого архива.
4. Текущее значение распаковки конкретного рахива будет
(N-1)*100 + value

Алгоритм даст тебе общий прогрессбар, но его части будут заполняться неравномерно. Можно выяснить размеры архивов и пересчитывать total и value с соотв. коэф. Вопрос, оно тебе нужно?
Ответить с цитированием
  #3  
Старый 27.10.2013, 08:04
Deep88 Deep88 вне форума
Прохожий
 
Регистрация: 27.10.2013
Сообщения: 8
Версия Delphi: xe4
Репутация: 10
По умолчанию

нужно)
я в делфи не сильно силён, поподробней))
Код:
 if total=100 then
    form1.ProgressBar1.Max := archives.count*100 else
     form1.ProgressBar1.Position := archives[i]-1;
   Result := S_OK;
как то так?
в каком направлении копать чтоб сделать плавный прогрессбар?
есть ещё пример для архиватора Freearc. там тоже как ни крутил не получалсоь общий прогрессбар. приду домой скину пример.
Ответить с цитированием
  #4  
Старый 27.10.2013, 10:04
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Там спецом передается аргумент "total: boolean", если он true, значит в value значение общего прогресса, иначе прогресс текущего файла.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #5  
Старый 27.10.2013, 10:41
Deep88 Deep88 вне форума
Прохожий
 
Регистрация: 27.10.2013
Сообщения: 8
Версия Delphi: xe4
Репутация: 10
По умолчанию

если ставлю total в false вообще ничё не показывает.


http://rghost.ru/49750502 тут прмер исползование unarc.dll. тож самое, не могу настроить общий прогрессбар. максимум что получилось это он останавливается там где должен след архив начаться.
Ответить с цитированием
  #6  
Старый 27.10.2013, 21:14
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от Deep88
нужно)
я в делфи не сильно силён, поподробней))
как то так?

Нет, не так.
Как-то так:
Код:
 if total then
    form1.ProgressBar1.Max := archives.count*100 else
     form1.ProgressBar1.Position := (i-1)*100 + value;
   Result := S_OK;
Ответить с цитированием
  #7  
Старый 27.10.2013, 21:36
Deep88 Deep88 вне форума
Прохожий
 
Регистрация: 27.10.2013
Сообщения: 8
Версия Delphi: xe4
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Нет, не так.
Как-то так:
Код:
 if total then
    form1.ProgressBar1.Max := archives.count*100 else
     form1.ProgressBar1.Position := (i-1)*100 + value;
   Result := S_OK;

всё равно показует каждый архив в отдельности, только ещё хуже)
сразу прогрес заполняется и приложение подвисает до след архива.

подскажи лучше как сделать через размеры архивов.
может напрямую через 7z.dll будет проще?

да кстате если сделать лабел с именем архива так
label2.Caption:='извлекается архив '+archives.strings[i];
то имя появляется только на последнем архиве.

Последний раз редактировалось Deep88, 27.10.2013 в 21:48.
Ответить с цитированием
  #8  
Старый 27.10.2013, 22:05
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от Deep88
всё равно показует каждый архив в отдельности, только ещё хуже)
сразу прогрес заполняется и приложение подвисает до след архива.

подскажи лучше как сделать через размеры архивов.
может напрямую через 7z.dll будет проще?

да кстате если сделать лабел с именем архива так
label2.Caption:='извлекается архив '+archives.strings[i];
то имя появляется только на последнем архиве.

Имя появляется только в конце по другой причине, тк пока идет обработка, у тебя не обрабатывается очередь сообщений, соотв. не проходит отрисовка.

Ты для начала сделай, что бы у тебя нормально отрабатывалось в общем случае, потом уже будешь биться над сглаживанием.

Еще раз.
Код:
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мя прогресс барами. Один показывает прогресс извлечения из текущего архива, второй - общий, по кол-ву обработанных архивов.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:17.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025