Introduction
The ZipArchive Library uses callback objects to notify about the progress of an
archive processing.
Creating Callback Objects
To be notified about the progress of various actions (see
CZipActionCallback::CallbackType
for possibilities), you need to:
- Define your own callback class derived from CZipActionCallback.
- Override at least the CZipCallback::Callback() method.
- Create an object of this class, and set it as a callback object with the CZipArchive::SetCallback() method. Make sure that the object
is not destroyed throughout the whole processing.
- Start processing an archive, the notifications about the progress will be coming
to the overridden CZipCallback::Callback() method.
The value of the
uProgress
parameter of the callback method is the
amount of data just processed.
- Examine members of the CZipActionCallback object to
read the progress state.
- To abort the processing, return
false
from the overridden callback
method.
Order of Methods Calls
You can also override other methods of the
CZipActionCallback
class to be notified about starting and ending stages of the process. The methods
are called in the following order:
Controlling the Frequency of Calling Callbacks
To control how often the
CZipCallback::Callback() method
is called, override the
CZipActionCallback::GetStepSize()
method and return the step size value for a given callback type. If you use one
CZipActionCallback object for multiple callback types,
you may find out for which callback type the step size is requested by examining
the
CZipActionCallback::m_iType value from within the
CZipActionCallback::GetStepSize() method.
Sample Code
class CProgressCallback : public CZipActionCallback
{
void Init(LPCTSTR lpszFileInZip, LPCTSTR lpszExternalFile)
{
CZipActionCallback::Init(lpszFileInZip, lpszExternalFile);
LPCTSTR lpszAction;
switch (m_iType)
{
case CZipActionCallback::cbAdd:
lpszAction = _T("Adding");
break;
case CZipActionCallback::cbExtract:
lpszAction = _T("Extracting");
break;
case CZipActionCallback::cbSave:
lpszAction = _T("Saving");
break;
default:
lpszAction = _T("???");
}
_tprintf(_T("\r\n%s...\r\n"), lpszAction);
}
bool Callback(ZIP_SIZE_TYPE uProgress)
{
#ifdef _ZIP_ZIP64
_tprintf(_T("Processed %I64u of %I64u (%I64u left) \r"),
m_uProcessed, m_uTotalToProcess, LeftToProcess());
#else
_tprintf(_T("Processed %u of %u (%u left) \r"),
m_uProcessed, m_uTotalToProcess, LeftToProcess());
#endif
return true;
}
int GetStepSize()
{
return m_iType == cbSave ? 1024 : 64;
}
};
void Progress()
{
LPCTSTR zipFileName = _T("C:\\Temp\\test.zip");
CZipArchive zip;
CProgressCallback callback;
zip.SetCallback(&callback);
zip.Open(zipFileName, CZipArchive::zipCreate);
zip.AddNewFile(_T("C:\\Temp\\file.dat"));
zip.Close();
zip.Open(zipFileName);
zip.ExtractFile(0, _T("C:\\Temp"), false, _T("file.ext"));
zip.Close();
}
Multiple Actions Callbacks
When processing multiple files in one step, there is additional information available
about the global progress. It is available for
CZipActionCallback::cbMultiActions
callback types. It can be requested with the
CZipActionCallback::GetMultiActionsInfo()
method call.
Order of Methods Calls
There are additional methods called when processing multiple files. They are
called in the following order:
Sample Code
class CMultiProgressCallback : public CZipActionCallback
{
bool Callback(ZIP_SIZE_TYPE uProgress)
{
if (m_iType == cbCalculateForMulti)
{
LPCTSTR FormatSymbol = _T("%I64u");
#ifdef _ZIP_ZIP64
_tprintf(_T("Found %I64u files so far \r\n"), m_uProcessed);
#else
_tprintf(_T("Found %u files so far \r\n"), m_uProcessed);
#endif
return true;
}
CMultiActionsInfo* pMulti = GetMultiActionsInfo();
ASSERT(pMulti);
#ifdef _ZIP_ZIP64
_tprintf(_T("Current File: %I64u of %I64u, Total Bytes: %I64u of %I64u \r"),
#else
_tprintf(_T("Current File: %u of %u, Total Bytes: %u of %u \r"),
#endif
m_uProcessed, m_uTotalToProcess,
pMulti->m_uBytesProcessed, pMulti->m_uTotalBytesToProcess);
return true;
}
int GetStepSize()
{
return 1;
}
bool MultiActionsNext()
{
if (CZipActionCallback::MultiActionsNext())
{
CMultiActionsInfo* pMulti = GetMultiActionsInfo();
#ifdef _ZIP_ZIP64
_tprintf(_T("\n\rFiles Processed: %I64u of %I64u \n\r"),
#else
_tprintf(_T("\n\rFiles Processed: %u of %u \n\r"),
#endif
pMulti->m_uFilesProcessed, pMulti->m_uTotalFilesToProcess);
return true;
}
else
return false;
}
};
void ProgressMulti()
{
CZipArchive zip;
CMultiProgressCallback callback;
zip.SetCallback(&callback,
CZipActionCallback::cbMultiAdd | CZipActionCallback::cbCalculateForMulti);
zip.Open(_T("C:\\Temp\\test.zip"), CZipArchive::zipCreate);
zip.AddNewFiles(_T("C:\\Temp"), _T("*.bin"), false);
zip.Close();
}
See Also API Links