I have a simple form, and I'm trying to work with the ProgressBar when a .zip
file is being created, based on the ZipDirectoryContents
callback. I have seen some Delphi example in the forum, but I don't know it well, and I get several errors. Here an example:
.cpp
#include <system.zip.hpp>
String PreviousFilename;
bool __fastcall createZipFromFolder( String inZipName,
String inSourcePath,
String inTargetPath )
{
bool result = true;
sZipName = "C:\\test\\testBar.zip";
sSourceName = "C:\\test2";
TZipFile* Zip = new TZipFile();
try{
if ( FileExists( sZipName ) ){
Zip->ZipDirectoryContents( sZipName, // destiny
sSourceName, // to include
zcDeflate, // compression mode
OnZipProgressEvent() ); // <--- p callback
Zip->Close();
}
}
catch(...){
result = false;
ShowMessage("Error");
}
delete Zip;
Zip = NULL;
return result;
}
void __fastcall OnZipProgressEvent( TObject* Sender, String FileName, TZipHeader Header, __int64 Position )
{
if ( PreviousFilename != FileName ){
PreviousFilename = FileName;
Form1->ProgressBar1->Max = Header.UncompressedSize;
Form1->ProgressBar1->Position = Position;
}
else{
Form1->ProgressBar1->Position = Position;
Application->ProcessMessages();
}
}
.h
#include <System.Zip.hpp>
public: // User declarations
__fastcall TForm1(TComponent* Owner);
typedef void __fastcall ( __closure * TZipProgressEvent )( TObject*,
String,
TZipHeader,
__int64 );
bool __fastcall createZipFromFolder( String inZipName,
String inSourcePath,
String inTargetPath );
void __fastcall OnZipProgressEvent( TObject* Sender,
String FileName,
TZipHeader Header,
__int64 Position );
};
extern PACKAGE TForm1 *Form1;
extern String PreviousFilename;
#endif
When calling Zip->ZipDirectoryContents()
, you need to change OnZipProgressEvent()
to &OnZipProgressEvent
instead. You are trying to call the callback (with missing parameters) when you should be passing its address.
Also, in your .cpp
file, both createZipFromFolder()
and OnZipProgressEvent()
need to be defined as being members of your Form class.
Also, in OnZipProgressEvent()
, the TZipHeader
parameter needs to be passed by const reference rather than by value, per the documentation.
Try this:
Unit1.h
...
class TForm1 : public TForm
{
...
private: // User declarations
String PreviousFilename;
void __fastcall OnZipProgressEvent( TObject* Sender,
String FileName,
const TZipHeader &Header,
__int64 Position );
public: // User declarations
__fastcall TForm1(TComponent* Owner);
bool __fastcall createZipFromFolder( String inZipName,
String inSourcePath,
String inTargetPath );
};
extern PACKAGE TForm1 *Form1;
#endif
Unit1.cpp
...
#include "Unit1.h"
#include <System.Zip.hpp>
bool __fastcall TForm1::createZipFromFolder( String inZipName,
String inSourcePath,
String inTargetPath )
{
bool result = true;
sZipName = _D("C:\\test\\testBar.zip");
sSourceName = _D("C:\\test2");
PreviousFilename = _D("");
TZipFile* Zip = new TZipFile();
try{
if ( FileExists( sZipName ) ){
Zip->ZipDirectoryContents( sZipName, // destiny
sSourceName, // to include
zcDeflate, // compression mode
&OnZipProgressEvent ); // <--- p callback
Zip->Close();
}
}
catch(...){
result = false;
ShowMessage(_D("Error"));
}
delete Zip;
Zip = NULL;
return result;
}
void __fastcall TForm1::OnZipProgressEvent( TObject* Sender,
String FileName,
const TZipHeader &Header,
__int64 Position )
{
if ( PreviousFilename != FileName ){
PreviousFilename = FileName;
ProgressBar1->Max = Header.UncompressedSize;
ProgressBar1->Position = Position;
}
else{
ProgressBar1->Position = Position;
Application->ProcessMessages();
}
}