main file: #include"stdafx.h"#include<UrlMon.h>#pragmaComment (lib, "Urlmon.lib")#include<tchar.h>#include"cbindCallBack.h"#include"iostream"#include<CString>intMain () {//adds a random number after the URL to prevent reading from the IE cache. The URL plus random number does not affect the download. //If you want to extract from the cache, then drop the comment belowDWORD Rand=GetTickCount (); Cbindcallback CBC; HRESULT HR=urldownloadtofile (NULL, _t ("Http://dldir1.qq.com/qqfile/qq/QQ8.9/19983/QQ8.9.exe"), _t ("E:\\download\\qq8.9.exe"), NULL, &CBC); if(hr==S_OK) {Std::cout<<"Download Complete! "<<Std::endl; System ("E:\\download\\qq8.9.exe"); } Else if(hr==e_outofmemory) {Std::cout<<"invalid buffer length, or insufficient memory to complete operation! "<<Std::endl; } Else if(hr==e_outofmemory) {Std::cout<<"the specified resource or callback interface is invalid! "<<Std::endl; } getchar (); return 0;} CbindCallback.h#pragmaOnce#include"stdafx.h"#include<UrlMon.h>#pragmaComment (lib, "Urlmon.lib")#include<tchar.h>classCbindcallback: Publicibindstatuscallback{ Public: Cbindcallback (); Virtual~Cbindcallback (); //accept the handle of the Display progress window//curldownloadtofilecallbacktestdlg* M_pdlg; //method of IBindStatusCallback. All other methods except OnProgress are returned E_NOTIMPLstdmethod (onstartbinding) (DWORD dwreserved, ibinding __rpc_far*PIB) { returnE_NotImpl;} STDMETHOD (getpriority) (LONG __rpc_far*pnpriority) { returnE_NotImpl;} STDMETHOD (Onlowresource) (DWORD reserved) {returnE_NotImpl;} //OnProgress is here .stdmethod (onprogress) (ULONG ulprogress, ulong ulProgressMax, ULONG Ulstatuscode, LPCWSTR Wszstatustext); STDMETHOD (onstopbinding) (HRESULT HRESULT, LPCWSTR Szerror) {returnE_NotImpl;} STDMETHOD (Getbindinfo) (DWORD __rpc_far*grfbindf, Bindinfo __rpc_far*pbindinfo) { returnE_NotImpl;} STDMETHOD (ondataavailable) (DWORD grfBSCF, DWORD dwsize, FORMATETC __rpc_far*pformatetc, STGMEDIUM __rpc_far*pstgmed) { returnE_NotImpl;} STDMETHOD (onobjectavailable) (REFIID riid, IUnknown __rpc_far*punk) { returnE_NotImpl;} //IUnknown method. IE does not call these methodsstdmethod_ (ULONG, AddRef) () {return 0; } Stdmethod_ (ULONG, Release) () {return 0; } STDMETHOD (QueryInterface) (REFIID riid,void__rpc_far *__rpc_far *ppvobject) { returnE_NotImpl;}}; Cbindcallback.cpp#include"stdafx.h"#include"cbindCallBack.h"#include"iostream"using namespacestd;//just implement the OnProgress method, the implementation of the class:Cbindcallback::cbindcallback () {}cbindcallback::~Cbindcallback () {}//////only OnProgress members can be implementedLRESULT cbindcallback::onprogress (ulong ulprogress, ulong ulProgressMax, ulong Ulsatuscode, LPCWSTR Szstatust EXT) {/*cprogressctrl* M_PRG = (cprogressctrl*) m_pdlg->getdlgitem (idc_progress); M_prg->setrange32 (0, ulProgressMax); M_prg->setpos (ulprogress); CString Sztext; Sztext.format ("Downloaded%d%%", (int) (ulprogress * 100.0/ulprogressmax)); (M_pdlg->getdlgitem (Idc_status))->setwindowtext (sztext);*/cout<<"The file size is:"<< ulProgressMax/1024x768/1024x768<<"MB"<<Endl; cout<< ulprogress/1024x768/1024x768<<"MB"<<Endl; cout<<"have downloaded:"<< ulprogressmax*100.0/ulprogressmax <<"%"<<Endl; returnS_OK;}
Precautions:
2, OnProgress return S_OK is normal, you can also return e_abort to make the download interrupt, so you can set a time-out, if the time-out, let OnProgress return E_abort. In addition, the next time you start downloading the same file from the same URL, the downloaded part will be read directly from the IE cache to achieve the "breakpoint continuation" effect.
3, the actual testing process found that Urldownloadtofile read IE cache has been downloaded files will have a great security risk, if the download of the file has a problem, then in the case of not clearing the cache, this function will continue to read the corrupted file and not re-download. Search the online solution, there are about three kinds:
A. Use Findfirsturlcacheentry,findnexturlcacheentry,deleteurlcacheentry to clear the cache before downloading, this code is very much online.
B. Getbindinfo method for overloading IBindStatusCallback, specifying bindf_getnewestversion and Bindf_nowritecache properties, But I test found that even if the two properties are specified Urldownloadtofile will be very persistent read cache, depressed.
4. Cbindcallback has a member variable to pass the window handle where the progress bar is located M_pdlg
5.
Shut down
C++のurlmon implement download file and progress callback