URLDownloadToFile的第五个参数就是用来设置进度的。
下载文件:这个放在主类中用来下载文件时测试用,当文件没有下载完时会卡主主线程,真正使用时创建一个线程放在里面使用
添加头文件://清除缓存函数使用
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
CCallback callback;//用来设置进度条用的
callback.m_pdlg = this;//初始化
DeleteUrlCacheEntry(TEXT("http://speedtest.atlanta.linode.com/100MB-atlanta.bin"));//清除缓存
HRESULT ret = URLDownloadToFile(NULL, TEXT("http://speedtest.atlanta.linode.com/100MB-atlanta.bin"),
TEXT("E:\\100MB-atlanta.bin"), 0, &callback);
if (S_OK == ret)//下载url函数
MessageBox(TEXT("下载成功"));
else
MessageBox(TEXT("下载失败"));
创建CCallback类,主要是进度条需要用
CCallback.h中
CMooerStudioDlg* m_pdlg;//dlg为对话框,可以自行设置,我这边是根据对话框创建的,进度条也是直接放在对话框上面
继续添加:
除了带onprogress以外的都返回E_NOTIMPL
STDMETHOD(OnStartBinding)(
/* [in] */ DWORD dwReserved,
/* [in] */ IBinding __RPC_FAR *pib)
{ return E_NOTIMPL; }
STDMETHOD(GetPriority)(
/* [out] */ LONG __RPC_FAR *pnPriority)
{ return E_NOTIMPL; }
STDMETHOD(OnLowResource)(
/* [in] */ DWORD reserved)
{ return E_NOTIMPL; }
//这个里面进度条
STDMETHOD(OnProgress)(
/* [in] */ ULONG ulProgress,
/* [in] */ ULONG ulProgressMax,
/* [in] */ ULONG ulStatusCode,
/* [in] */ LPCWSTR wszStatusText);
STDMETHOD(OnStopBinding)(
/* [in] */ HRESULT hresult,
/* [unique][in] */ LPCWSTR szError)
{ return E_NOTIMPL; }
STDMETHOD(GetBindInfo)(
/* [out] */ DWORD __RPC_FAR *grfBINDF,
/* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
{ return E_NOTIMPL; }
STDMETHOD(OnDataAvailable)(
/* [in] */ DWORD grfBSCF,
/* [in] */ DWORD dwSize,
/* [in] */ FORMATETC __RPC_FAR *pformatetc,
/* [in] */ STGMEDIUM __RPC_FAR *pstgmed)
{ return E_NOTIMPL; }
STDMETHOD(OnObjectAvailable)(
/* [in] */ REFIID riid,
/* [iid_is][in] */ IUnknown __RPC_FAR *punk)
{ return E_NOTIMPL; }
// IUnknown methods. Note that IE never calls any of these methods, since
// the caller owns the IBindStatusCallback interface, so the methods all
// return zero/E_NOTIMPL.
STDMETHOD_(ULONG,AddRef)()
{ return 0; }
STDMETHOD_(ULONG,Release)()
{ return 0; }
STDMETHOD(QueryInterface)(
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{ return E_NOTIMPL; }
在CCallback.cpp中添加,这个就是调用进度条和显示数字,其中静态文本框会有闪烁的问题,
LRESULT CCallback::OnProgress(ULONG ulProgress,
ULONG ulProgressMax,
ULONG ulSatusCode,
LPCWSTR szStatusText)
{
CProgressCtrl* m_prg = (CProgressCtrl*)m_pdlg->GetDlgItem(IDC_PROGRESS1);//进度条ID
m_prg->SetRange32(0, ulProgressMax);
m_prg->SetPos(ulProgress);
CString szText = _T("");
if (0 != ulProgressMax)
{
szText.Format(_T("已下载%u%%"), (int)(ulProgress * 100.0 / ulProgressMax));
(m_pdlg->GetDlgItem(IDC_STATIC1))->SetWindowText(szText);//静态文本框
}
else
{
(m_pdlg->GetDlgItem(IDC_STATIC1))->SetWindowText(TEXT("0%"));
}
Sleep(1);//加点延时
return S_OK;
}
现在这样下载和进度条其实都是在主线程里面的,下载文件时会程序会卡主不能进行其他操作,需要将下载放到别的线程里面去,这样在没有下载完时也可以取消下载,也不卡主程序