📄 controller_downloadfile.h
字号:
/*
* 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 + -