| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 525 人关注过本帖
标题:[原创][求助]动态显示下载过程的方法?
只看楼主 加入收藏
停止流浪
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2006-12-16
收藏
 问题点数:0 回复次数:4 
[原创][求助]动态显示下载过程的方法?
现在用VC做了个给设备下载参数的小软件,但不知道怎么动态显示下载的整个过程
因为如果是静态的话,很难知道其中串口是否已经中断,要等到最后才知道结果
VC的进度条的时间划分是怎么弄的,如何判断开始和结束。(下载主要是把文件直接送到缓冲区内,然后下载到终端)
以前用的是VB,所以现在不知道应该怎么下手。
请高手指点迷津,谢谢
搜索更多相关主题的帖子: 动态 
2006-12-16 18:26
corrupt
Rank: 2
等 级:新手上路
威 望:3
帖 子:535
专家分:0
注 册:2004-9-29
收藏
得分:0 
VC的进度条
先 判断 有多少字节..
然后,下载一部分后,计算 下载的大概百分数, 然后调整 进度条,,

2006-12-17 15:03
停止流浪
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2006-12-16
收藏
得分:0 
没用过VC的进度条,不是很清楚
corrupt,谢谢你,有没有相关的例子呢
2006-12-22 08:59
清澂居士
Rank: 6Rank: 6
等 级:贵宾
威 望:28
帖 子:1237
专家分:7
注 册:2006-12-19
收藏
得分:0 

// HttpClient.h: HTTP协议客户端的实现类
//
//////////////////////////////////////////////////////////////////////

#if !defined(_HTTPCLIENT_H__)
#define _HTTPCLIENT_H__

#include "../comm/tcp.h"


#pragma warning(disable : 4786)

#include <map>
#include <string>
using namespace std;

#define BUFFER_SIZE 8192
#define HEADS_BUFFER_SIZE 2048
#define PEEK_SIZE 500
#define TCP_TIMEOUT 5

class CHttpClient
{
public:
void Cancel();
const char* GetStatusString();
CHttpClient();
virtual ~CHttpClient();

bool Download(char* url,char* fname); //直接下载到文件
bool Download(char* url,HWND hParent,long msg = WM_USER+1); //消息方式下载数据流

inline long Instr(char* from,char* find);
virtual void OnDataRecived(char* data,long datasize,int first = false );
long GetHostName(char *url, char *buf);
int GetStatus();
long GetHeader(char* headname,char* buf);
long GetHeader(char* from,char* searchfor,char* buf);
bool Reset();
private:
long m_Message;
HWND m_hParent;
bool m_noCancel;
char m_fname[BUFFER_SIZE];
int m_status;
char m_heads_buffer[HEADS_BUFFER_SIZE];
char m_buffer[BUFFER_SIZE+1];
CTcp tcp;

map<const int,string> m_map;
};

#endif


//----------------------------------------------------------------
// HttpClient.cpp: implementation of the CHttpClient class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HttpClient.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CHttpClient::CHttpClient()
{
Reset();
memset(m_fname,0,BUFFER_SIZE);
tcp.init();

m_map[100]= "Continue";
m_map[101]= "Switching Protocols";
m_map[200]= "OK";
m_map[201]= "Created";
m_map[202]= "Accepted";
m_map[203]= "Non-Authoritative Information";
m_map[204]= "No Content";
m_map[205]= "Reset Content";
m_map[206]= "Partial Content";
m_map[300]= "Multiple Choices";
m_map[301]= "Moved Permanently";
m_map[302]= "Found";
m_map[303]= "See Other";
m_map[304]= "Not Modified";
m_map[305]= "Use Proxy";
m_map[307]= "Temporary Redirect";
m_map[400]= "Bad Request";
m_map[401]= "Unauthorized";
m_map[402]= "Payment Required";
m_map[403]= "Forbidden";
m_map[404]= "Not Found";
m_map[405]= "Method Not Allowed";
m_map[406]= "Not Acceptable";
m_map[407]= "Proxy Authentication Required";
m_map[408]= "Request Time-out";
m_map[409]= "Conflict";
m_map[410]= "Gone ";
m_map[411]= "Length Required";
m_map[412]= "Precondition Failed";
m_map[413]= "Request Entity Too Large";
m_map[414]= "Request-URI Too Large";
m_map[415]= "Unsupported Media Type";
m_map[416]= "Requested range not satisfiabl";
m_map[417]= "Expectation Failed";
m_map[500]= "Internal Server Error";
m_map[501]= "Not Implemented";
m_map[502]= "Bad Gateway";
m_map[503]= "Service Unavailable";
m_map[504]= "Gateway Time-out";
m_map[505]= "HTTP Version not supported";
}

CHttpClient::~CHttpClient()
{

}

bool CHttpClient::Reset()
{
m_noCancel=true;
m_hParent=NULL;
m_Message=0;
memset(m_buffer,0,BUFFER_SIZE);
memset(m_heads_buffer,0,HEADS_BUFFER_SIZE);
return 1;
}

//HTTP下载主程序
bool CHttpClient::Download(char *url, HWND hParent,long msg)
{
m_Message=m_Message;
m_hParent=hParent;

//状态为忙

Reset();
char hostname[256];
memset(hostname,0,256);
GetHostName(url,hostname);

long AllSize=0;
long ReadSize=0;
bool headFinished=false;

int s;
s=tcp.connect(hostname,80,TCP_TIMEOUT,1);
if(s<0)
return false;

sprintf(m_buffer,"GET %s HTTP/1.0 \r\nHost:%s\r\nAccept:*/*\r\nUser-Agent: AutoUpdate/1.0 \r\n\r\n",url,hostname);
tcp.send(s,m_buffer,strlen(m_buffer),TCP_TIMEOUT);

//先取PEEK_SIZE个字节,这样可以确保取到Content-Length
ReadSize=tcp.recv(s,m_buffer,PEEK_SIZE,TCP_TIMEOUT);
if(ReadSize==-1)
return false;
m_buffer[ReadSize]=0;

memset(hostname,0,256);

int m,n;
m=Instr(m_buffer," ");
n=Instr(m_buffer+m+1," ");
memcpy(hostname,m_buffer+m+1,n);

m_status=atoi(hostname);
if(m_status!=200)return false;

memset(hostname,0,256);
if(GetHeader(m_buffer,"Content-Length",hostname)<0)
return false;

//取得内容总长度
AllSize=atol(hostname);
memset(hostname,0,256);

//寻找HTTP数据区表示
int i;
i=Instr(m_buffer,"\r\n\r\n");
if(i>0)
{
memcpy(m_heads_buffer,m_buffer,i+4);
headFinished=true;
ReadSize=ReadSize-i-4;
OnDataRecived(m_buffer+i+4,ReadSize,true);
}

while(ReadSize<AllSize && m_noCancel)
{
int nSize;
if(headFinished)
{
nSize=(AllSize-ReadSize)>BUFFER_SIZE?BUFFER_SIZE:(AllSize-ReadSize);
memset(m_buffer,0,BUFFER_SIZE);
if(tcp.recv(s,m_buffer,nSize,TCP_TIMEOUT)!=nSize)
return false;
ReadSize+=nSize;
m_buffer[nSize]=0;

OnDataRecived(m_buffer,nSize);
}
else
{
nSize=(AllSize-ReadSize)>(BUFFER_SIZE-ReadSize)?(BUFFER_SIZE-ReadSize):(AllSize-ReadSize);
if(tcp.recv(s,m_buffer+ReadSize,nSize,TCP_TIMEOUT)!=nSize)
return false;
ReadSize+=nSize;
m_buffer[nSize]=0;
//寻找HTTP数据区表示
i=Instr(m_buffer,"\r\n\r\n");
if(i>0)
{
memcpy(m_heads_buffer,m_buffer,i+4);
headFinished=true;
ReadSize=ReadSize-i-4;
OnDataRecived(m_buffer+i+4,ReadSize,true);
}
}
}

if(!m_noCancel)remove(m_fname);

tcp.close(s);
return true;
}


int CHttpClient::GetStatus()
{
return m_status;
}

//从URL中取出主机名
long CHttpClient::GetHostName(char *url, char *buf)
{
int i,j;
char* lpsz = _tcsstr(url, "//");
if(!lpsz)return -1;
i=lpsz-url+2;

lpsz= _tcsstr(url+i, "/");
if(!lpsz)return -1;
j=lpsz-url;

memcpy(buf,url+i,j-i);
return j-i;
}

long CHttpClient::GetHeader(char *headname, char *buf)
{
return GetHeader(m_heads_buffer,headname,buf);
}

long CHttpClient::GetHeader(char *from, char *headname, char *buf)
{
char *p;
char* lpsz = _tcsstr(from, headname);
if(!lpsz)return -1;

//lpsz++;
p=lpsz+strlen(headname)+2;
lpsz = _tcsstr(p, "\r\n");

if(!lpsz)return -1;

memcpy(buf,p,lpsz-p);

return strlen(buf);
}

void CHttpClient::OnDataRecived(char* data,long datasize ,int first)
{

if(m_hParent)
::SendMessage(m_hParent,m_Message,(unsigned int)data,datasize);
else
{
if(first)remove(m_fname);
FILE* f=fopen(m_fname,"ab");
if(f){
fwrite(data,1,datasize,f);
fclose(f);
}
}
//处理数据,一定要拷贝走哦,缓冲区可是循环使用的
}

inline long CHttpClient::Instr(char *from, char *find)
{
char* lpsz = _tcsstr(from, find);
return (!lpsz)?-1:lpsz-from;
}

bool CHttpClient::Download(char *url, char *fname)
{
strcpy(m_fname,fname);
return Download(url,NULL,NULL);
}

const char* CHttpClient::GetStatusString()
{
return m_map[m_status].c_str();
}

void CHttpClient::Cancel()
{
m_noCancel=false;
}





专用于下载到本地磁盘的同时显示进度条

使用本类,请先取得CHttpClient下载类


// HttpClientProcess.h: 专用于下载到本地磁盘的同时显示进度条
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_HTTPCLIENTPROCESS_H__)
#define AFX_HTTPCLIENTPROCESS_H__


#include "HttpClient.h"

class CHttpClientProcess : public CHttpClient
{
public:
CHttpClientProcess();
virtual ~CHttpClientProcess();

bool Download(char*url,char*fname,void* p); //p为进度条控件的指针
virtual void OnDataRecived(char* data,long datasize,int first = false );
private:
CProgressCtrl* m_lpProcessBar;
};

#endif


//------------------------------------------------------------------
// HttpClientProcess.cpp
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HttpClientProcess.h"


CHttpClientProcess::CHttpClientProcess()
{
m_lpProcessBar=NULL;
}

CHttpClientProcess::~CHttpClientProcess()
{

}
void CHttpClientProcess::OnDataRecived(char* data,long datasize,int first)
{
CHttpClient::OnDataRecived(data,datasize,first);
if(!m_lpProcessBar)return;

if(first)
{
char buf[128];
memset(buf,0,128);
GetHeader("Content-Length",buf);
m_lpProcessBar->SetRange32(0,atol(buf));
m_lpProcessBar->SetPos(datasize);
}
else
{
m_lpProcessBar->SetPos(m_lpProcessBar->GetPos()+datasize);
}
}

bool CHttpClientProcess::Download(char *url, char *fname, void *p)
{
m_lpProcessBar=(CProgressCtrl*)p;
return CHttpClient::Download(url,fname);
}


佛曰:\"前世的500次回眸才换来今生的一次擦肩而过\".我宁愿用来世的一次擦肩而过来换得今生的500次回眸.
2006-12-22 16:26
停止流浪
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2006-12-16
收藏
得分:0 
清澂居士,谢谢您了。我试一下
2006-12-26 09:10
快速回复:[原创][求助]动态显示下载过程的方法?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.038683 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved