VC下载文件 + 显示进度条

Posted 朝闻道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC下载文件 + 显示进度条相关的知识,希望对你有一定的参考价值。

codeproject里找了许久,发现这样一个VC下载文件并显示进度条的源码,于是添加了些中文注释:

 

1、下载线程函数:

 

[cpp] view plain copy
 
 print?
  1. UINT DownloadFile(LPVOID pParam)  
  2. {  
  3.     CWnd*           pwnd = AfxGetMainWnd();  
  4.     CProgressCtrl*  m_Prog = (CProgressCtrl*)pwnd->GetDlgItem(IDC_PROGRESS1);  
  5.     CButton*        bStart = (CButton*)pwnd->GetDlgItem(IDB_BTN_START);  
  6.       
  7.     char                filebuf[512];  
  8.     CInternetSession    netSession;  
  9.     CStdioFile          *fTargFile;  
  10.     int                 outfs;  
  11.     CString             szFile,FileSize,KBin,KBsec,NewName,Perc;  
  12.       
  13.     try  
  14.     {  
  15.         pwnd->GetDlgItemText(IDC_EDIT1,szFile);  
  16.         pwnd->SetDlgItemText(IDC_STAT,"正在校验下载地址...");  
  17.         fTargFile = netSession.OpenURL(szFile,1,INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD);  
  18.         nDownloaded = 1;  
  19.   
  20.         COleDateTime dlStart = COleDateTime::GetCurrentTime();  
  21.         int filesize = fTargFile->SeekToEnd();  
  22.         fTargFile->SeekToBegin();  
  23.         outfs = filesize / 1024;        // 计算文件大小(千字节)  
  24.         FileSize.Format("%d",outfs);    // 以KB为单位格式文件大小  
  25.           
  26.         // 在当前目录创建新的目标文件  
  27.         CFile fDestFile(fTargFile->GetFileName(), CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);  
  28.         int byteswrite;     // 写入文件的字节数  
  29.         int pos = 0;        // 当前进度条的位置  
  30.         int nperc,kbrecv;   // 进度条的百分比,获取到的数据大小(Kbs为单位)  
  31.         double secs,kbsec;  // 记录秒数, 速度(KB/秒)  
  32.           
  33.         // 如果文件名太长,缩短窗口的标题并在状态显示  
  34.         NewName = fTargFile->GetFileName();                  // 获取新文件名  
  35.           
  36.         if(fTargFile->GetFileName().GetLength() >= 10)  
  37.         {  
  38.             NewName = fTargFile->GetFileName().Mid(0,7); // 分割文件  
  39.             NewName = NewName + "...";  
  40.         }  
  41.           
  42.         pwnd->SetDlgItemText(IDC_STAT,"正在下载...");  
  43.         m_Prog->SetRange32(0,filesize);  
  44.           
  45.         while (byteswrite = fTargFile->Read(filebuf, 512))   // 读取文件  
  46.         {  
  47.             if(nTerminate == 1)                     // 如果点击取消下载  
  48.             {  
  49.                 fDestFile.Close();                  // 关闭我们的目标文件  
  50.                 fTargFile->Close();                  // 关闭远程文件  
  51.                 delete fTargFile;                   // 删除CStdioFile对象,以防止泄漏  
  52.                 pwnd->SetDlgItemText(IDC_STAT,"下载时已被用户取消!"); // Set satus bar text  
  53.                 AfxEndThread(0);                    // 结束下载线程  
  54.             }  
  55.   
  56.             // 根据开始时间与当前时间比较,获取秒数  
  57.             COleDateTimeSpan dlElapsed = COleDateTime::GetCurrentTime() - dlStart;  
  58.             secs = dlElapsed.GetTotalSeconds();  
  59.             pos = pos + byteswrite;                 // 设置新的进度条位置  
  60.             fDestFile.Write(filebuf, byteswrite);   // 将实际数据写入文件  
  61.             m_Prog->SetPos(pos);  
  62.               
  63.             nperc = pos * 100 / filesize;           // 进度百分比  
  64.             kbrecv = pos / 1024;                    // 获取收到的数据  
  65.             kbsec = kbrecv / secs;                  // 获取每秒下载多少(KB)  
  66.   
  67.             Perc.Format("%d",nperc);                // 格式化进度百分比  
  68.             KBin.Format("%d",kbrecv);               // 格式化已下载数据大小(KB)  
  69.             KBsec.Format("%d",(int)kbsec);          // 格式化下载速度(KB/秒)  
  70.   
  71.             pwnd->SetDlgItemText(IDC_EDIT_FILESIZE,FileSize + "KB");// 远程文件大小  
  72.             pwnd->SetDlgItemText(IDC_EDIT_SIZEOK,KBin + "KB");       // 已下载大小  
  73.             pwnd->SetDlgItemText(IDC_EDIT2,KBsec + "KB/秒");      // 下载速度  
  74.             pwnd->SetDlgItemText(IDC_EDIT4,Perc + "%");              // 进度百分比  
  75.         }  
  76.         // 下载完成,关闭文件  
  77.         fDestFile.Close();  
  78.     }  
  79.   
  80.     catch(CInternetException *IE)  
  81.     {  
  82.         CString strerror;  
  83.         TCHAR error[255];  
  84.   
  85.         IE->GetErrorMessage(error,255); // 获取错误消息  
  86.         strerror = error;  
  87.   
  88.         pwnd->SetDlgItemText(IDC_STAT,strerror);  
  89.         pwnd->SetDlgItemText(IDB_BTN_STOP,"Exit");  
  90.         nDownloaded = 0;  
  91.         delete fTargFile;  
  92.         IE->Delete();                    // 删除异常对象,以防止泄漏  
  93.     }  
  94.     // 恢复默认  
  95.     pwnd->SetDlgItemText(IDC_EDIT2,"Kb/秒");  
  96.     pwnd->SetDlgItemText(IDC_EDIT3,"Loading...");  
  97.     pwnd->SetDlgItemText(IDC_EDIT4,"0%");  
  98.       
  99.     delete fTargFile;  
  100.     if(nDownloaded == 1)  
  101.     {  
  102.         pwnd->SetDlgItemText(IDC_STAT,"下载完成!");  
  103.         bStart->EnableWindow(TRUE);  
  104.     }  
  105.     return 0;  
  106. }  

 

 

2、程序运行效果:

技术分享

 

 

3、源码下载:

 

http://download.csdn.net/source/1674247

 

http://www.rayfile.com/files/047e5e02-a3a6-11de-9dba-0014221b798a/

 

http://blog.csdn.net/wangningyu/article/details/4564818

以上是关于VC下载文件 + 显示进度条的主要内容,如果未能解决你的问题,请参考以下文章

Python 给下载文件显示进度条和下载时间

Python HTTP下载文件并显示下载进度条

iOS,Swift:串行下载多个文件并将所有文件的单个进度条显示为一个进度

下载文件时进度条不显示剩余百分比?

[WinFrom]下载文件并显示进度条的实现代码

Delphi下载指定网址(URL)的文件,带进度条显示