MyWindow.h
#ifndef MYWINDOW_HEAD
#define MYWINDOW_HEAD
#pragma once
#include
#include
#include
#include
#include
#pragma comment(lib ,"Wininet.lib")
class CMyApp:public CWinApp
{
public:
//构造函数
CMyApp();
//析构函数
virtual ~CMyApp();
//重载函数
public:
//初始函数
virtual BOOL InitInstance();
};
class CMyWindow : public CFrameWndEx
{
public:
CButton m_btStart; //开始按钮
CButton m_btStop; //停止按钮
CStatic m_stProcess; //百分进度
CEdit m_editUrl; //下载地址
CProgressCtrl m_ProcessPb; //下载进度条
HANDLE m_Thread; //线程句柄
BOOL m_IsStop; //是否停止
public:
//构造函数
CMyWindow();
//析构函数
virtual ~CMyWindow();
//线程函数
protected:
static DWORD WINAPI PBThreadProc( LPVOID lpParameter );
//虚函数
public:
//命令响应消息
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//消息映射
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
#endif
#include "MyWindow.h"
CMyApp myapp;
#define IDC_START 1001 //开始按钮
#define IDC_STOP 1002 //暂停按钮
#define IDC_PROCESS 1003 //进度状态
//构造函数
CMyApp::CMyApp()
{
}
//析构函数
CMyApp::~CMyApp()
{
}
//初始函数
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMyWindow();
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMyWindow, CFrameWndEx)
ON_WM_CREATE()
END_MESSAGE_MAP()
//构造函数
CMyWindow::CMyWindow()
{
Create(NULL, TEXT("My Window"));
}
//析构函数
CMyWindow::~CMyWindow()
{
}
//命令响应消息
BOOL CMyWindow::OnCommand( WPARAM wParam, LPARAM lParam )
{
int wmId=LOWORD(wParam);
switch (wmId)
{
case IDC_START:
{
//创建线程
m_IsStop=FALSE;
m_Thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PBThreadProc,this,0,0);
CloseHandle(m_Thread);
return true;
}
break;
case IDC_STOP:
{
m_IsStop=TRUE;
return true;
}
break;
default:
return true;
}
return __super::OnCommand(wParam,lParam);
}
//创建事件
int CMyWindow::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
__super::OnCreate(lpCreateStruct);
//居中窗口
SetWindowPos(NULL,0,0,600,400,SWP_SHOWWINDOW);
SetActiveWindow();
SetForegroundWindow();
CenterWindow(GetParent());
//创建按钮
RECT rect={0,0,0,0};
m_btStart.Create(TEXT("开始"),WS_CHILD|WS_VISIBLE,rect,this,IDC_START);
m_btStop.Create(TEXT("停止"),WS_CHILD|WS_VISIBLE,rect,this,IDC_STOP);
m_stProcess.Create(TEXT("0 %"),WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,rect,this,IDC_PROCESS);
m_editUrl.Create(WS_CHILD|WS_VISIBLE|WS_BORDER,rect,this,NULL);
m_ProcessPb.Create(WS_CHILD | WS_VISIBLE,rect,this,NULL);
m_btStart.SetWindowPos(NULL,0,0,60,30,SWP_SHOWWINDOW);
m_btStop.SetWindowPos(NULL,100,0,60,30,SWP_SHOWWINDOW);
m_stProcess.SetWindowPos(NULL,0,100,100,30,SWP_SHOWWINDOW);
m_editUrl.SetWindowPos(NULL,0,50,450,30,SWP_SHOWWINDOW);
m_ProcessPb.SetWindowPos(NULL,0,150,450,30,SWP_SHOWWINDOW);
m_editUrl.SetWindowText(_T("http://dldir1.qq.com/music/clntupate/QQMusicForYQQ.exe") );
m_IsStop=FALSE;
m_Thread=NULL;
return true;
}
DWORD WINAPI CMyWindow::PBThreadProc( LPVOID lpParameter )
{
//定义变量
CMyWindow* pMyWindow = (CMyWindow *)lpParameter;
assert(pMyWindow);if (pMyWindow==NULL)return FALSE;
LONGLONG dwByteToRead=0;
DWORD dwSizeOfRq=4;
DWORD dwBytes=0;
LONGLONG sum=0;
DWORD dwSize=0;
PBRANGE range={0}; //进度条的范围
void * szTemp[16384]={0}; //接收数据
HINTERNET hConnect=NULL;
FILE *pfDownLoad=NULL; //下载文件
TCHAR szUrlAdd[MAX_PATH]={0};
TCHAR szHead[128]= _T("Accept: */*\r\n\r\n");
TCHAR pBuf[MAX_PATH]={0}; //存放路径的变量
//本地系统的连接状态
DWORD dwFlags;
if(InternetGetConnectedState(&dwFlags,0)==FALSE)
{
::MessageBox(NULL,_T("没有网络连接!"),_T("提示"),MB_OK);
return 0;
}
//初始化应用程序使用的WinInet函数
TCHAR strAgent[64];
swprintf(strAgent,_T("Agent%ld"),timeGetTime());
HINTERNET hopen;
if(!(dwFlags&INTERNET_CONNECTION_PROXY))
hopen=InternetOpen(strAgent,INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,NULL,NULL,0);
else
hopen=InternetOpen(strAgent,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if(!hopen)
{
::MessageBox(NULL,_T("打不开网络连接!"),_T("提示"),MB_OK);
return 0;
}
pMyWindow->m_editUrl.GetWindowText( szUrlAdd , ARRAYSIZE(szUrlAdd) );
GetCurrentDirectory(MAX_PATH,pBuf);
wcscat(pBuf, wcsrchr( szUrlAdd ,'/') );
long fileSize=0;
pfDownLoad=_wfopen( pBuf ,_T("r"));
if (pfDownLoad)
{
fseek(pfDownLoad, 0, SEEK_END);
fileSize = ftell(pfDownLoad);
_stprintf(szHead, _T("Range: bytes=%d-\r\nAccept: */*\r\n\r\n"), fileSize);
fclose(pfDownLoad);
pfDownLoad=_wfopen( pBuf ,_T("rb+ "));
if(pfDownLoad==NULL)
{
::MessageBox(NULL,_T("打开本地文件失败!"),_T("提示"),MB_OK);
return 0;
}
fseek(pfDownLoad, 0, SEEK_END);
}
else
{
pfDownLoad=_wfopen( pBuf ,_T("wb+"));
_stprintf(szHead, _T("Accept: */*\r\n\r\n"));
if(pfDownLoad==NULL)
{
::MessageBox(NULL,_T("打开本地文件失败!"),_T("提示"),MB_OK);
return 0;
}
}
//查询有关HTTP请求的信息
if(!(hConnect=InternetOpenUrl(hopen,szUrlAdd,szHead,wcslen(szHead),INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_PRAGMA_NOCACHE,0)))
{
::MessageBox(NULL,_T("打开网络地址失败!"),_T("提示"),MB_OK);
return 0;
}
//查询是否支持断点续传
//Accept-Ranges: bytes
if(HttpQueryInfo(hConnect,HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER ,(LPVOID)&dwByteToRead,&dwSizeOfRq,NULL)==FALSE)
{
return false;
}
if (dwByteToRead==206)
{
OutputDebugString(TEXT("支持断点续传"));
}
//获取文件大小
if(HttpQueryInfo(hConnect,HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER,(LPVOID)&dwByteToRead,&dwSizeOfRq,NULL)==FALSE)
{
dwByteToRead=0;
}
//设置进度条的范围
pMyWindow->m_ProcessPb.SendMessage(PBM_SETRANGE, (WPARAM)0, (LPARAM)(MAKELPARAM(0,100)) );
//获取进度条的范围 //TRUE 表示返回值为范围的最小值,FALSE表示返回最大值
pMyWindow->m_ProcessPb.SendMessage( PBM_GETRANGE, (WPARAM)TRUE,(LPARAM)&range );
//
TCHAR sumdata[64]={0};
while(TRUE)
{
//2016年5月16日14:42:07
//下载超过255MB大的文件下载就停止了。不知道什么原因
//读取数据
if(InternetReadFile(hConnect,szTemp,16384,&dwSize)==FALSE) //16384
{
InternetCloseHandle(hopen);
fclose(pfDownLoad);
::MessageBox(NULL,_T("网络中断!"),_T("提示"),MB_OK);
return 0;
}
if(dwSize==0)break;
sum+=dwSize;
fwrite(szTemp,dwSize,1,pfDownLoad);
swprintf(sumdata,_T("%d %%"),(sum*100)/dwByteToRead);
//设置进度条当前值
pMyWindow->m_ProcessPb.SendMessage(PBM_SETPOS, (WPARAM)(sum*100)/dwByteToRead, (LPARAM)0 );
pMyWindow->m_stProcess.SetWindowText(sumdata);
//停止判断
if (pMyWindow->m_IsStop==TRUE)break;
}
//关闭一个Internet手柄
InternetCloseHandle(hopen);
fclose(pfDownLoad);
//pthis->m_ProcessPb.SendMessage(PBM_SETPOS, (WPARAM)range.iLow, (LPARAM)0 ); //将进度条复位
//pthis->m_ProcessPb.ShowWindow(SW_HIDE ); //隐藏进度条
//pthis->m_stProcess.ShowWindow(SW_HIDE ); //隐藏 百分比控件
//::MessageBox(NULL,TEXT("文件下载完毕"),NULL,MB_OK);
return 0;
}