函数定义 :
HRESULT URLDownloadToFile( LPUNKNOWN pCaller, LPCSTR szURL, LPCSTR szFileName, DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB );
HRESULT OnProgress( ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText );
以下是IBindStatusCallback的派生类写法 :
//头文件
//--------------------------------------------------------------------------- #ifndef CallbackH #define CallbackH #include <Urlmon.h> #include "DownThread.h" //--------------------------------------------------------------------------- class TCallback : public IBindStatusCallback { DWORD m_cRef; //IBinding *m_pbinding; private: STDMETHODIMP QueryInterface(REFIID riid,void **ppv); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); STDMETHODIMP GetBindInfo(DWORD *grfBINDF,BINDINFO *bindinfo); STDMETHODIMP GetPriority(LONG *nPriority); STDMETHODIMP OnDataAvailable(DWORD grfBSCF,DWORD dwSize, FORMATETC *formatetc,STGMEDIUM *stgmed); STDMETHODIMP OnLowResource(DWORD reserved); STDMETHODIMP OnObjectAvailable(REFIID iid,IUnknown *punk); STDMETHODIMP OnStartBinding(DWORD dwReserved,IBinding *pib); STDMETHODIMP OnStopBinding(HRESULT hresult,LPCWSTR szError); STDMETHODIMP OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText); public: TDownload *D; TCallback() {m_cRef = 1;/*m_pbinding = NULL*/}; //~TCallback() {if (m_pbinding) m_pbinding->Release();}; }; #endif
//CPP文件
//--------------------------------------------------------------------------- #include "Callback.h" //--------------------------------------------------------------------------- STDMETHODIMP TCallback::QueryInterface(REFIID riid,void **ppv) { *ppv = NULL; if (riid==IID_IUnknown || riid==IID_IBindStatusCallback) { *ppv = this; AddRef(); return S_OK; } return E_NOINTERFACE; } STDMETHODIMP_(ULONG) TCallback::AddRef() { return m_cRef++; } STDMETHODIMP_(ULONG) TCallback::Release() { if(--m_cRef==0) { delete this; return 0; } return m_cRef; } STDMETHODIMP TCallback::GetBindInfo(DWORD *grfBINDF,BINDINFO *bindinfo) { return E_NOTIMPL; } STDMETHODIMP TCallback::GetPriority(LONG *nPriority) { return E_NOTIMPL; } STDMETHODIMP TCallback::OnDataAvailable(DWORD grfBSCF,DWORD dwSize, FORMATETC *formatetc,STGMEDIUM *stgmed) { return E_NOTIMPL; } STDMETHODIMP TCallback::OnLowResource(DWORD reserved) { return E_NOTIMPL; } STDMETHODIMP TCallback::OnObjectAvailable(REFIID iid,IUnknown *punk) { return E_NOTIMPL; } STDMETHODIMP TCallback::OnStartBinding(DWORD dwReserved,IBinding *pib) { return E_NOTIMPL; } STDMETHODIMP TCallback::OnStopBinding(HRESULT hresult,LPCWSTR szError) { return E_NOTIMPL; } STDMETHODIMP TCallback::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) { AnsiString Status; switch (ulStatusCode) { case BINDSTATUS_FINDINGRESOURCE : Status = "Finding resource " + AnsiString(szStatusText); break; case BINDSTATUS_CONNECTING : Status = "Connecting to " + AnsiString(szStatusText); break; case BINDSTATUS_REDIRECTING : Status = "Redirecting..."; break; case BINDSTATUS_BEGINDOWNLOADDATA : Status = "Start to download " + AnsiString(szStatusText); break; case BINDSTATUS_DOWNLOADINGDATA : Status = "Downloading..."; break; case BINDSTATUS_ENDDOWNLOADDATA : Status = "Complete downloading " + AnsiString(szStatusText); break; case BINDSTATUS_BEGINDOWNLOADCOMPONENTS : Status = "Start to download components"; break; case BINDSTATUS_INSTALLINGCOMPONENTS : Status = "Installing components..." ; break; case BINDSTATUS_ENDDOWNLOADCOMPONENTS : Status = "Complete downloading components"; break; case BINDSTATUS_USINGCACHEDCOPY : Status = "Copying form buffer..."; break; case BINDSTATUS_SENDINGREQUEST : Status = "Sending request..."; break; case BINDSTATUS_CLASSIDAVAILABLE : Status = "Class ID is available"; break; case BINDSTATUS_MIMETYPEAVAILABLE : Status = "MIME type is available"; break; case BINDSTATUS_CACHEFILENAMEAVAILABLE : Status = "Cache file name is available"; break; case BINDSTATUS_BEGINSYNCOPERATION : Status = "Start sync operation"; break; case BINDSTATUS_ENDSYNCOPERATION : Status = "Complete sync operation"; break; case BINDSTATUS_BEGINUPLOADDATA : Status = "Start to upload data"; break; case BINDSTATUS_UPLOADINGDATA : Status = "Uploading data"; break; case BINDSTATUS_ENDUPLOADDATA : Status = "Complete Uploading data"; break; case BINDSTATUS_PROTOCOLCLASSID : Status = "Protocol class ID is available"; break; case BINDSTATUS_ENCODING : Status = "Encoding..."; break; case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : Status = "Verified MIME is available"; break; case BINDSTATUS_CLASSINSTALLLOCATION : Status = "Class install location"; break; case BINDSTATUS_DECODING : Status = "Decoding..."; break; case BINDSTATUS_LOADINGMIMEHANDLER : Status = "Loading MIME handler"; break; case BINDSTATUS_CONTENTDISPOSITIONATTACH : Status = "Content disposition attach"; break; case BINDSTATUS_FILTERREPORTMIMETYPE : Status = "Filter report MIME type"; break; case BINDSTATUS_CLSIDCANINSTANTIATE : Status = "Clsid can instantiate"; break; case BINDSTATUS_IUNKNOWNAVAILABLE : Status = "Unknown available"; break; case BINDSTATUS_DIRECTBIND : Status = "Direct bind"; break; case BINDSTATUS_RAWMIMETYPE : Status = "MIME type of the resource, before any code sniffing is done"; break; case BINDSTATUS_PROXYDETECTING : Status = "Detecting proxy..."; break; case BINDSTATUS_ACCEPTRANGES : Status = "Valid types of range requests for a resource"; break; default : Status = ""; } //在这里填入显示进度的代码。 //如果要实现中断下载,最好在一个线程中调用URLDownloadToFile函数, //如下面代码中的 D 既是一个线程,设定DoCancel变量来决定是否取消下载。 //DoProgress是线程中显示进度的函数。 if (!Status.IsEmpty()) D->ShowMsg(Status); D->DoProgress(ulProgress,ulProgressMax,ulStatusCode); if (D->DoCancel) return E_ABORT; else return S_OK; }
使用范例:
#include <Urlmon.h> //还须加入urlmon.lib ... TCallback Status; //回调类实例 URLDownloadToFile(NULL,"http://...","C://???",0,&Status);