Delphi10.2如何使用ZipProgress
Delphi 10.2 how to use the ZipProgress
一个较早的 Whosebug 主题提供了一些示例代码,用于在使用 TZipFile
:
时使用进度事件
Using Delphi Toyko creating a Zip file onprocess example
如果我将它用作 MainForm,我能够使示例工作。但是我完全无法尝试将代码转换为在单独的单元中工作。
每次尝试将代码编译为一个单元时,都会收到错误消息:
E2009 Incompatible types: 'method pointer and regular procedure'
线路触发错误:
TZipFile.ZipDirectoryContents('C:\temp\Test.zip','c:\temp\zipTest',zcDeflate,OnZipProgressEvent);
我研究了所有我能想到的方法,并尝试了所有的替代方法,但没有成功。
谁能解释一下如何使 OnZipProgressEvent
代码在单独的单元中工作?
这是我目前拥有的单位代码:
unit ZipDelphiNative;
interface
uses
Windows,SysUtils, StrUtils, Variants, MaskUtils, Dialogs,StdCtrls,
Graphics, Menus,Classes, ClipBrd, System.Zip, Winapi.Messages,
System.Generics.Collections, system.ioutils, system.types,
Forms,ComCtrls, DateUtils;
Type
TZipProgressEvent = procedure(Sender: TObject; FileName: string; Header: TZipHeader; Position: Int64) of object;
// TZipProgressEvent = procedure(Sender: TObject; FileName: string; Header: TZipHeader; Position: Int64);
function jrCreateZipFromFolder(inZipName : string; inSourcePath : string; inTargetPath : string) : boolean;
procedure OnZipProgressEvent (Sender: TObject; FileName: string; Header: TZipHeader; Position: Int64);
var
PreviousFilename : string;
implementation
uses
Unit1;
function jrCreateZipFromFolder(inZipName : string; inSourcePath : string; inTargetPath : string) : boolean;
//inTargetPath is already confirmed to be valid
//Zips all files in inSourcePath & subfolders
var
Zip : TZipFile;
// ZipCallBack: TZipProgressEvent;
sZipName, sSourceName : string;
begin
result := true;
// ZipCallBack := OnZipProgressEvent;
sZipName := IncludeTrailingBackslash(inTargetPath) + inZipName;
sSourceName := IncludeTrailingBackslash(inSourcePath) ;
Zip := TZipFile.Create;
try
if FileExists(sZipName) then
DeleteFile(sZipName);
// zip.ZipDirectoryContents(sZipName, sSourceName, zcDeflate, ZipCallBack); //do not store folder too
zip.ZipDirectoryContents(sZipName, sSourceName, zcDeflate, OnZipProgressEvent); //do not store folder too
zip.Close;
except
result := false;
end;
FreeAndNil(Zip);
end;
procedure OnZipProgressEvent(Sender: TObject; FileName: string;
Header: TZipHeader; Position: Int64);
begin
if PreviousFilename <> FileName then
begin
PreviousFilename := FileName;
unit1.Form1.ProgressBar1.Max := Header.UncompressedSize;
unit1.Form1.ProgressBar1.Position := Position;
end
else
// Unit1.Form1.ProgressBar1.Position := (Position * 100) div Header.UncompressedSize ;
Unit1.Form1.ProgressBar1.Position := Position;
Application.ProcessMessages;
end;
end.
我试过定义 TZipProgressEvent
有无 of object
。在这段代码中,我有两个使用 TZipProgressEvent
的选项,或者像原始示例一样,或者定义 ZipCallBack
的注释掉的版本。当在表单中使用时,两者在不同的情况下工作。在本机中使用时均无效。
所以,我对如何进行这项工作感到困惑。如果Embarcadero能提供有用的示例代码就更好了!
TZipProgressEvent
被声明为 of object
,这意味着它必须是一个对象的方法 (class)。因此,为了实现它,您需要声明一个 class 来实现具有该签名的方法(TZip
class 中的签名,而不是您编写的签名)。
这应该可以帮助您入门。将您自己的代码添加到 jrCreateZipFromFolder
和 TMyZipProgress.ShowZipProgress
的实现中,正如我在下面的代码注释中所说的那样。我已将其设为 class procedure
,因此您无需创建 TMyZipProgress
的实例即可使用它。
unit ZipDelphiNative;
interface
function jrCreateZipFromFolder(inZipName, inSourcePath, inTargetPath: string): Boolean;
implementation
{ TMyZip }
uses
System.Zip;
type
TMyZipProgress = class(TObject)
private
class procedure ShowZipProgress(Sender: TObject; FileName: string;
Header: TZipHeader; Position: Int64);
end;
function jrCreateZipFromFolder(inZipName, inSourcePath,
inTargetPath: string): boolean;
var
FZip: TZipFile;
begin
Result := False;
FZip := TZipFile.Create;
try
// Rest of your zip file code here, then call
FZip.ZipDirectoryContents(sZipName, sSourceName, zcDeflate, TMyZipProgress.ShowZipProgess);
Result := True;
finally
FZip.Free;
end;
end;
class procedure TMyZipProgress.ShowZipProgress(Sender: TObject; FileName: string;
Header: TZipHeader; Position: Int64);
begin
// Show your progress here, whatever it needs to do
end;
end.
一个较早的 Whosebug 主题提供了一些示例代码,用于在使用 TZipFile
:
Using Delphi Toyko creating a Zip file onprocess example
如果我将它用作 MainForm,我能够使示例工作。但是我完全无法尝试将代码转换为在单独的单元中工作。
每次尝试将代码编译为一个单元时,都会收到错误消息:
E2009 Incompatible types: 'method pointer and regular procedure'
线路触发错误:
TZipFile.ZipDirectoryContents('C:\temp\Test.zip','c:\temp\zipTest',zcDeflate,OnZipProgressEvent);
我研究了所有我能想到的方法,并尝试了所有的替代方法,但没有成功。
谁能解释一下如何使 OnZipProgressEvent
代码在单独的单元中工作?
这是我目前拥有的单位代码:
unit ZipDelphiNative;
interface
uses
Windows,SysUtils, StrUtils, Variants, MaskUtils, Dialogs,StdCtrls,
Graphics, Menus,Classes, ClipBrd, System.Zip, Winapi.Messages,
System.Generics.Collections, system.ioutils, system.types,
Forms,ComCtrls, DateUtils;
Type
TZipProgressEvent = procedure(Sender: TObject; FileName: string; Header: TZipHeader; Position: Int64) of object;
// TZipProgressEvent = procedure(Sender: TObject; FileName: string; Header: TZipHeader; Position: Int64);
function jrCreateZipFromFolder(inZipName : string; inSourcePath : string; inTargetPath : string) : boolean;
procedure OnZipProgressEvent (Sender: TObject; FileName: string; Header: TZipHeader; Position: Int64);
var
PreviousFilename : string;
implementation
uses
Unit1;
function jrCreateZipFromFolder(inZipName : string; inSourcePath : string; inTargetPath : string) : boolean;
//inTargetPath is already confirmed to be valid
//Zips all files in inSourcePath & subfolders
var
Zip : TZipFile;
// ZipCallBack: TZipProgressEvent;
sZipName, sSourceName : string;
begin
result := true;
// ZipCallBack := OnZipProgressEvent;
sZipName := IncludeTrailingBackslash(inTargetPath) + inZipName;
sSourceName := IncludeTrailingBackslash(inSourcePath) ;
Zip := TZipFile.Create;
try
if FileExists(sZipName) then
DeleteFile(sZipName);
// zip.ZipDirectoryContents(sZipName, sSourceName, zcDeflate, ZipCallBack); //do not store folder too
zip.ZipDirectoryContents(sZipName, sSourceName, zcDeflate, OnZipProgressEvent); //do not store folder too
zip.Close;
except
result := false;
end;
FreeAndNil(Zip);
end;
procedure OnZipProgressEvent(Sender: TObject; FileName: string;
Header: TZipHeader; Position: Int64);
begin
if PreviousFilename <> FileName then
begin
PreviousFilename := FileName;
unit1.Form1.ProgressBar1.Max := Header.UncompressedSize;
unit1.Form1.ProgressBar1.Position := Position;
end
else
// Unit1.Form1.ProgressBar1.Position := (Position * 100) div Header.UncompressedSize ;
Unit1.Form1.ProgressBar1.Position := Position;
Application.ProcessMessages;
end;
end.
我试过定义 TZipProgressEvent
有无 of object
。在这段代码中,我有两个使用 TZipProgressEvent
的选项,或者像原始示例一样,或者定义 ZipCallBack
的注释掉的版本。当在表单中使用时,两者在不同的情况下工作。在本机中使用时均无效。
所以,我对如何进行这项工作感到困惑。如果Embarcadero能提供有用的示例代码就更好了!
TZipProgressEvent
被声明为 of object
,这意味着它必须是一个对象的方法 (class)。因此,为了实现它,您需要声明一个 class 来实现具有该签名的方法(TZip
class 中的签名,而不是您编写的签名)。
这应该可以帮助您入门。将您自己的代码添加到 jrCreateZipFromFolder
和 TMyZipProgress.ShowZipProgress
的实现中,正如我在下面的代码注释中所说的那样。我已将其设为 class procedure
,因此您无需创建 TMyZipProgress
的实例即可使用它。
unit ZipDelphiNative;
interface
function jrCreateZipFromFolder(inZipName, inSourcePath, inTargetPath: string): Boolean;
implementation
{ TMyZip }
uses
System.Zip;
type
TMyZipProgress = class(TObject)
private
class procedure ShowZipProgress(Sender: TObject; FileName: string;
Header: TZipHeader; Position: Int64);
end;
function jrCreateZipFromFolder(inZipName, inSourcePath,
inTargetPath: string): boolean;
var
FZip: TZipFile;
begin
Result := False;
FZip := TZipFile.Create;
try
// Rest of your zip file code here, then call
FZip.ZipDirectoryContents(sZipName, sSourceName, zcDeflate, TMyZipProgress.ShowZipProgess);
Result := True;
finally
FZip.Free;
end;
end;
class procedure TMyZipProgress.ShowZipProgress(Sender: TObject; FileName: string;
Header: TZipHeader; Position: Int64);
begin
// Show your progress here, whatever it needs to do
end;
end.