mfc解压7z文件并显示进度条
时间: 2023-07-02 19:15:27 浏览: 125
以下是一个使用 MFC 和 7-Zip SDK 解压 7z 文件并显示进度条的示例代码:
```c++
#include "stdafx.h"
#include "7z.h"
#include "7zAlloc.h"
#include "7zFile.h"
#include "7zVersion.h"
#include <afxmt.h>
#include <afxwin.h>
// 进度条对话框类
class CProgressDialog : public CDialog
{
public:
CProgressDialog(CWnd* pParent = NULL)
: CDialog(IDD_PROGRESS, pParent)
{
m_pProgress = NULL;
m_nMax = 100;
m_nPos = 0;
}
virtual ~CProgressDialog()
{
}
void SetProgress(int nPos)
{
m_nPos = nPos;
if (m_pProgress != NULL)
{
m_pProgress->SetPos(m_nPos);
m_pProgress->UpdateWindow();
}
}
void SetMax(int nMax)
{
m_nMax = nMax;
if (m_pProgress != NULL)
{
m_pProgress->SetRange32(0, m_nMax);
m_pProgress->UpdateWindow();
}
}
void SetMessage(LPCTSTR lpszMessage)
{
if (m_pProgress != NULL)
{
m_pProgress->SetWindowText(lpszMessage);
m_pProgress->UpdateWindow();
}
}
virtual BOOL OnInitDialog()
{
CDialog::OnInitDialog();
m_pProgress = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS);
m_pProgress->SetRange32(0, m_nMax);
m_pProgress->SetPos(m_nPos);
return TRUE;
}
enum { IDD = IDD_PROGRESS };
protected:
CProgressCtrl* m_pProgress;
int m_nMax;
int m_nPos;
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CProgressDialog, CDialog)
END_MESSAGE_MAP()
// 解压进度回调函数
SRes OnExtractProgress(void* pUserData, UInt64 u64Total, UInt64 u64Completed)
{
CProgressDialog* pProgress = (CProgressDialog*)pUserData;
if (pProgress != NULL)
{
int nPos = (int)(u64Completed * 100 / u64Total);
pProgress->SetProgress(nPos);
}
return SZ_OK;
}
// 解压 7z 文件
BOOL Extract7zFile(LPCTSTR lpszArchivePath, LPCTSTR lpszDestPath)
{
CProgressDialog dlgProgress;
dlgProgress.Create(IDD_PROGRESS, NULL);
// 设置 7-Zip SDK 的内存分配器
ISzAlloc sAlloc = { SzAlloc, SzFree };
// 打开 7z 文件
CFileInStream archiveStream;
if (InFile_Open(&archiveStream.file, CT2CA(lpszArchivePath)) != 0)
{
return FALSE;
}
archiveStream.s.Init(&archiveStream.file);
// 获取 7z 文件的属性
CLookToRead lookStream;
lookStream.s = &archiveStream.s;
LookToRead_CreateVTable(&lookStream, False);
CrcGenerateTable();
CSzArEx db;
SzArEx_Init(&db);
SRes res = SzArEx_Open(&db, &lookStream.s, &sAlloc, &sAlloc);
if (res != SZ_OK)
{
return FALSE;
}
// 解压 7z 文件
TCHAR szDestPath[MAX_PATH];
_tcscpy_s(szDestPath, lpszDestPath);
UInt32 i;
UInt64 total = 0;
for (i = 0; i < db.NumFiles; i++)
{
total += SzArEx_GetFileSize(&db, i);
}
UInt64 completed = 0;
for (i = 0; i < db.NumFiles; i++)
{
// 显示进度条和消息
TCHAR szMessage[256];
_stprintf_s(szMessage, _T("Extracting %s..."), CA2CT(SzArEx_GetFileNameUtf16(&db, i)));
dlgProgress.SetMessage(szMessage);
dlgProgress.SetMax(100);
dlgProgress.SetProgress(0);
// 创建目录
TCHAR szFilePath[MAX_PATH];
_stprintf_s(szFilePath, _T("%s\\%s"), szDestPath, CA2CT(SzArEx_GetFileNameUtf16(&db, i)));
TCHAR* pLastSlash = _tcsrchr(szFilePath, _T('\\'));
if (pLastSlash != NULL)
{
*pLastSlash = _T('\0');
if (!CreateDirectory(szFilePath, NULL))
{
DWORD dwError = GetLastError();
if (dwError != ERROR_ALREADY_EXISTS)
{
return FALSE;
}
}
*pLastSlash = _T('\\');
}
// 解压文件
res = SzArEx_Extract(&db, &lookStream.s, i, &sAlloc, &sAlloc, szDestPath, &onExtractProgress, &dlgProgress);
if (res != SZ_OK)
{
return FALSE;
}
// 更新进度条
completed += SzArEx_GetFileSize(&db, i);
int nPos = (int)(completed * 100 / total);
dlgProgress.SetProgress(nPos);
}
// 关闭 7z 文件
SzArEx_Free(&db, &sAlloc);
File_Close(&archiveStream.file);
return TRUE;
}
// 主程序入口
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
// 初始化 MFC
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
// 解压 7z 文件
Extract7zFile(_T("test.7z"), _T("test"));
return 0;
}
```
注意,以上代码仅供参考,具体使用方法还需要参考 7z.h 中的函数说明和示例代码。同时,代码中可能存在一些不足之处,例如没有处理异常情况等。