PostHeaderIcon A Simple Downloader With MFC

I have write something about software updater in my website.

Now this article is same with that, but with something difference.

This new added thread,you should know it and use it in your application~

Yeah, first let us see a picture:

simple downloader

The follow is the exe and the source code, you can download them:

exe:       Simple Downloader Executable File

code:    Simple Downloader Source Code

One thing note is the project is developed with Visual C++ 2010, So if you want to compile it, you should have the tool at least the Visual C++ 2008.

In my opinion, the newer IDE is better for you,but do not to do it with .NET framework, it is large for you and your application.

The key of this project is Thread, Now I will show you the critical section about it:

UINT DownloadFile(LPVOID pParam)
{
	// get the pointer of Dlg
	CSimpleDownDlg* pDlg=(CSimpleDownDlg*)pParam;
	// use two variables to save the edit's value of the Dlg
	CString str_url,str_filepath;
	// get the two value of each other
	pDlg->m_FileUrl.GetWindowTextW(str_url);
	pDlg->m_FileSavePath.GetWindowTextW(str_filepath);

	// a state
	DWORD dwFlags;

	// get the internet sate
	InternetGetConnectedState(&dwFlags,0);
	CHAR strAgent[64];
	sprintf(strAgent,"Agent%ld",timeGetTime());
	HINTERNET hOpen;

	// open the internet connection
	if(!(dwFlags&INTERNET_CONNECTION_PROXY))
		hOpen=InternetOpenA(strAgent,INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
		NULL,NULL,0);
	else
		hOpen=InternetOpenA(strAgent,INTERNET_OPEN_TYPE_PRECONFIG,
		NULL,NULL,0);

	if(!hOpen)
	{
		AfxMessageBox(_T("Internet connected error!"));
		return -1;
	}

	DWORD dwSize;

	VOID* szTemp[16384];
	HINTERNET hConnect;
	CFile file;

	CStringA url(str_url);
	DWORD options = INTERNET_FLAG_NEED_FILE|INTERNET_FLAG_HYPERLINK|
        INTERNET_FLAG_RESYNCHRONIZE|INTERNET_FLAG_RELOAD;

	CButton* btn_download=&pDlg->m_btnDownload;

	// request the internet file with the url
	if(!(hConnect=InternetOpenUrlA(hOpen,
		url,
		NULL,
		NULL,
		options,
		0)
		))
	{
		AfxMessageBox(_T("Invalid URL address, access to the file fail!"));
		if(!btn_download->IsWindowEnabled())
			btn_download->EnableWindow(TRUE);
		return -1;
	}

	// create local file
	if (file.Open(str_filepath,CFile::modeWrite|CFile::modeCreate)==FALSE)
	{
		AfxMessageBox(_T("Create local file fail!"));
		if(!btn_download->IsWindowEnabled())
			btn_download->EnableWindow(TRUE);
		return -1;
	}

	DWORD dwByteToRead=0;
	DWORD dwSizeOfQequest=4;
	DWORD dwBytes=0;

	// get the length of the file
	if(!HttpQueryInfo(hConnect,
		HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER,
		(LPVOID)&dwByteToRead,
		&dwSizeOfQequest,NULL))
	{
		dwByteToRead=0;
	}

	DWORD start;
	DWORD end;
	DWORD time;
	CString tempStr;
	time=0;
	start=timeGetTime();
	do {
		// read and accept the internet file
		if (!InternetReadFile(hConnect,szTemp,16484,&dwSize))
		{
			AfxMessageBox(_T("Error reading files!"));
			file.Close();
			if(!btn_download->IsWindowEnabled())
				btn_download->EnableWindow(TRUE);
			return -1;
		}
		if(dwSize==0)
		{
			break;
		}
		else
		{
			file.Write(szTemp,dwSize);
		}
		dwBytes+=dwSize;

		// download progress
		if(dwByteToRead)
		{
			tempStr.Format(_T("%d%%"),(dwBytes*100)/dwByteToRead);
			pDlg->m_ProgressCtrl.SetPos((dwBytes*100)/dwByteToRead);
			pDlg->m_ProgressText.SetWindowTextW(tempStr);
			Sleep(100);
		}

		// download speed
		FLOAT fSpeed=0;
		fSpeed=(float)dwBytes;
		end=timeGetTime();
		time=end-start;
		if (time==0)
		{
			time=10;
		}
		fSpeed/=((float)time)/1000.0f;
		fSpeed/=1024.0f;
		tempStr.Format(_T("%lfKB/s"),fSpeed);
		pDlg->m_DownSpeed.SetWindowTextW(tempStr);
		Sleep(100);

	}while(TRUE);

	// close resources
	file.Close();
	InternetCloseHandle(hOpen);
	if(!btn_download->IsWindowEnabled())
		btn_download->EnableWindow(TRUE);
	AfxMessageBox(_T("File Download Success!"));

	return 0;
}

You can understand the code yourself, and it is easy for you.
You can also use it in your project, I feel like about it.
but before you use it, maybe you can update any with the following points:

  • Add the brower button and dialog with file save path edit and keep the original name of the file(easy);
  • Multithreading download if the file is large(medium);
  • Resume from break point.(medium)

Lastly, remeber software development is not hard, but reconfiguration is hard, try your best to do it well~

115,318 views

Leave a Reply

Your email address will not be published. Required fields are marked *

*


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


Copyright © 2010 - C++ Technology. All Rights Reserved.

Powered by Jerry | Free Space Provided by connove.com