ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Urldownloadtofile()
    프로그래밍/Windows API 2009. 5. 6. 12:17

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

    댓글