MFC多线程对话框显示进度和状态

如,我要将一些当前程序的数据打印为PDF,这个过程需要一段时间,需要设置进度条,可以选择一个弹窗式的进度条。
 建立共享变量
int m_process;//进度条进度,0-100
CString m_status;//当前程序状态输出文本


首先,创建一个对话框,并建立与其对应的类CJingDuTiao,添加一个进度条控件绑定m_ctrlProgress, 添加一个static用于输出文本。对话框CPP顶端共享上述两个变量
然后在对话框对应的类中添加两个函数:
void CJingDuTiao::OnTimer(UINT nIDEvent)
{
 
if(m_process==100)
{
OnOK();
}
else if(m_process!=0)
{
m_progress.SetPos(m_process);
if (((CStatic*)GetDlgItem(IDC_STATUS))->GetSafeHwnd())  
{  
CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATUS);  
ASSERT(pStatic);  
  
CRect rc;  
pStatic->GetWindowRect(&rc);  
ScreenToClient(&rc);  
InvalidateRect(&rc);  
}  
SetDlgItemText(IDC_STATUS,m_status);
}
CDialogEx::OnTimer(nIDEvent);
}
BOOL CJingDuTiao::OnInitDialog()
{
CDialogEx::OnInitDialog();


// TODO:  在此添加额外的初始化
KillTimer(1);
SetTimer(1,20,NULL);
return TRUE;  // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}

再在主程序(MainFrm)中添加两个子进程需要处理的函数,注意要在.h中USING namespace std后声明UINT   PrintPdf_thread(LPVOID pParam);
如:
void C单腔模拟View::PrintPdf(int print_pic_each,int print_pic_all, int print_sheet, int print_property)
{
{
 for(int i = 0; i < 1000; i++)
{
  m_process++;
  Sleep(50);
  }
m_process = 100;
return 0;
}
这个函数(function)是用来控制进度条变化的函数。
UINT PrintPdf_thread(LPVOID pParam)
{
C单腔模拟View* pInfo2=(C单腔模拟View*)pParam;
pInfo2->PrintPdf(print_pic_each,print_pic_all,print_sheet,print_property);
 return 0;
}
 
最后在需要运动进度条的地方添加
AfxBeginThread(PrintPdf_thread,this);//申请一个进程来执行function1,也就是主程序处理代码。
 if(dlg1.DoModal()==IDOK)//模态显示对话框,此时主程序代码执行到此,不往下执行,直至对话框关闭,但是两个
{
需等待print结束之后运行的代码
}
//子进程始终在运行中。
其中dlg1是对话框的一个对象。
这样一个同事处理数据且显示进度条对话框的功能就实现了。
好的,针对你的问题,我给出以下解答: 首先,我们需要使用lib7zip库来解压.7z文件,因此需要将其添加到项目中。将lib7zip中的所有文件添加到您的项目中,并将其包含在您的源文件中。 然后,我们需要使用WinINet库来下载文件。使用WinINet,我们可以轻松地下载文件并跟踪下载进度。我们将使用HttpQueryDataAvailable函数获取下载文件的大小,然后使用InternetReadFile函数读取下载的数据。 接下来,我们需要在对话框上创建两个进度条控件:一个用于下载进度,另一个用于解压进度。我们还需要一个按钮来启动下载和解压过程。 最后,我们将使用多线程来执行下载和解压操作。我们将使用C++11中的std::thread类来创建线程。在下载和解压期间,我们将更新进度条并将状态消息发送回主线程以在对话框显示。 以下是代码示例: ```c++ #include "stdafx.h" #include "ZipExtractor.h" #include <thread> #include <iostream> #include <fstream> #include <wininet.h> #include "lib7zip/7z.h" #include "lib7zip/7zAlloc.h" #include "lib7zip/7zBuf.h" #include "lib7zip/7zCrc.h" #include "lib7zip/7zFile.h" #include "lib7zip/7zVersion.h" #pragma comment(lib, "wininet.lib") #pragma comment(lib, "lib7zip.lib") #define BUFFER_SIZE 10240 // 下载进度回调函数 static DWORD CALLBACK DownloadProgressCallback( IN HINTERNET hInternet, IN DWORD_PTR dwContext, IN DWORD dwInternetStatus, IN LPVOID lpvStatusInformation, IN DWORD dwStatusInformationLength ) { if (dwInternetStatus == INTERNET_STATUS_RESPONSE_RECEIVED) { DWORD nBytesAvailable = 0; if (InternetQueryDataAvailable(hInternet, &nBytesAvailable, 0, 0)) { // 更新下载进度条 CProgressCtrl* pDownloadProgressBar = (CProgressCtrl*)dwContext; pDownloadProgressBar->SetRange32(0, nBytesAvailable); pDownloadProgressBar->SetPos(0); } } else if (dwInternetStatus == INTERNET_STATUS_REQUEST_COMPLETE) { DWORD nBytesRead = 0; LPBYTE pBuffer = (LPBYTE)lpvStatusInformation; DWORD nBytesAvailable = *(LPDWORD)dwStatusInformationLength; if (InternetReadFile(hInternet, pBuffer, nBytesAvailable, &nBytesRead)) { // 更新下载进度条 CProgressCtrl* pDownloadProgressBar = (CProgressCtrl*)dwContext; pDownloadProgressBar->SetPos(pDownloadProgressBar->GetPos() + nBytesRead); } } return 0; } // 解压进度回调函数 static SRes ExtractCallback( const void* pInData, // 输入数据 size_t nInSize, // 输入数据大小 void* pOutData, // 输出数据 size_t nOutSize, // 输出数据大小 void* pUserData // 用户数据(进度条控件指针) ) { // 更新解压进度条 CProgressCtrl* pExtractProgressBar = (CProgressCtrl*)pUserData; pExtractProgressBar->SetPos(pExtractProgressBar->GetPos() + nInSize); return SZ_OK; } // 下载并解压线程函数 void DownloadAndExtractThread(LPCTSTR lpszUrl, LPCTSTR lpszOutputPath, CProgressCtrl* pDownloadProgressBar, CProgressCtrl* pExtractProgressBar) { // 创建Internet连接 HINTERNET hInternet = InternetOpen(_T("7zDownloader"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInternet == NULL) { AfxMessageBox(_T("Failed to create Internet connection")); return; } // 打开URL HINTERNET hUrl = InternetOpenUrl(hInternet, lpszUrl, NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 0); if (hUrl == NULL) { AfxMessageBox(_T("Failed to open URL")); InternetCloseHandle(hInternet); return; } // 获取文件大小 DWORD nFileSize = 0; DWORD nSizeLen = sizeof(DWORD); if (!HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &nFileSize, &nSizeLen, NULL)) { AfxMessageBox(_T("Failed to get file size")); InternetCloseHandle(hUrl); InternetCloseHandle(hInternet); return; } // 创建文件 HANDLE hFile = CreateFile(lpszOutputPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { AfxMessageBox(_T("Failed to create file")); InternetCloseHandle(hUrl); InternetCloseHandle(hInternet); return; } // 更新下载进度条 pDownloadProgressBar->SetRange32(0, nFileSize); pDownloadProgressBar->SetPos(0); // 开始下载 char szBuffer[BUFFER_SIZE]; DWORD dwBytesRead = 0; while (InternetReadFile(hUrl, szBuffer, BUFFER_SIZE, &dwBytesRead) && dwBytesRead > 0) { DWORD dwBytesWritten = 0; if (!WriteFile(hFile, szBuffer, dwBytesRead, &dwBytesWritten, NULL)) { AfxMessageBox(_T("Failed to write file")); CloseHandle(hFile); InternetCloseHandle(hUrl); InternetCloseHandle(hInternet); return; } // 更新下载进度条 pDownloadProgressBar->SetPos(pDownloadProgressBar->GetPos() + dwBytesRead); } // 关闭文件和URL句柄 CloseHandle(hFile); InternetCloseHandle(hUrl); InternetCloseHandle(hInternet); // 开始解压 CFile file; if (!file.Open(lpszOutputPath, CFile::modeRead)) { AfxMessageBox(_T("Failed to open file")); return; } CArchive ar(&file, CArchive::load); CMemoryFile memfile; memfile.SetSize(ar.GetFile()->GetLength()); ar.Read(memfile.GetBuffer(), memfile.GetLength()); ar.Close(); file.Close(); // 打开7z文件 CLookToRead lookStream; lookStream.buf = (Byte*)memfile.GetBuffer(); lookStream.size = memfile.GetLength(); lookStream.pos = 0; LookToRead_CreateVTable(&lookStream, False); CrcGenerateTable(); CSzArEx db; SzArEx_Init(&db); ISzAlloc allocImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; CrcGenerateTable(); ISzAlloc allocTempImp; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; CArchiveDatabase archiveDatabase; SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); // 解压文件 for (UInt32 i = 0; i < db.NumFiles; i++) { UInt32 blockIndex = 0xFFFFFFFF; SRes res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, ExtractCallback, pExtractProgressBar); if (res != SZ_OK) { AfxMessageBox(_T("Failed to extract file")); break; } } // 关闭7z文件 SzArEx_Free(&db, &allocImp); memfile.Close(); // 更新解压进度条 pExtractProgressBar->SetPos(pExtractProgressBar->GetRange().right); // 显示完成消息 AfxMessageBox(_T("Download and extract complete")); } // CZipExtractorDlg 对话框 class CZipExtractorDlg : public CDialogEx { // ... public: // ... private: // ... afx_msg void OnBnClickedButtonDownload(); // ... }; void CZipExtractorDlg::OnBnClickedButtonDownload() { // 获取下载URL和输出路径 CString strUrl, strOutputPath; GetDlgItemText(IDC_EDIT_URL, strUrl); GetDlgItemText(IDC_EDIT_OUTPUT_PATH, strOutputPath); // 创建并启动线程 std::thread downloadThread(DownloadAndExtractThread, strUrl.GetBuffer(), strOutputPath.GetBuffer(), &m_wndDownloadProgressBar, &m_wndExtractProgressBar); downloadThread.detach(); } // ... ``` 以上代码仅为示例,具体实现可能需要根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值