MFC开发之URLDownloadToFile下载文件时添加进度条

博客介绍了URLDownloadToFile的第五个参数可设置进度。提到下载文件放在主类测试会卡住主线程,应创建线程处理。还说明了添加头文件,创建CCallback类用于进度条,以及在CCallback.cpp中调用进度条和显示数字,指出需将下载放至其他线程避免程序卡顿。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}

现在这样下载和进度条其实都是在主线程里面的,下载文件时会程序会卡主不能进行其他操作,需要将下载放到别的线程里面去,这样在没有下载完时也可以取消下载,也不卡主程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值