Windows客户端开发--URLDownloadToFile下载文件进度条

在博客《 windows客户端开发–根据可下载url另存为文件》 中,我们介绍了一个windows api, URLDownloadToFile

今天我们就要实现的是使用URLDownloadToFile下载文件,并显示进度条。

基础知识

认真看一看URLDownloadToFile的参数:

URLDownloadToFile

HRESULT URLDownloadToFile( LPUNKNOWN pCaller, LPCTSTR szURL, LPCTSTR szFileName, _Reserved_ DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB );

pCaller
If the calling application is not an ActiveX component, this value can be set to NULL.
我们可以设为NULL

szURL
A pointer to a string value that contains the URL to download.
我们要下载的URL

szFileName
A pointer to a string value containing the name or full path of the file to create for the download.
存储的文件名

dwReserved
Reserved. Must be set to 0.
必须为NULL

lpfnCB
A pointer to the IBindStatusCallback interface of the caller. By using IBindStatusCallback::OnProgress, a caller can receive download status. URLDownloadToFile calls the IBindStatusCallback::OnProgress and IBindStatusCallback::OnDataAvailable methods as data is received.
这个参数是我们关注的重点!!!!!

接下来我们就看看IBindStatusCallback 的定义以及描述:

IBindStatusCallback
The IBindStatusCallback interface inherits from the IUnknown interface。既然是接口,我们就要继承它,根据自己的实际情况实现。这里就介绍一个函数:

OnProgress
Indicates the progress of the bind operation.

撸代码

实现自己的DownloadProgress :

class DownloadProgress : public IBindStatusCallback { public: HRESULT __stdcall QueryInterface(const IID &, void **) { return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef(void) { return 1; } ULONG STDMETHODCALLTYPE Release(void) { return 1; } HRESULT STDMETHODCALLTYPE OnStartBinding(DWORD dwReserved, IBinding *pib) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE GetPriority(LONG *pnPriority) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE OnLowResource(DWORD reserved) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE OnStopBinding(HRESULT hresult, LPCWSTR szError) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD *grfBINDF, BINDINFO *pbindinfo) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(REFIID riid, IUnknown *punk) { return E_NOTIMPL; } virtual HRESULT __stdcall OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) { if (ulProgressMax != 0) { double *percentage = new double(ulProgress * 1.0 / ulProgressMax * 100); //将percentage 发送给显示 delete percentage; } return S_OK; } };

使用:

std::string url = "......";
std::string file_path = "......";
DownloadProgress progress;
IBindStatusCallback* callback = (IBindStatusCallback*)&progress;
URLDownloadToFile(NULL, url.c_str(), file_path .c_str(), NULL, static_cast<IBindStatusCallback*>(&progress));

最后说一下头文件以及lib:

#include <Urlmon.h>
#pragma comment(lib, "urlmon.lib")

最后,记得在子线程中进行下载操作,c++11给我提供了非常方便的多线程:

c++11特性之std::thread–初识

c++11特性之std::thread–初识二

c++11特性之std::thread–进阶

c++11特性之std::thread–进阶二

你可能感兴趣的:(windows,下载进度条)