웹, HTML

URLDownloadToFile 에서의 콜백 구현

디버그정 2008. 9. 15. 19:41

집의 OpenWiki 에서 옮겨온다. 큰의미있는 코드는 아니고 이전에 적은게 아까워서..


URLDownloadToFile

http 를 이용해 파일을 다운받기 위한 함수. 예전에 잠깐 테스트를 위해서 써본적이 있고, 단순히 파일을 받는것에는 아무 문제가 없었다. 하지만 당시 일반적인 http request 가 아니었기 때문에 http socket class 를 코딩했었다. URLDownloadToFile 자체 보다는 콜백 인터페이스를 상속받아서 구현한 부분이 오히려 가치가 있는 소스다.

source

부를때

CBindTransferStatus m_bindTransfer;
...
...
HRESULT hr = URLDownloadToFile(NULL, "http://a.b.c/d.avi", "c:\\d.avi", dwReserved, &m_bindTransfer);

콜백 인터페이스 구현

CBindTransferStatus.h

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

class CBindTransferStatus : public IBindStatusCallback
{
public:
        CBindTransferStatus();
        virtual ~CBindTransferStatus();


//////////////////////////////////////////////////////////////////////////////////////////
//      callee 의 포인터 저장
//////////////////////////////////////////////////////////////////////////////////////////
protected:
        CComicGetDlg*           m_pThis;
public:
        void                    Init(CComicGetDlg* pThis){m_pThis=pThis;};

//////////////////////////////////////////////////////////////////////////////////////////
//      IUnknown Method 구현
//////////////////////////////////////////////////////////////////////////////////////////
        STDMETHOD_(ULONG, AddRef)();
        STDMETHOD_(ULONG, Release)();
        STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppvObj);


//////////////////////////////////////////////////////////////////////////////////////////
//      IBindStatusCallback Method 구현
//////////////////////////////////////////////////////////////////////////////////////////
        STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindinfo);
        STDMETHOD(GetPriority)(LONG *pnPriotity);
        STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pfmtetc, STGMEDIUM *pstgmed);
        STDMETHOD(OnLowResource)(DWORD dwReserved);
        STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown* punk);
        STDMETHOD(OnProgress)(ULONG ulProgess, ULONG ulProgessMax, ULONG ulStatusCode, LPCWSTR szStatusCode);
        STDMETHOD(OnStartBinding)(DWORD dwReserved, IBinding *pbinding);
        STDMETHOD(OnStopBinding)(HRESULT hrStatus, LPCWSTR szStatusText);
};

CBindTransferStatus.cpp

CBindTransferStatus::CBindTransferStatus()
{
}

CBindTransferStatus::~CBindTransferStatus()
{
}

STDMETHODIMP_(ULONG) CBindTransferStatus::AddRef()
{
        return 1;
}


STDMETHODIMP_(ULONG) CBindTransferStatus::Release()
{
        return 0;
}

STDMETHODIMP CBindTransferStatus::QueryInterface(REFIID iid, LPVOID* ppvObj)
{
        if( iid == __uuidof(IBindStatusCallback) ) {
                *ppvObj = (IBindStatusCallback*)this;
                return S_OK;
        }
        else if( iid == __uuidof(IUnknown) ) {
                *ppvObj = (IUnknown*)this;
                return S_OK;
        }

        return E_NOINTERFACE;
}


// Provides information about how the bind operation should be handled when called by an asynchronous moniker.
STDMETHODIMP CBindTransferStatus::GetBindInfo(DWORD* pgrfBINDF, BINDINFO *pbindinfo)
{
#ifdef _DEBUG
        CString strHowBound;
        switch( *pgrfBINDF )
        {
        case 0x00000001:strHowBound = "BINDF_ASYNCHRONOUS";break;
        case 0x00000002:strHowBound = "BINDF_ASYNCSTORAGE";break;
        case 0x00000004:strHowBound = "BINDF_NOPROGRESSIVERENDERING";break;
        case 0x00000008:strHowBound = "BINDF_OFFLINEOPERATION";break;
        case 0x00000010:strHowBound = "BINDF_GETNEWESTVERSION";break;
        case 0x00000020:strHowBound = "BINDF_NOWRITECACHE";break;
        case 0x00000040:strHowBound = "BINDF_NEEDFILE";break;
        case 0x00000080:strHowBound = "BINDF_PULLDATA";break;
        case 0x00000100:strHowBound = "BINDF_IGNORESECURITYPROBLEM";break;
        case 0x00000200:strHowBound = "BINDF_RESYNCHRONIZE";break;
        case 0x00000400:strHowBound = "BINDF_HYPERLINK";break;
        case 0x00000800:strHowBound = "BINDF_NO_UI";break;
        case 0x00001000:strHowBound = "BINDF_SILENTOPERATION";break;
        case 0x00002000:strHowBound = "BINDF_PRAGMA_NO_CACHE";break;
        case 0x00004000:strHowBound = "BINDF_GETCLASSOBJECT";break;
        case 0x00008000:strHowBound = "BINDF_RESERVED_1";break;
        case 0x00010000:strHowBound = "BINDF_FREE_THREADED";break;
        case 0x00020000:strHowBound = "BINDF_DIRECT_READ";break;
        case 0x00040000:strHowBound = "BINDF_FORMS_SUBMIT";break;
        case 0x00080000:strHowBound = "BINDF_GETFROMCACHE_IF_NET_FAIL";break;
        case 0x00100000:strHowBound = "BINDF_FROMURLMON";break;
        case 0x00200000:strHowBound = "BINDF_FWD_BACK";break;
        case 0x00400000:strHowBound = "BINDF_RESERVED_2";break;
        case 0x00800000:strHowBound = "BINDF_RESERVED_3";break;
        default:strHowBound="*UNKNOWN*";
        }

        TRACE("GetBindInfo Called, how : %s\n", strHowBound );

#endif

        return S_NOTIMPL;
}


// Obtains the priority for the bind operation when called by an asynchronous moniker.
STDMETHODIMP CBindTransferStatus::GetPriority(LONG* pnPriority)
{
        TRACE("GetPriority Called\n");
        return E_NOTIMPL;
}


// Provides data to the client as it becomes available during asynchronous bind operations
STDMETHODIMP CBindTransferStatus::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pfmtetc, STGMEDIUM* pstgmed)
{
        TRACE("OnDataAvailable Called\n");
        return E_NOTIMPL;
}


//  Not currently implemented
STDMETHODIMP CBindTransferStatus::OnLowResource(DWORD dwReserved)
{
        return E_NOTIMPL;
}


//      Passes the requested object interface pointer to the client.
STDMETHODIMP CBindTransferStatus::OnObjectAvailable(REFIID riid, IUnknown* punk)
{
        TRACE("OnObjectAvailable Called\n");
        return E_NOTIMPL;
}


STDMETHODIMP CBindTransferStatus::OnProgress(ULONG ulProgess, ULONG ulProgessMax, ULONG ulStatusCode, LPCWSTR szStatusCode)
{
        return E_NOTIMPL;
}




STDMETHODIMP CBindTransferStatus::OnStartBinding(DWORD dwReserved, IBinding* pbinding)
{
        return E_NOTIMPL;
}


STDMETHODIMP CBindTransferStatus::OnStopBinding(HRESULT hrStatus, LPCWSTR szStatusText)
{
        return E_NOTIMPL;
}


CategoryProgrammingWindows

http download 다운로드 인터페이스 구현 인터페이스구현