【发布时间】:2018-08-18 23:09:27
【问题描述】:
较早的 StackOverflow 主题提供了一些示例代码,用于在使用 TZipFile 时使用进度事件:
Using Delphi Toyko creating a Zip file onprocess example
如果我将它用作 MainForm,我可以使示例工作。但是我在尝试将代码转换为在单独的单元中工作时完全受阻。
每次我尝试将代码作为一个单元编译时,都会收到一条错误消息:
E2009 不兼容的类型:“方法指针和常规过程”
错误触发就行了:
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 提供有用的示例代码,那就太好了!
【问题讨论】:
-
那么我之前的评论给了你答案。
OnZipProgressEvent需要是一个对象方法,不是一个独立的过程。不要试图对事件做出自己的声明。将适当的单位添加到 uses 子句,它将为您声明它,然后使事件处理程序成为类方法,而不是独立的过程。它被声明为procedure of object,这意味着它需要是一个对象方法。 -
感谢您的快速回答。不幸的是,我在研究过程中看到了这个建议的变化,我不知道如何实现这一点。这就是为什么我正在寻找一个例子。