Вверх ↑
Этот топик читают: Гость
Ответов: 824
Рейтинг: 138
#1: 2014-08-09 16:27:10 ЛС | профиль | цитата
Всем, здравствуйте!

Решил прикрутить к HiAsm 7 zip (7z.dll)
В общем, получилось.
Использовал для этого 7zip API
Кроме того, для правильной работы 7zip API пришлось прикрутить к HiAsm Delphi 7.
Закинул sevenzip.pas в \HiAsm_AltBuild\Elements\delphi\code\

Но ввиду моих незначительных знаний в Delphi не все получается...
Вот текст моего IC
IC code

#pas
unit HiAsmUnit;

interface

uses kol, Share, Debug, sevenzip, Messages;


type
THiAsmClass = class(TDebug)
private

public
//Data
SourseFile:THI_Event; //Файл архива для извлечения или файл для сжатия
DestPatch:THI_Event; //Каталог для извлечения
OutFile:THI_Event; //Имя файла архива
CLevel:THI_Event; //Степень сжатия
CMethod:THI_Event; //Метод сжатия
//Event
onFinish:THI_Event; //Событие после завершения сжатия/извлечения
onProgress:THI_Event; //Устанавливает текущее значение прогресс-бара
onProgressMax:THI_Event;//Устанавливает максимальное значение прогресс-бара
//doWork
procedure doExtract(var _Data:TData; Index:Word); //Извлечение файлов из архива в указанный каталог
procedure doCreate(var _Data:TData; Index:Word); //Сжатие указанного файла

function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall; //Функция вывода данных на прогресс-бар

end;

implementation

var sf: String;
dp: String;
ouf: String;

function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall; //Функция вывода данных на прогресс-бар
begin
if total then
_hi_onEvent(onProgressMax, value) else //Error: Undeclared identifier: 'onProgressMax', Error: There is no overloaded version of '_hi_OnEvent' that can be called with these arguments
_hi_onEvent(onProgress, value); //Error: Undeclared identifier: 'onProgress', Error: There is no overloaded version of '_hi_OnEvent' that can be called with these arguments
Result := S_OK;
end;


procedure THiAsmClass.doExtract; //Извлечение файлов из архива в указанный каталог
begin
sf:= ReadString(_Data,SourseFile);
dp:= ReadString(_Data,DestPatch);

with CreateInArchive(CLSID_CFormat7z) do
begin
OpenFile(sf);
ExtractTo(dp);
end;
_hi_OnEvent(onFinish,'');
end;

procedure THiAsmClass.doCreate; //Сжатие указанного файла
var
Arch: I7zOutArchive;
Met: T7zCompressionMethod; //T7zCompressionMethod = (m7Copy, m7LZMA, m7BZip2, m7PPMd, m7Deflate, m7Deflate64)
begin
sf:= ReadString(_Data,SourseFile);
ouf:= ReadString(_Data,OutFile);
Met:= ReadData(_Data, CMethod); //#### Как правильно считать данные с точки? ####
Arch:= CreateOutArchive(CLSID_CFormat7z);
begin
Arch.AddFile(sf, ExtractFileName(sf)); //Указываем файл для сжатия
SetCompressionLevel(Arch, ReadInteger(_Data, CLevel));//Устанавливаем степень сжатия
SevenZipSetCompressionMethod(Arch, Met);//Устанавливаем метод сжатия Error: Incompatible types: 'T7zCompressionMethod' and 'TData' ####
Arch.SetProgressCallback(nil, ProgressCallback); //Взываем функцию вывода информации на прогресс-бар
Arch.SaveToFile(ouf) //Указываем имя архива
end;
Arch:= nil;
_hi_OnEvent(onFinish, '');
end;

end.
Ошибки описаны в комментариях к строчкам в IC.
Собственно, просьба помочь исправить эти ошибки.

карма: 1

0
Ответов: 4630
Рейтинг: 749
#2: 2014-08-09 18:06:36 ЛС | профиль | цитата
К полю onProgressMax можно обращаться только из методов класса THiAsmClass, либо через экземпляр класса.
procedure THiAsmClass.doCreate; является методом класса, поэтому обращаться к своим полям можно.
function ProgressCallback просто глобальная процедура и не знает о существовании THiAsmClass. Для таких случаев в callback-функцию предусматривается передача пользовательского параметра. Таким параметром можно передать указатель на экземпляр класса THiAsmClass, через который можно будет получить доступ к его полям. Смотри API. В частности, что значит параметр
ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;


sashaoli писал(а):
Кроме того, для правильной работы 7zip API пришлось прикрутить к HiAsm Delphi 7
Уверен, там нет ничего особенного, чтобы оно не работало и на старом Delphi.

sashaoli писал(а):
Как правильно считать данные с точки?
Met := T7zCompressionMethod(ReadInteger(_Data, CMethod));

------------ Дoбавленo в 18.06:

#pas
function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
begin
if total then
_hi_onEvent(THiAsmClass(sender).onProgressMax, value) else
_hi_onEvent(THiAsmClass(sender).onProgress, value);
Result := S_OK;
end;

procedure THiAsmClass.doCreate;
var
...
begin
...
Arch.SetProgressCallback(Self, ProgressCallback);
...
end;
карма: 26

0
Ответов: 824
Рейтинг: 138
#3: 2014-08-09 18:27:01 ЛС | профиль | цитата
Спасибо.
Честно - "экземпляр класса", "метод класса" "указатель на экземпляр класса" - если сказать мягко, для меня темный лес.
Не понимаю, не доходит - читаю и "Ни в зуб ногою"
Мне стыдно...

Сейчас попробую.....
карма: 1

0
Ответов: 4630
Рейтинг: 749
#4: 2014-08-09 19:51:04 ЛС | профиль | цитата
Попробую объяснить.

Пусть у нас есть определение такого класса:

#pas
type
TMyClass = class
Field1: Integer;
Field2: Integer;
end;
Это только описание класса - чтобы компилятор знал какие поля и методы в нем есть (методов сейчас мы не задали).
Это определение не зря лежит в секции type - мы можем объявлять переменные этого типа.
Переменная - это адрес участка в оперативной памяти, в котором лежат данные указанного типа. Раз переменная некоторого типа располагается в памяти, то:
1) компилятор (а также программист) должен точно знать размер этого типа, чтобы выделить нужное количество памяти.
2) должна быть выделена память необходимого размера. Для некоторых типов память выделяется автоматически при объявлении переменной указанного типа, а для некоторых - нужно вручную вызывать некоторые функции для выделения памяти (такие типы называются динамическими, также память выделяется вручную для ссылочных типов и вообще для произвольных структур, размер которых меняется в процессе работы программы).

Переменные так называемых простых типов хранят собственно значение, которое передается в функции, копируется при присваивании и т.п.

Другие стандартные типы даных являются ссылочными типами: переменная такого типа содержит не сами данные, а только адрес (длиной 4 байта) этих данных в памяти. При передачи таких переменных в функции, передается только адрес данных, что избавляет от необходимости каждый раз делать копию данных, на которые указывает переменная. Также при присваивании значения одной переменной другой, копируется только адрес данных. Таким образом две переменные указывают на одни и те же данные в памяти. Такой адрес называется указателем. Универсальный тип для хранения указателей называется Pointer.

Класс - это динамический ссылочный тип.
Будем называть классом само определение полей, как в примере выше. То-есть, когда мы описываем класс в секции type, это описание никакой памяти не занимает и с ним ничего не можно делать.
Динамический тип значит, что память под него нужно выделять и удалять вручную.
Ссылочный - значит переменные данного типа хранят только адрес и имеют размер 4 байта.
Тогда экземпляр класса - это память, выделенная для данного класса. Для сокращения также будем называть экземпляр класса термином "объект", хотя это не совсем верно. Если мы объявим переменную типа TMyClass, то она будет содержать адрес некоторого экземпляра, адрес объекта. А может содержать 0-вой адрес (специальное ключевое слово nil) - это значит, что данная переменная не указывает ни на какой объект.

Для выделния памяти под экземпляр класса (создание объекта) мы должны вызвать специальный метод класса, который называется конструктором. Хоть мы можем определять свои конструкторы, в любого класса по-умолчанию уже есть стандартный конструктор Create. Соотвественно, для освобождения занимаемой памяти (уничтожения объекта) используется специальный метод - деструктор. Стандартный деструктор называется Destroy. Но для уничтожения всё же обычно вызывается стандартный метод объекта Free (а уже он все равно потом вызовет Destroy).

Размер памяти, которая будет выделена при создании объекта с помощью конструктора, будет зависеть от размера и количества полей, которые мы определим в описании класса.
Например, в приведенном выше классе есть 2 поля типа Integer, которые имеют размер 4 байта. Тогда под каждый экземпляр данного класса будет выделяться 8 байт (реально больше, так как каждый объект имеет ещё и служебную информацию; если данный класс наследуется от других классов, то занимаемый объем есть суммой объемов данного и всех родительских классов).

Приступим к практике:


#pas
// Объявим переменную для хранения нашего объекта (а точнее, адреса на него)
var
MyObject: TMyClass; // Переменная изначально хранит nil, то-есть не указывает ни на какой объект

// Поработаем с нашим классом
procedure Test;
begin
// Выделим память с помощью конструктора и присвоим её адрес нашей переменной
MyObject := TMyClass.Create; // Конструктор возвращает адрес на новосозданный объект

// Теперь мы можем работать с объектом:
MyObject.Field1 := 123;
MyObject.Field2 := MyObject.Field1 + 222;

// Никогда не забываем освободить память, когда объект больше не нужен
MyObject.Free;
// Вызов метода Free освободил занимаемую память, но переменная MyObject всё ещё содержит
// адрес бывшего объекта. По этому адресу теперь будут записаны какие-то другие данные,
// а значит после вызова Free мы уже не имеем права обращаться к полям и методам объекта MyObject,
// пока не создадим новый объект и присвоим его адрес этой переменной.
// Чтобы знать, что переменная не указывает на действительный объект, присвоим ей 0-вой адрес:
MyObject := nil;
end;
Класс может содержать методы - функции, которые выполняют некоторую работу и оперируют полями экземпляра класса.
Когда в классе появляется метод, его нужно дополнительно описать в секции implementation.

Пример:

#pas
type
TMyClass = class
Field1: Integer;
Field2: Integer;

function GetSum: Integer;
end;

implementation


function TMyClass.GetSum: Integer;
begin
// В методах своего класса мы можем обращаться к своим полям. А точнее, эти поля будут принадлежать
// тому объекту, для которого мы вызываем метод (текущий объект).
Result := Field1 + Field2;
//Для получения адреса текущего объекта в методе можно обратится к предопределенной переменной Self
// Строчка выше может быть записана как
// Result := Self.Field1 + Self.Field2;
// Этот свой адрес мы можем передавать в различные сторонние функции и т.п.
end;

procedure Test;
var
i: Integer;
begin
MyObject := TMyClass.Create;

// Присвоим значения полям
MyObject.Field1 := 123;
MyObject.Field2 := 222;

// Получим их сумму, вызвав метод объекта:
i := MyObject.GetSum;
// Метод GetSum будет оперировать полями объекта, заданного в MyObject

// В отличии от конструктора TMyClass.Create
// мы не должны вызывать метод как TMyClass.GetSum, потому что методу нужно оперировать с
// уже созданным объектом. Тогда как для конструктора объекта ещё не существует и он как раз
// используется для создания экземпляра объекта.

MyObject.Free;
MyObject := nil;
end;
Исходя из этого можно объснить, что я сделал в твоем коде:

#pas
Arch.SetProgressCallback(Self, ProgressCallback);
Я передал свой адрес (Self), указав его в SetProgressCallback

#pas
function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
begin
if total then
_hi_onEvent(THiAsmClass(sender).onProgressMax, value) else
_hi_onEvent(THiAsmClass(sender).onProgress, value);
Result := S_OK;
end;
Когда API вызовет ProgressCallback, оно передаст туда этот же адрес в качестве параметра sender Поскольку это может быть любой адрес, а не только на мой объект, то он объявлен в функции как Pointer.
API этот адрес не интересует, оно просто передаст его в callback-функцию.
А раз так, то мы должны явно указать компилятору, чем мы считаем этот адрес. А считаем мы его указаывающим на объект типа THiAsmClass (ведь адрес именного такого объекта мы передали). Делаем мы это с помощью приведения типа THiAsmClass(sender). В таком случае мы уже можем обращаться к полям и методам объекта.
карма: 26

2
Голосовали:sla8a, sashaoli
Ответов: 824
Рейтинг: 138
#5: 2014-08-09 20:30:29 ЛС | профиль | цитата
Netspirit писал(а):
Попробую объяснить.

Это нужно переварить...
Вечером сяду и внимательно перечитаю.
[flood]Жена готовится к консервированию и вечно ей чего то нужно, откуда то принести... [/flood]


карма: 1

0
Ответов: 2267
Рейтинг: 676
#6: 2014-08-09 23:25:08 ЛС | профиль | цитата
Netspirit,
flood
а разве до:
#pas
MyObject := TMyClass.Create;
и после:
#pas
MyObject.Free;
класс MyObject не равен nil? До прочтения вашего поста, считал что если не создан или уничтожен, то по умолчанию nil. И вот в этом: MyObject := nil; нет необходимости.
карма: 11

0
Разработчик
Ответов: 26155
Рейтинг: 2127
#7: 2014-08-10 00:46:02 ЛС | профиль | цитата
sla8a, нет, не равен. Переменная MyObject будет содержать указатель на несуществующую область памяти. free не очищает указатель, а только освобождает выделенную под экземпляр класса память. Для обнуления переменной класса и освобождения памяти существует специальная процедура -- free_and_nil
карма: 22

1
Голосовали:sla8a
Ответов: 9906
Рейтинг: 351
#8: 2014-08-10 01:21:26 ЛС | профиль | цитата
[offtop]Free - метод.
а free_and_nil - не метод. А просто procedure... Правда, с var-аргументом.

А вообще-то, все вычисляется ЛОГИЧЕСКИ. Не заглядывая в буквари, используя только свои мозги.
Метод (в том числе и Free) имеет первым своим параметром Self - адрес объекта. Но он понятия не имеет, в какой переменной хранится этот адрес.
Следовательно, и обнулить он ничего не может. Даже если бы захотел
[/offtop]
карма: 9

0
Разработчик
Ответов: 26155
Рейтинг: 2127
#9: 2014-08-10 01:51:43 ЛС | профиль | цитата
[offtop]
Galkov писал(а):
а free_and_nil - не метод. А просто procedure... Правда, с var-аргументом.

Да, все правильно, ведь она не относится ни к какому классу[/offtop]

карма: 22

0
Ответов: 824
Рейтинг: 138
#10: 2014-08-10 11:50:33 ЛС | профиль | цитата
Netspirit, кое-что уже понятно, "истественно" пока не все могу представить в "моске", как-бы картинка не полная...
Вот Вы сказали, ProgressCallback глобальная функция, но ведь она объявлена в классе THiAsmClass, и она не может обратится к методам класса THiAsmClass.
И мне это не понятно. Разве что - это декларация использования функции в классе?
Предполагаю, если-бы я описал функцию вот так
#pas
function THiAsmClass.ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
begin
if total then
_hi_onEvent(onProgressMax, value) else
_hi_onEvent(onProgress, value);
Result := S_OK;
end;
то она, увидела бы методы onProgressMax и onProgress.
карма: 1

0
Ответов: 4630
Рейтинг: 749
#11: 2014-08-10 13:04:29 ЛС | профиль | цитата
sashaoli писал(а):
но ведь она объявлена в классе THiAsmClass
Ага, не заметил. Это объявление нужно вывести за пределы класса.
sashaoli писал(а):
то она, увидела бы
Да, увидела бы. Но внутреннее представление методов класса в Delphi отличается от обычных процедур и функций: в метод компилятором неявно передается тот самый адрес объекта, к полям которого мы в методе и обращаемся, и который доступен в переменной Self.
Например, если в классе есть метод
TMyClass.TestMethod(Arg1: Integer)
то вот этот вызов
MyObject.TestMethod(123)
компилятором фактически трансформируется примерно в это:
TMyClass.TestMethod(MyObject, 123)
Типа, TMyClass.TestMethod - это название обычной процедуры, описанной в секции implementation. А работать она должна с полями объекта, который мы ей передаём.
Эта методика применяется только в Delphi. В других языках это может быть реализовано по-другому. Поэтому в API не могут зашить работу только с Delphi, разрешив тебе указывать в качестве callback метод класса THiAsmClass.ProgressCallback. А вот глобальная функция, дополнительно подкрепленная ключевым словом stdcall, имеет вполне конкретную внутреннюю реализацию и будет работать с любым языком, который поддерживает соглашение stdcall.
карма: 26

0
Ответов: 824
Рейтинг: 138
#12: 2014-08-10 18:01:05 ЛС | профиль | цитата
Netspirit писал(а):
Это объявление нужно вывести за пределы класса.

Вывел, если она в классе - не компилируется проект.

code_34131.txt
Наблюдается неправильная работа прогресс-бара при работе с файлами >4 Gb. А так - "Все хорошо прекрасная маркиза..."
------------ Дoбавленo в 17.44:
Понаблюдал за работой схемы при сжатии, если файл >4 Gb та на точку onProgressMax выдаются не правильные данные.
onProgress - работает правильно.
Что-то, где-то, в sevenzip.pas не так...
По идее на точку onProgressMax должен выдаваться размер исходного файла в байтах, а не выдается...
------------ Дoбавленo в 18.01:
Во в этой схеме прогресс-бар работает правильно, но так мне не нравится...
#pas
Add(MainForm,9527681,189,98)
{
Width=413
Height=148
Caption="MAU Database Backup"
BorderStyle=1
link(onCreate,6193362:doData,[])
}
Add(InlineCode,11032646,294,315)
{
@Hint=#2:7я|45:Извлечение файлов из архива в указаную папку |
WorkPoints=#35:doExtract=Извлекает файлы из архива|23:doCreate=Сжатие в архив|
EventPoints=#41:onFinish=Событие после окончания операции|10:onProgress|13:onProgressMax|
DataPoints=#22:SourseFile=Файл архива|25:DestPatch=Путь извлечения|27:OutFile=Файл для сохранения|6:CLevel|7:CMethod|0:|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|41:uses kol,Share,Debug, sevenzip, Messages;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|9: //Data|24: SourseFile:THI_Event;|23: DestPatch:THI_Event;|21: OutFile:THI_Event;|20: CLevel:THI_Event;|21: CMethod:THI_Event;|10: //Event|22: onFinish:THI_Event;|24: onProgress:THI_Event;|27: onProgressMax:THI_Event;|11: //doWork|52: procedure doExtract(var _Data:TData; Index:Word);|51: procedure doCreate(var _Data:TData; Index:Word);|96:// function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;|5: end;|1: |14:implementation|0:|15:var sf: String;|11:dp: String;|12:ouf: String;|0:|0:|132:function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall; //Функция вывода данных на прогресс-бар|6: begin|17: if total then|61: _hi_onEvent(THiAsmClass(sender).onProgressMax, value) else|54: _hi_onEvent(THiAsmClass(sender).onProgress, value);|19: Result := S_OK;|5: end;|0:|72:procedure THiAsmClass.doExtract; //Извлечение файла в указанный каталог|5:begin|34:sf:= ReadString(_Data,SourseFile);|33:dp:= ReadString(_Data,DestPatch);|0:|40:with CreateInArchive(CLSID_CFormat7z) do|6: begin|16: OpenFile(sf);|47: SetProgressCallback(Self, ProgressCallback);|17: ExtractTo(dp);|5: end;|25:_hi_OnEvent(onFinish,');|4:end;|0:|48:procedure THiAsmClass.doCreate; //Сжатие файла|4:var |20:Arch: I7zOutArchive;|26:Met: T7zCompressionMethod;|7: begin|36: sf:= ReadString(_Data,SourseFile);|34: ouf:= ReadString(_Data,OutFile);|60:// Met:= T7zCompressionMethod(ReadInteger(_Data, CMethod));|43: Arch:= CreateOutArchive(CLSID_CFormat7z);|9: begin|43: Arch.AddFile(sf, ExtractFileName(sf));|59: SetCompressionLevel(Arch, ReadInteger(_Data, CLevel));|34: //SetMultiThreading(Arch, 4);|54: Arch.SetProgressCallback(Self, ProgressCallback);|28: Arch.SaveToFile(ouf)|11: end;|19: Arch:= nil; |27:_hi_OnEvent(onFinish, ');|5:end;|1:|4:end.|
link(onFinish,8851918:doMessage,[])
link(onProgress,13568845:doCalc,[])
link(SourseFile,15469623:Var2,[])
link(OutFile,16636503:Var2,[])
link(CLevel,5252122:Index,[])
}
Add(StyleXP,4230452,49,130)
{
}
Add(Label,12171220,125,179)
{
Left=10
Top=34
Width=92
Height=17
Caption="Сhoose Out File"
}
Add(Edit,5273902,308,182)
{
Left=100
Top=30
Width=270
Text=""
ReadOnly=0
}
Add(Thread,49940,238,322)
{
Delay=1
FastStop=0
link(onExec,11032646:doCreate,[])
}
Add(MultiElementEx,8162144,147,315)
{
link(onEvent1,16052644:doWork1,[(200,321)])
link(onEvent2,16052644:doWork2,[])
link(FileName,16636503:Var1,[(153,292)])
}
BEGIN_SDK
Add(EditMultiEx,14924651,21,21)
{
WorkCount=#12:doFileExists|
EventCount=#8:onEvent1|8:onEvent2|
DataCount=#8:FileName|
Width=174
Height=81
link(doFileExists,7893840:doFileExists,[(32,27)(32,76)])
}
Add(FileTools,7893840,49,49)
{
DelToRecycle=1
link(onEnd,3472324:doEvent,[])
link(FileName,14924651:FileName,[(55,33)(27,33)])
}
Add(IndexToChanel,3472324,91,49)
{
link(onEvent1,14924651:onEvent1,[(130,55)(130,27)])
link(onEvent2,9272160:doEvent1,[])
}
Add(Hub,9272160,133,56)
{
link(onEvent1,7893840:doDelete,[(158,62)(158,41)(39,41)(39,69)])
link(onEvent2,14924651:onEvent2,[(165,69)(165,34)])
}
END_SDK
Add(MathParse,13568845,420,322)
{
MathStr="trunc((%1/%2)*100) "
link(onResult,4774259:doPosition,[])
link(X2,8505183:FileSize,[(433,313)(411,313)(411,370)(398,370)])
}
Add(HubEx,16052644,196,322)
{
link(onEvent,49940:doStart,[])
}
Add(ComboBox,5252122,301,70)
{
@Group=71631344
Left=100
Top=55
Width=95
Height=21
Strings=#5:Store|7:Fastest|5:Faste|6:Normal|7:Maximum|5:Ultra|
Text=""
ReadOnly=0
Point(Index)
Point(doSelect)
}
Add(Label,10069394,299,20)
{
@Group=71631344
Left=10
Top=60
Width=79
Height=17
Caption="Compress Level"
}
Add(Label,7778279,49,182)
{
Left=10
Top=10
Width=71
Height=17
Caption="Сhoose In File"
}
Add(Button,12779734,176,182)
{
Left=370
Top=30
Width=25
Caption="..."
link(onClick,12843300:doExecute,[])
}
Add(Button,9444944,56,308)
{
Left=280
Top=54
Width=115
Height=23
Caption="Start"
link(onClick,4767643:doEvent1,[])
}
Add(DoData,6193362,245,112)
{
Data=Integer(3)
link(onEventData,5252122:doSelect,[])
}
Add(ProgressBarRush,4774259,469,322)
{
Left=10
Top=85
Width=385
Point(doMax)
}
Add(SDialog,12843300,259,182)
{
Filter="7 zip|*.7z"
FileName=""
Point(doFileName)
link(onExecute,5273902:doText,[])
}
Add(Edit,3866846,147,228)
{
Left=100
Top=5
Width=270
Text=""
link(onChange,4826214:doPart,[])
}
Add(Button,10710181,48,228)
{
Left=370
Top=5
Width=25
Caption="..."
link(onClick,14577979:doExecute,[])
}
Add(ODialog,14577979,98,228)
{
link(onExecute,3866846:doText,[])
}
Add(FilePartElm,4826214,196,228)
{
Mode=2
Point(Part)
link(onPart,12843300:doFileName,[(235,234)(235,195)])
}
Add(GetDataEx,16636503,308,287)
{
link(Data,5273902:Text,[])
}
Add(Message,8851918,525,315)
{
Message="Finish"
}
Add(FileAttributes,8505183,371,329)
{
Point(FileSize)
link(FileName,15469623:Var3,[(377,277)])
}
Add(Hub,4767643,105,308)
{
link(onEvent1,8505183:doRead,[(130,314)(130,363)(340,363)(340,335)])
link(onEvent2,8162144:doFileExists,[])
}
Add(GetDataEx,15469623,294,272)
{
Angle=3
link(Data,3866846:Text,[(153,277)])
}


карма: 1

0
файлы: 1code_34131.txt [5.7KB] [261]
Ответов: 16884
Рейтинг: 1239
#13: 2014-08-10 19:35:49 ЛС | профиль | цитата
sashaoli, сам пробовал скопировать выложенный код, который "в этой схеме прогресс-бар работает правильно, но так мне не нравится...",
в HiAsm
У меня не получается.
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 824
Рейтинг: 138
#14: 2014-08-10 19:47:55 ЛС | профиль | цитата
Странненько как-то схемка скопировалась....
------------ Дoбавленo в 19.47:
Add(MainForm,9527681,189,98)
{
Width=413
Height=148
Caption="MAU Database Backup"
BorderStyle=1
link(onCreate,6193362:doData,[])
}
Add(InlineCode,11032646,294,315)
{
@Hint=#2:7я|45:Извлечение файлов из архива в указаную папку |
WorkPoints=#35:doExtract=Извлекает файлы из архива|23:doCreate=Сжатие в архив|
EventPoints=#41:onFinish=Событие после окончания операции|10:onProgress|13:onProgressMax|
DataPoints=#22:SourseFile=Файл архива|25:DestPatch=Путь извлечения|27:OutFile=Файл для сохранения|6:CLevel|7:CMethod|0:|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|41:uses kol,Share,Debug, sevenzip, Messages;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|9: //Data|24: SourseFile:THI_Event;|23: DestPatch:THI_Event;|21: OutFile:THI_Event;|20: CLevel:THI_Event;|21: CMethod:THI_Event;|10: //Event|22: onFinish:THI_Event;|24: onProgress:THI_Event;|27: onProgressMax:THI_Event;|11: //doWork|52: procedure doExtract(var _Data:TData; Index:Word);|51: procedure doCreate(var _Data:TData; Index:Word);|96:// function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;|5: end;|1: |14:implementation|0:|15:var sf: String;|11:dp: String;|12:ouf: String;|0:|0:|132:function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall; //Функция вывода данных на прогресс-бар|6: begin|17: if total then|61: _hi_onEvent(THiAsmClass(sender).onProgressMax, value) else|54: _hi_onEvent(THiAsmClass(sender).onProgress, value);|19: Result := S_OK;|5: end;|0:|72:procedure THiAsmClass.doExtract; //Извлечение файла в указанный каталог|5:begin|34:sf:= ReadString(_Data,SourseFile);|33:dp:= ReadString(_Data,DestPatch);|0:|40:with CreateInArchive(CLSID_CFormat7z) do|6: begin|16: OpenFile(sf);|47: SetProgressCallback(Self, ProgressCallback);|17: ExtractTo(dp);|5: end;|25:_hi_OnEvent(onFinish,');|4:end;|0:|48:procedure THiAsmClass.doCreate; //Сжатие файла|4:var |20:Arch: I7zOutArchive;|26:Met: T7zCompressionMethod;|7: begin|36: sf:= ReadString(_Data,SourseFile);|34: ouf:= ReadString(_Data,OutFile);|60:// Met:= T7zCompressionMethod(ReadInteger(_Data, CMethod));|43: Arch:= CreateOutArchive(CLSID_CFormat7z);|9: begin|43: Arch.AddFile(sf, ExtractFileName(sf));|59: SetCompressionLevel(Arch, ReadInteger(_Data, CLevel));|34: //SetMultiThreading(Arch, 4);|54: Arch.SetProgressCallback(Self, ProgressCallback);|28: Arch.SaveToFile(ouf)|11: end;|19: Arch:= nil; |27:_hi_OnEvent(onFinish, ');|5:end;|1:|4:end.|
link(onFinish,8851918:doMessage,[])
link(onProgress,13568845:doCalc,[])
link(onProgressMax,2380161:doValue,[])
link(SourseFile,3866846:Text,[(300,285)(153,285)])
link(OutFile,16636503:Var2,[])
link(CLevel,5252122:Index,[])
}
Add(StyleXP,4230452,49,130)
{
}
Add(Label,12171220,125,179)
{
Left=10
Top=34
Width=92
Height=17
Caption="Сhoose Out File"
}
Add(Edit,5273902,308,182)
{
Left=100
Top=30
Width=270
Text=""
ReadOnly=0
}
Add(Thread,49940,238,322)
{
Delay=1
FastStop=0
link(onExec,11032646:doCreate,[])
}
Add(MultiElementEx,8162144,147,315)
{
link(onEvent1,16052644:doWork1,[(200,321)])
link(onEvent2,16052644:doWork2,[])
link(FileName,16636503:Var1,[(153,292)])
}
BEGIN_SDK
Add(EditMultiEx,14924651,21,21)
{
WorkCount=#12:doFileExists|
EventCount=#8:onEvent1|8:onEvent2|
DataCount=#8:FileName|
Width=174
Height=81
link(doFileExists,7893840:doFileExists,[(32,27)(32,76)])
}
Add(FileTools,7893840,49,49)
{
DelToRecycle=1
link(onEnd,3472324:doEvent,[])
link(FileName,14924651:FileName,[(55,33)(27,33)])
}
Add(IndexToChanel,3472324,91,49)
{
link(onEvent1,14924651:onEvent1,[(130,55)(130,27)])
link(onEvent2,9272160:doEvent1,[])
}
Add(Hub,9272160,133,56)
{
link(onEvent1,7893840:doDelete,[(158,62)(158,41)(39,41)(39,69)])
link(onEvent2,14924651:onEvent2,[(165,69)(165,34)])
}
END_SDK
Add(MathParse,13568845,399,322)
{
MathStr="trunc((%1/%2)*100) "
link(onResult,4774259:doPosition,[])
link(X2,2380161:Value,[(412,313)(391,313)(391,369)(356,369)])
}
Add(HubEx,16052644,196,322)
{
link(onEvent,49940:doStart,[])
}
Add(ComboBox,5252122,301,70)
{
@Group=80480160
Left=100
Top=55
Width=95
Height=21
Strings=#5:Store|7:Fastest|5:Faste|6:Normal|7:Maximum|5:Ultra|
Text=""
ReadOnly=0
Point(Index)
Point(doSelect)
}
Add(Label,10069394,299,20)
{
@Group=80480160
Left=10
Top=60
Width=79
Height=17
Caption="Compress Level"
}
Add(Label,7778279,49,182)
{
Left=10
Top=10
Width=71
Height=17
Caption="Сhoose In File"
}
Add(Button,12779734,176,182)
{
Left=370
Top=30
Width=25
Caption="..."
link(onClick,12843300:doExecute,[])
}
Add(Button,9444944,56,315)
{
Left=280
Top=54
Width=115
Height=23
Caption="Start"
link(onClick,8162144:doFileExists,[])
}
Add(DoData,6193362,245,112)
{
Data=Integer(3)
link(onEventData,5252122:doSelect,[])
}
Add(ProgressBarRush,4774259,448,322)
{
Left=10
Top=85
Width=385
Point(doMax)
}
Add(Memory,2380161,350,329)
{
}
Add(SDialog,12843300,259,182)
{
Filter="7 zip|*.7z"
FileName=""
Point(doFileName)
link(onExecute,5273902:doText,[])
}
Add(Edit,3866846,147,228)
{
Left=100
Top=5
Width=270
Text=""
link(onChange,4826214:doPart,[])
}
Add(Button,10710181,48,228)
{
Left=370
Top=5
Width=25
Caption="..."
link(onClick,14577979:doExecute,[])
}
Add(ODialog,14577979,98,228)
{
link(onExecute,3866846:doText,[])
}
Add(FilePartElm,4826214,196,228)
{
Mode=2
Point(Part)
link(onPart,12843300:doFileName,[(235,234)(235,195)])
}
Add(GetDataEx,16636503,308,287)
{
link(Data,5273902:Text,[])
}
Add(Message,8851918,504,315)
{
Message="Finish"
}

карма: 1

0
Ответов: 16884
Рейтинг: 1239
#15: 2014-08-10 19:47:59 ЛС | профиль | цитата
sashaoli писал(а):
Странненько как-то схемка скопировалась....
Эффект тот же.

Схемы с IC желательно архивировать.

карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)