(2)为各控件添加变量
为“FTP 服务器地址”文本框添加CString类型的变量m_strFTPServer;为“端口”文本框添加UINT类型的变量m_nFTPPort ;为“用户名”文本框添加CString 类型的变量m_strUserName ;为“密码”文本框添加CString 类型的变量m_strPassword,其Password 属性为TRUE;为“ 下载目录”文本框添加CString 类型的变量m_strFTPDirectory;为“下载目录文件列表”列表框控件添加CListBox 类型的变量m_listFiles;为“连接”按钮添加CButton类型的变量m_bnConnect;为“下载文件”按钮添加CButton类型的变量m_bnDownloadFile。
3. 实现
(1)建立与FTP服务器的连接
为此需要在对话框类(FTPClientDlg.h)中添加CInternetSession 类的对象m_Session和CFtpConnection 对象指针m_pConnection 两个变量。为使程序可使用WinInet 类,需要在stdafx.h 中加入一个对afxinet.h 和afx.h 的包含。建立连接主要是通过单击对话框中的“连接”按钮来实现的(调用FTPClientDlg.cpp中的CFTPClientDlg::OnBnClickedButtonconnect()),其代码如下。
void CFTPClientDlg::OnBnClickedButtonconnect()
{
UpdateData(TRUE);//从对话框中获取数据
if(!m_pConnection)//进行连接
{
if(m_strFTPServer!="")
{
//利用Internet 对话对象m_Session 打开一个FTP 连接
m_pConnection=m_Session.GetFtpConnection(m_strFTPServer,m_strUserName,m_strPassword,m_nFTPPort);
if(m_pConnection)
{
//如果连接成功,则获取当前目录
m_pConnection->GetCurrentDirectory(m_strFTPDirectory);
//将“连接”按钮改为“断开连接”按钮
m_bnConnect.SetWindowText(_T("断开连接"));
LoadListofFtpFiles();//获取文件列表
//FTP已连接,“下载文件”按钮使能
m_bnDownloadFile.EnableWindow(TRUE);
UpdateData(FALSE);//更新对话框数据
}
}
}
else //断开连接
{
m_pConnection->Close();//断开连接并删除连接对象
delete m_pConnection;
m_pConnection=NULL;//重置连接对象指针为NULL
//将“断开连接”按钮改为“连接”按钮
m_bnConnect.SetWindowText(_T("连接"));
m_strFTPDirectory="";//重置目录
m_listFiles.ResetContent();//清空列表框
//FTP 断开连接,“下载文件”按钮Disable
m_bnDownloadFile.EnableWindow(FALSE);
UpdateData(FALSE);//更新对话框数据
}
}
另外,为了建立一个默认的连接,需要在对话框(FTPClientDlg.cpp)的初始化函数(CFTPClientDlg::OnInitDialog())中添加设置变量的默认值,其代码如下。
BOOL CFTPClientDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...//省略原有代码
// TODO: 在此添加额外的初始化代码
//设置默认的FTP 服务器名(IP)、端口、用户名(匿名)和登录密码,目录
m_strFTPServer = _T("192.168.0.1");//设置FTP 的IP
m_nFTPPort = 21;//设置FTP 端口:默认的端口是21
m_strUserName = _T("user1");//设置登录用户名,默认的是匿名:user1
m_strPassword = _T("user1");//设置登录密码:user1
m_listFiles.ResetContent();//清空文件目录列表
m_pConnection = NULL;//初始状态FTP 未连接,FTP 连接类的指针变量初始化为空
//FTP 未连接,“下载文件”按钮Disable
m_bnDownloadFile.EnableWindow(FALSE);
UpdateData(FALSE);//交换数据,对话框显示初始化内容
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
此外,为了关闭Internet会话(InternetSession),需要为对话框的头文件(FTPClientDlg.h)添加一个WM_CLOSE的消息响应函数(即public: afx_msg void OnClose();)。OnClose()的实现代码在FTPClientDlg.cpp中添加,其代码如下。
void CFTPClientDlg::OnClose()
{
m_Session.Close();//在对话框关闭时关闭Internet 连接
CDialog::OnClose();
}
(2)读FTP服务器中的文件和目录到列表框中
该功能是通过FTPClientDlg.cpp中的CFTPClientDlg::LoadListofFtpFiles(void)来实现的,其代码如下。
void CFTPClientDlg::LoadListofFtpFiles(void)
{
m_listFiles.ResetContent();//清空列表框
//构建一个FTP 文件操作类对象,同时把FTP 连接指针传递给该对象,
//打开一个文件查找对话
CFtpFileFind fFiles(m_pConnection);
CString strFileName; //用来保存文件名
BOOL bMoreFiles; //用来设置文件搜索状态
//利用默认的方法找到第一个文件,同时找到文件列表
bMoreFiles=fFiles.FindFile(NULL);
while(bMoreFiles)//文件搜索,直到最后一个文件
{
bMoreFiles=fFiles.FindNextFile();//查找下一个文件
strFileName=fFiles.GetFileName();//获取该文件名
if(fFiles.IsDirectory())//若为目录,则在名后加一个标志
strFileName+=" <DIR>";
m_listFiles.AddString(strFileName);//将文件名添加到列表框中
}
fFiles.Close();//关闭文件查找对话框
}
(3)下载FTP服务器中的文件
下载文件是通过单击对话框中的“下载文件”按钮来实现的(调用FTPClientDlg.cpp中的CFTPClientDlg::OnBnClickedButtondownloadfile()),其具体实现是利用CFileDialog的保存功能来完成文件下载的,其主要代码如下。
void CFTPClientDlg::OnBnClickedButtondownloadfile()
{
UpdateData(TRUE);//从对话框中获取数据
m_listFiles.GetText(m_listFiles.GetCurSel(),m_strFile);
//将列表框选中的项的值赋给m_strFile(选中的文件或目录)
if(m_strFile!="")
{
if(m_strFile.Right(5)=="<DIR>")//判断用户选择的是否目录
MessageBox(_T("无法下载目录!"));//如果是目录,报错
else
{
//打开文件对话框,询问下载位置
CFileDialog filedlg(FALSE,NULL,m_strFile);
if(filedlg.DoModal()==IDOK)
{
//确定地址后开始下载文件
if(!m_pConnection->GetFile(m_strFile,filedlg.GetFileName()))
MessageBox(_T("无法下载文件!"));//下载出错
else
MessageBox(_T("文件下载完毕!"));//下载成功
}
}
}
}
4. 最终实现界面,如图2所示。