一个基于WinInet API的FTP下载器的实现
2008年11月4日星期二
今天看了一下关于WinInet编程,编写了一个小的FTP下载器,运行图如下:
详细实现代码如下:
包含头文件:
// included for WinInet programming
#include <wininet.h>
#include <afxmt.h>
部分实现代码:
// Impletement of WinInet programming
void CFileDownloadDlg::OnBnClickedButdownload()
{
// 下载按钮事件
CString rightstrtmp,midstrtmp;
int index = m_List.GetItemCount();
GetDlgItem(IDC_EDTURL)->GetWindowText(strurl);
if (strurl.IsEmpty()) return;
strurl.TrimLeft(); // 清除字符串左边的空格
strurl.TrimRight(); // 清除字符串右边的空格
CString strprotocol(_T("")); // 设置协议字符串
CString strleft; // 提取的协议字符串
strleft = strurl.Left(7);
if (strleft.Compare(_T("http://")) == 0)
{
strprotocol = _T("http");
}
else
{
strleft = strurl.Left(6);
if (strleft.Compare(_T("ftp://")) == 0)
{
strprotocol = _T("ftp");
}
else
{
AfxMessageBox(_T("不能识别的URL!"));
return;
}
}
if (strprotocol.Compare(_T("http")) == 0)
{
rightstrtmp = strurl.Right(strurl.GetLength() - 7);
int pos = rightstrtmp.Find(_T("/"));
midstrtmp = rightstrtmp.Right(rightstrtmp.GetLength() - pos - 1);
if (midstrtmp.IsEmpty())
{
AfxMessageBox(_T("没有找到指定文件"));
return;
}
pos = rightstrtmp.Find(_T("/"));
while (pos > 0)
{
midstrtmp = midstrtmp.Right(midstrtmp.GetLength() - pos - 1);
pos = midstrtmp.Find(_T("/"));
}
strresult = midstrtmp;
}
if (strprotocol.Compare(_T("ftp")) == 0)
{
rightstrtmp = strurl.Right(strurl.GetLength() - 6);
int pos = rightstrtmp.Find(_T("/"));
strftpserver = rightstrtmp.Left(pos);
int nTmp;
if ((nTmp = rightstrtmp.Find(_T(":"))) != -1)
{
strftpserver = rightstrtmp.Left(nTmp);
}
midstrtmp = rightstrtmp.Right(rightstrtmp.GetLength() - pos - 1);
strftpfile = midstrtmp;
if (midstrtmp.IsEmpty())
{
AfxMessageBox(_T("没有指定文件"));
return;
}
pos = midstrtmp.Find(_T("/"));
while (pos > 0)
{
midstrtmp = midstrtmp.Right(midstrtmp.GetLength() - pos - 1);
pos = midstrtmp.Find(_T("/"));
}
strresult = midstrtmp;
}
// 通过浏览对话框选择下载文件保存路径
BROWSEINFO bi;
TCHAR buffer[MAX_PATH];
::ZeroMemory(buffer,MAX_PATH);
::memset(&bi,0,sizeof(bi));
bi.hwndOwner = this->m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = NULL;
bi.lpszTitle = _T("选择一个文件夹");
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
LPITEMIDLIST pList = NULL;
if ((pList = SHBrowseForFolder(&bi)) != NULL)
{
TCHAR path[MAX_PATH];
::ZeroMemory(path,MAX_PATH);
SHGetPathFromIDList(pList,path);
m_List.InsertItem(index,_T(""));
CString strindex;
strindex.Format(_T("%d"),index + 1);
m_List.SetItemText(index,0,strindex);
m_List.SetItemText(index,1,strurl);
CString str;
path[_tcslen(path)] = 0;
str.Format(_T("%s"),path);
if (str.Right(1) != _T("//"))
{
str += _T("//");
str += strresult;
}
else
{
str += strresult;
}
strlocalname = str;
m_List.SetItemText(index,2,strlocalname);
if (strprotocol.Compare(_T("http")) == 0)
::CreateThread(NULL,0,ThreadProc1,this,0,NULL); // 启动处理“http”的线程
if (strprotocol.Compare(_T("ftp")) == 0)
::CreateThread(NULL,0,ThreadProc2,this,0,NULL); // 启动处理“ftp”的线程
strprotocol = _T(""); // 置为空,以防影响下次操作
}
}
// Http download threadProc
//
DWORD WINAPI ThreadProc1(LPVOID lParam)
{
CFileDownloadDlg *pDlg = (CFileDownloadDlg *)lParam;
TCHAR szHead[] = _T("Accept:*/*/r/n/r/n");
if (pDlg->strurl == _T("")) return 0;
VOID *szTemp[25];
DWORD dwSize;
HINTERNET hConnect;
HINTERNET hOpen;
FILE *pFile;
cMutex.Lock();
hOpen = ::InternetOpen(NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
hConnect = ::InternetOpenUrl(hOpen,pDlg->strurl,szHead,_tcslen(szHead),INTERNET_FLAG_DONT_CACHE,0);
cMutex.Unlock();
if (!hConnect) return 0;
//pFile = _wfopen(pDlg->strlocalname,_T("wb"));
while (1)
{
::InternetReadFile(hConnect,szTemp,50,&dwSize);
if (!dwSize)
goto end;
else
fwrite(szTemp,sizeof(TCHAR),dwSize,pFile);
}
end:
::MessageBox(NULL,_T("下载完成!"),_T("提示"),MB_OK);
fflush(pFile); // 清空输入缓冲区中的内容,避免残存读取函数无法读取的内容
fclose(pFile);
::InternetCloseHandle(hConnect);
::InternetCloseHandle(hOpen);
return 0;
}
// FTP download threadProc
//
DWORD WINAPI ThreadProc2(LPVOID lParam)
{
CFileDownloadDlg *pDlg = (CFileDownloadDlg *)lParam;
if (pDlg->strurl == _T("")) return 0;
HINTERNET hInternetSession;
HINTERNET hFTPSession;
hInternetSession = ::InternetOpen(_T("Microsoft Internet Explorer"),
INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
hFTPSession = ::InternetConnect(hInternetSession,pDlg->strftpserver,
22,_T("test"),_T("test"),INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE,(DWORD)0);
if (!hFTPSession) return 0;
DWORD dwt = FtpGetFile(hFTPSession, pDlg->strftpfile,pDlg->strlocalname,
FALSE,FILE_ATTRIBUTE_NORMAL,FTP_TRANSFER_TYPE_ASCII | INTERNET_FLAG_PASSIVE,0);
if (dwt)
::MessageBox(NULL,_T("下载完成!"),_T("提示"),MB_OK);
::InternetCloseHandle(hFTPSession);
::InternetCloseHandle(hInternetSession);
return 0;
}