Skip Navigation Links
Skip Navigation LinksHome > ZipArchive > How to Use > Article
Progress Notifications: Using Callback Objects
Applies To: All

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:

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);
// we can display initial information here
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)
{
#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 false here to abort processing
return true;
}
// override the method to adjust the frequency of calling the callback
int GetStepSize()
{
return m_iType == cbSave ? 1024 : 64;
}
};
void Progress()
{
LPCTSTR zipFileName = _T("C:\\Temp\\test.zip");
CZipArchive zip;
CProgressCallback callback;
// set one callback for all notifications
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)
{
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()
{
// Let's the call the Callback method very often to better illustrate
// the functionality.
// Normally this would degrade performance with some callback types.
return 1;
}
// override to be notified about every file processed
bool MultiActionsNext()
{
// call the base class' method
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
// Processing was requested to be stopped.
// It won't happen in this sample code, because
// the Callback method always returns true.
return false;
}
};
void ProgressMulti()
{
CZipArchive zip;
CMultiProgressCallback callback;
// register for
zip.SetCallback(&callback,
CZipActionCallback::cbMultiAdd | CZipActionCallback::cbCalculateForMulti);
zip.Open(_T("C:\\Temp\\test.zip"), CZipArchive::zipCreate);
// add multiple files
zip.AddNewFiles(_T("C:\\Temp"), _T("*.bin"), false);
zip.Close();
}

See Also API Links

Article ID: 0610231200
Back To Top Up