MFC类CAsyncMonikerFile可以用来从Internet上下载文件,其原理在于利用了COM对象Moniker.先上个例子:
class
CAsyncURLDownload :
public
CAsyncMonikerFile
{
public :
CAsyncURLDownload();
virtual ~ CAsyncURLDownload();
protected :
/*
* 在异步约束操作中,调用OnDataAvailable来向客户提供有效的数据
* dwSize:约束开始后数据传输的累计数(字节)。
* dwBscfFlag:
BSCF_FIRSTDATANOTIFICATION 表示对一个特定的约束操作,第一次调用OnDataAvailable。
BSCF_INTERMEDIATEDATANOTIFICATION 表示对一个特定的约束操作,中间调用OnDataAvailable。
BSCF_LASTDATANOTIFICATION 表示对一个特定的约束操作,最后一次调用OnDataAvailable。
*/
virtual void OnDataAvailable(DWORD dwSize, DWORD dwBscfFlag);
/*
* 在数据下载过程中调用它来标示进度
* ulProgress: 表示约束操作的当前进度号
* ulProgressMax:表示调用OnProgress的操作中,ulProgress最大可能值。
* ulStatusCode: 提供识别约束操作进度的附加信息。
* szStatusText: 有关当前进度的信息,依赖于ulStatusCode的值。
*/
virtual void OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCTSTR szStatusText);
};
///////////////////// cpp文件 /////////////////////////////////////////////////////////////////////////////////////////////
CAsyncURLDownload::CAsyncURLDownload()
{
}
CAsyncURLDownload:: ~ CAsyncURLDownload()
{
}
void CAsyncURLDownload::OnDataAvailable( DWORD dwSize, DWORD dwBscfFlag )
{
CAsyncMonikerFile::OnDataAvailable(dwSize, dwBscfFlag);
char szBuffer[ 1024 ];
UINT uBytesRead = 0 ;
// 打开文件
HANDLE hFile = ::CreateFile( _T( " D:\\config.ini " ), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, CREATE_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL );
if ( INVALID_HANDLE_VALUE == hFile )
return ;
do
{
// 读取已下载的数据
uBytesRead = this -> Read( szBuffer, _countof( szBuffer ) - 1 );
szBuffer[uBytesRead] = ' \0 ' ;
// 写文件
DWORD dwSizeToWrite = 0 ;
::WriteFile( hFile, szBuffer, uBytesRead, & dwSizeToWrite, NULL );
} while ( uBytesRead == _countof( szBuffer ) - 1 );
::CloseHandle( hFile );
}
void CAsyncURLDownload::OnProgress( ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCTSTR szStatusText )
{
CAsyncMonikerFile::OnProgress(ulProgress, ulProgressMax, ulStatusCode, szStatusText);
if ( ulProgressMax == 0 )
return ;
// 在输出窗口输出进度值
CString strHint;
strHint.Format( _T( " Progress: %d " ), ( int )(( float )ulProgress / ulProgressMax * 100 ) );
strHint += _T( " %\n " );
::OutputDebugString( strHint );
}
///////////////////////////////////////////////////////////////////////////////////////////// /
使用:CAsyncURLDownload asyncDown;
asyncDown.Open( _T( " 下载地址 " ) );
PS: 这种下载方法缺乏健全的操作,比如中断下载等,这种下载方法只适合下载一些配置性的小文件,但是多一种手段多一份选择,这种方案毕竟比开线程下载简单的多,而且贵在这种下载不会阻塞线程.
{
public :
CAsyncURLDownload();
virtual ~ CAsyncURLDownload();
protected :
/*
* 在异步约束操作中,调用OnDataAvailable来向客户提供有效的数据
* dwSize:约束开始后数据传输的累计数(字节)。
* dwBscfFlag:
BSCF_FIRSTDATANOTIFICATION 表示对一个特定的约束操作,第一次调用OnDataAvailable。
BSCF_INTERMEDIATEDATANOTIFICATION 表示对一个特定的约束操作,中间调用OnDataAvailable。
BSCF_LASTDATANOTIFICATION 表示对一个特定的约束操作,最后一次调用OnDataAvailable。
*/
virtual void OnDataAvailable(DWORD dwSize, DWORD dwBscfFlag);
/*
* 在数据下载过程中调用它来标示进度
* ulProgress: 表示约束操作的当前进度号
* ulProgressMax:表示调用OnProgress的操作中,ulProgress最大可能值。
* ulStatusCode: 提供识别约束操作进度的附加信息。
* szStatusText: 有关当前进度的信息,依赖于ulStatusCode的值。
*/
virtual void OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCTSTR szStatusText);
};
///////////////////// cpp文件 /////////////////////////////////////////////////////////////////////////////////////////////
CAsyncURLDownload::CAsyncURLDownload()
{
}
CAsyncURLDownload:: ~ CAsyncURLDownload()
{
}
void CAsyncURLDownload::OnDataAvailable( DWORD dwSize, DWORD dwBscfFlag )
{
CAsyncMonikerFile::OnDataAvailable(dwSize, dwBscfFlag);
char szBuffer[ 1024 ];
UINT uBytesRead = 0 ;
// 打开文件
HANDLE hFile = ::CreateFile( _T( " D:\\config.ini " ), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, CREATE_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL );
if ( INVALID_HANDLE_VALUE == hFile )
return ;
do
{
// 读取已下载的数据
uBytesRead = this -> Read( szBuffer, _countof( szBuffer ) - 1 );
szBuffer[uBytesRead] = ' \0 ' ;
// 写文件
DWORD dwSizeToWrite = 0 ;
::WriteFile( hFile, szBuffer, uBytesRead, & dwSizeToWrite, NULL );
} while ( uBytesRead == _countof( szBuffer ) - 1 );
::CloseHandle( hFile );
}
void CAsyncURLDownload::OnProgress( ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCTSTR szStatusText )
{
CAsyncMonikerFile::OnProgress(ulProgress, ulProgressMax, ulStatusCode, szStatusText);
if ( ulProgressMax == 0 )
return ;
// 在输出窗口输出进度值
CString strHint;
strHint.Format( _T( " Progress: %d " ), ( int )(( float )ulProgress / ulProgressMax * 100 ) );
strHint += _T( " %\n " );
::OutputDebugString( strHint );
}
///////////////////////////////////////////////////////////////////////////////////////////// /
使用:CAsyncURLDownload asyncDown;
asyncDown.Open( _T( " 下载地址 " ) );