⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 controller_downloadfile.h

📁 用VC
💻 H
📖 第 1 页 / 共 2 页
字号:
/*
 *   Copyright (C) =USTC= Fu Li
 *
 *   Author   :  Fu Li
 *   Create   :  2005-9-25
 *   Home     :  www.crazy-bit.com
 *   Mail     :  crazybit@263.net
 *   History  :  
 */
#pragma once
#pragma warning (disable : 4786) // identifier was truncated to '255' characters in the browser information
#include <comdef.h>
#include <FSTREAM>
#include <DEQUE>
#include <ASSERT.H>
#include <afxinet.h>
#pragma comment(lib, "wininet.lib")

//=============================================================================
/**
 *  Map table.
 */
template<class T1, class T2>
class PCL_TT_Convertor
{
public:
    /// T1 ==> T2
    T2 First_to_Second (const T1& t1, const T2& t2Default) const
    {
        int   i = GetIndexT1(t1) ;
        return (i==-1) ? t2Default : m_t2Tab[i] ;
    }

    /// T2 ==> T1
    T1 Second_to_First (const T2& t2, const T1& t1Default) const
    {
        int   i = GetIndexT2(t2) ;
        return (i==-1) ? t1Default : m_t1Tab[i] ;
    }

    /// Get element count.
    int GetElementCount() const
    {
        if (m_t1Tab.size() == m_t2Tab.size())
            return (int)m_t1Tab.size();
        assert(false) ;
        return 0 ;
    }

    /// Get 0-based index in array by t1, return -1 if not found.
    int GetIndexT1 (const T1& t1) const
    {
        for (size_t i=0 ; i < m_t1Tab.size() ; i++)
        {
            if (m_t1Tab[i] == t1)
                return (int)i ;
        }
        return -1 ;
    }
    /// Get 0-based index in array by t2, return -1 if not found.
    int GetIndexT2 (const T2& t2) const
    {
        for (size_t i=0 ; i < m_t2Tab.size() ; i++)
        {
            if (m_t2Tab[i] == t2)
                return (int)i ;
        }
        return -1 ;
    }

    /// Get first element.
    const T1& GetT1 (int n) const {assert(IsValidIndex(n)); return m_t1Tab[n];}
          T1& GetT1 (int n)       {assert(IsValidIndex(n)); return m_t1Tab[n];}
    /// Get second element.
    const T2& GetT2 (int n) const {assert(IsValidIndex(n)); return m_t2Tab[n];}
          T2& GetT2 (int n)       {assert(IsValidIndex(n)); return m_t2Tab[n];}

    /// Add a new element into table.
    void AddElement (const T1& t1, const T2& t2)
    {
        m_t1Tab.push_back (t1) ;
        m_t2Tab.push_back (t2) ;
    }

    /// Remove an element from table by 0-based index.
    void RemoveElement (int nIndex)
    {
        if (IsValidIndex(nIndex))
        {
            m_t1Tab.erase(m_t1Tab.begin() + nIndex) ;
            m_t2Tab.erase(m_t2Tab.begin() + nIndex) ;
        }
        else
            {assert(false);}
    }
    /// Remove an element from table.
    void RemoveElement (const T1& t1, const T2& t2)
    {
        for (int i=0 ; i < GetElementCount() ; i++)
            if ((m_t1Tab[i] == t1) && (m_t2Tab[i] == t2))
            {
                RemoveElement(i) ;
                return ; // must return immediately
            }
    }

    /// Clear all elements.
    void Clear()
    {
        m_t1Tab.clear() ;
        m_t2Tab.clear() ;
    }

    /// Pop a element from front of list.
    void PopFront()
    {
        if (GetElementCount())
        {
            m_t1Tab.pop_front() ;
            m_t2Tab.pop_front() ;
        }
    }

private:
    bool IsValidIndex (int nIndex) const
    {
        return (nIndex >= 0) && (nIndex < GetElementCount()) ;
    }

private:
    std::deque<T1>   m_t1Tab ;
    std::deque<T2>   m_t2Tab ;
};

//=============================================================================
/**
 *  Create a thread to download a file.
 *  The owner window will receive notify message.
 */
template<class T>
class FCDownloadFileWndBase : public T
{
public:
    /// Default constructor.
    FCDownloadFileWndBase () {}
    /// Dialog constructor.
    FCDownloadFileWndBase (UINT nID, CWnd* pParent) : T(nID, pParent) {}
    /// CFormView constructor.
    FCDownloadFileWndBase (UINT nID) : T(nID) {}

    virtual ~FCDownloadFileWndBase()
    {
        // wait for all thread exit.
        for (int i=0 ; i < m_ThreadTab.GetElementCount() ; i++)
        {
            if (::WaitForSingleObject (m_ThreadTab.GetT1(i), 10 * 1000) == WAIT_TIMEOUT)
            {
                ::TerminateThread (m_ThreadTab.GetT1(i), 0) ;
            }
            ::CloseHandle (m_ThreadTab.GetT1(i)) ;
        }
    }

    /// Create a thread to download file, return immediately if the file is downloading.
    void DownloadFile (LPCTSTR strFileURL, int nPriority=THREAD_PRIORITY_IDLE)
    {
        if (!lstrlen(strFileURL))
            return ;

        HANDLE   h = m_ThreadTab.Second_to_First(strFileURL, NULL) ;
        if (h)
        {
            if (::WaitForSingleObject(h,0) == WAIT_TIMEOUT) // downloading now
            {
                // ASSERT(FALSE);
                return ;
            }
            else
            {
                m_ThreadTab.RemoveElement (h, strFileURL) ; // remove
                ::CloseHandle (h) ;
            }
        }

        DWORD      _i ;
        PARA_DATA  * pPara = new PARA_DATA ;
        pPara->pThis = this ;
        pPara->strFileURL = strFileURL ;
        h = ::CreateThread (NULL, 0, __uis_DownloadFile, pPara, CREATE_SUSPENDED, &_i); ASSERT(h);
        m_ThreadTab.AddElement (h, strFileURL) ;
        ::SetThreadPriority (h, nPriority) ;
        ::ResumeThread (h) ;
    }

protected:
    /**
     *  @name Owner window will receive these notify.
     */
    //@{
    /**
     *  Check last modified time of download file URL.
     *  @return continue to download file return TRUE, otherwise return FALSE.
     */
    virtual BOOL DownloadFile_OnCheckTime (CString strFileURL, CString strTime) =0 ;
    /// The file download finished.
    virtual void DownloadFile_OnFinished (CString strFileURL, char* pBuffer, int nLength) {}
    /// Fill proxy's username & password to validate.
    virtual void DownloadFile_OnProxyValidate (CString strFileURL, CString& strUsername, CString& strPassword) {}
    /// Error during download.
    virtual void DownloadFile_OnError (CString strFileURL) {}
    /// Start download file.
    virtual void DownloadFile_OnStartDownload (CString strFileURL) {}
    /**
     *  Download progress.
     *  @param nNow : downloaded bytes.
     *  @param nTotal : total bytes, don't know size if 0.
     */
    virtual void DownloadFile_OnProgress (CString strFileURL, int nNow, int nTotal) {}
    //@}

    // inner
    virtual LRESULT WindowProc (UINT msg, WPARAM wParam, LPARAM lParam)
    {
        if (msg == GetMsg_CheckTime())
        {
            WM_DLF_CHECKTIME   * p = (WM_DLF_CHECKTIME*)wParam ;
            return DownloadFile_OnCheckTime (*p->pstrFileURL, *p->pStrTime) ;
        }
        else if (msg == GetMsg_DownFinished())
        {
            WM_DLF_FINISHED   * p = (WM_DLF_FINISHED*)wParam ;
            DownloadFile_OnFinished (*p->pstrFileURL, p->pBuffer, p->nLength) ;
            return 0 ;
        }
        else if (msg == GetMsg_ProxyValidate())
        {
            WM_DLF_PROXY_VALIDATE   * p = (WM_DLF_PROXY_VALIDATE*)wParam ;
            DownloadFile_OnProxyValidate (*p->pstrFileURL, *p->pStrUsername, *p->pStrPassword) ;
            return 0 ;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -