利用CAsyncMonikerFile下载文件

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: 这种下载方法缺乏健全的操作,比如中断下载等,这种下载方法只适合下载一些配置性的小文件,但是多一种手段多一份选择,这种方案毕竟比开线程下载简单的多,而且贵在这种下载不会阻塞线程.
原文地址:https://www.cnblogs.com/fangkm/p/1534393.html