mfc使用 bit7z 解压7z文件并显示进度条 详细更新进度条的代码
时间: 2023-08-15 15:15:55 浏览: 202
以下是使用Bit7z解压7z文件并显示进度条,并更新进度条的MFC代码示例:
```cpp
#include "stdafx.h"
#include "Bit7z.h"
#include "7z/CPP/7zip/Archive/IArchive.h"
#include "7z/CPP/7zip/UI/Common/Extract.h"
#include "7z/CPP/7zip/UI/Common/ExtractCallback.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
void CBit7zDlg::OnBnClickedButton1()
{
// 7z文件路径
CString strFilePath = _T("C:\\test.7z");
// 解压路径
CString strExtractPath = _T("C:\\test");
// 初始化Bit7z
Bit7z::Init();
// 创建Bit7z的解压参数
Bit7z::ExtractOptions extractOptions;
extractOptions.CompressionMethod = Bit7z::CompressionMethod::LZMA;
// 创建Bit7z的解压回调
CExtractCallback extractCallback;
extractCallback.SetFolderPath(strExtractPath);
// 创建Bit7z的解压对象
Bit7z::Extractor extractor(strFilePath, extractOptions, &extractCallback);
// 开始解压
extractor.Extract();
// 销毁Bit7z
Bit7z::Deinit();
}
class CExtractCallback : public IExtractCallbackUI
{
public:
CExtractCallback()
{
m_nTotalBytes = 0;
m_nCompletedBytes = 0;
}
virtual ~CExtractCallback()
{
}
void SetFolderPath(LPCTSTR lpszFolderPath)
{
m_strFolderPath = lpszFolderPath;
}
// IProgressCallback
STDMETHOD(SetTotal)(UInt64 total) override
{
m_nTotalBytes = total;
return S_OK;
}
STDMETHOD(SetCompleted)(const UInt64* completeValue) override
{
m_nCompletedBytes = *completeValue;
// 更新进度条
int nPercent = (int)(m_nCompletedBytes * 100 / m_nTotalBytes);
m_wndProgress.SetPos(nPercent);
// 处理消息队列,防止界面卡死
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return S_OK;
}
// IExtractCallbackUI
STDMETHOD(AskOverwrite)(
const wchar_t* existName, const FILETIME* existTime, const UInt64* existSize,
const wchar_t* newName, const FILETIME* newTime, const UInt64* newSize,
Int32* answer) override
{
CString strMessage;
strMessage.Format(_T("文件 %s 已经存在,是否覆盖?"), newName);
int nResult = AfxMessageBox(strMessage, MB_YESNOCANCEL | MB_ICONQUESTION);
if (nResult == IDYES)
{
*answer = NExtract::NOverwriteAnswer::kOverwrite;
}
else if (nResult == IDNO)
{
*answer = NExtract::NOverwriteAnswer::kSkip;
}
else
{
*answer = NExtract::NOverwriteAnswer::kCancel;
}
return S_OK;
}
STDMETHOD(PrepareOperation)(Int32 askExtractMode) override
{
return S_OK;
}
STDMETHOD(MessageError)(const wchar_t* message) override
{
AfxMessageBox(message, MB_OK | MB_ICONERROR);
return S_OK;
}
STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) override
{
return S_OK;
}
STDMETHOD(SetRatioInfo)(const UInt64* inSize, const UInt64* outSize) override
{
return S_OK;
}
STDMETHOD(SetTotalProgress)(const UInt64* total) override
{
return S_OK;
}
STDMETHOD(SetCompleted)(UInt64 completeValue) override
{
return SetCompleted(&completeValue);
}
STDMETHOD(AskPassword)(Int32* passwordIsDefined, BSTR* password) override
{
return E_NOTIMPL;
}
STDMETHOD(PrepareOperation2)(Int32 askExtractMode, Int32* options) override
{
return S_OK;
}
STDMETHOD(FinishOperation)(Int32 resultEOperationResult) override
{
return S_OK;
}
private:
CString m_strFolderPath; // 解压路径
CProgressCtrl m_wndProgress; // 进度条控件
UInt64 m_nTotalBytes; // 总字节数
UInt64 m_nCompletedBytes; // 已完成字节数
};
```
在上述代码中,`CExtractCallback` 是 Bit7z 的解压回调类,继承自 `IExtractCallbackUI` 接口。在回调类中,我们可以通过 `SetTotal` 和 `SetCompleted` 方法获取解压的总字节数和已完成字节数,并通过 `m_wndProgress` 控件更新进度条的进度。注意,在 `SetCompleted` 方法中,我们需要处理消息队列,防止界面卡死。
另外,在 `OnBnClickedButton1` 方法中,我们首先初始化 Bit7z,然后创建解压参数、回调和解压对象,最后调用 `Extract` 方法开始解压。解压完成后,我们需要销毁 Bit7z。
希望这个示例代码能够帮助您解决问题。
阅读全文