ftp文件上传下载模块概述
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ftp文件上传下载模块概述
1.1 开发背景
如果用户不使用FTP客户端软件,而是直接登录到FTP服务器来上传或下载FTP文件,会存在许多不足。例如,在同时下载多个文件时,如何暂停或继续某个文件的下载,如果下载大量文件,如何在任务下载完成后关闭计算机。这就是FTP客户端软件的作用,也是笔者设计本章程序的主要原因。
1.2 需求分析
FTP文件上传下载模块的主要功能是实现FTP文件的多任务上传、下载,对于实现FTP 文件的上传和下载,可以使用MFC提供的WinInet相关类非常方便地实现,模块的难点在于多任务,需要为每个上传或下载的任务维护一个单独的线程,用户可以暂停和取消任务。在关键技术部分笔者将介绍如何实现FTP文件多任务下载。
1.3 模块预览
FTP文件上传下载模块只包含一个主对话框,但是主对话框却由登录信息栏、工具栏、本地信息窗口、远程FTP服务器信息窗口和任务列表共5个子窗口构成。下面分别给出各个窗口的效果图。
FTP文件上传下载模块主窗口效果图如图1所示。
图1 FTP文件上传下载模块主窗口
登录信息栏效果如图2所示工具栏窗口效果如图3所示。
图3 工具栏窗口
本地信息窗口效果图如图4所示。
图4 本地信息窗口
远程FTP服务器信息窗口效果如图5所示。
任务列表窗口运行效果如图6所示。
图6 任务列表窗口
关键技术
1.1 设计类似于资源管理器的列表视图控件
在设计FTP文件上传下载模块时,首先需要确定采用何种方式显示本地和FTP服务器上的目录和文件。为了模仿Windows资源管理器的效果,笔者采用了列表视图控件——CListCtrl来实现目录和文件的显示。但是,MFC提供的默认的CListCtrl无法实现Windows 资源管理器的效果,我们必须重新设计一个列表视图控件。该控件需要具备的功能有以本地系统默认的图标显示目录和文件的图标,在控件中双击某一个目录将进入子目录,按“Back Space”键将返回上一级目录,实现对某一列的升序、降序排列,并以箭头标识。控件的设计效果如图13.4所示。在设计控件之前,读者需要对CListCtrl控件有所了解。CListCtrl 控件主要有两部分构成,第一部分是列头部分,由CHeaderCtrl控件构成,第二部分是表格部分。当在列头部分绘制排序箭头时,实际上是在CHeaderCtrl控件上进行的。
下面介绍控件的详细设计过程。首先设计列头控件,因为需要绘制排序列的标记。
(1)从CHeaderCtrl类派生一个子类——CSortHeaderCtrl,向该类中添加成员变量。
(1)从CHeaderCtrl类派生一个子类——CSortHeaderCtrl,向该类中添加成员变量。
int m_nSortColumn; //排序列
BOOL m_bAscend; //是否为升序
(2)在构造函数中初始化成员变量。
CSortHeaderCtrl::CSortHeaderCtrl()
{
m_nSortColumn = -1;
m_bAscend = TRUE;
}
(3)向CSortHeaderCtrl类中添加SetSortColomn方法,用于设置排序列和排序列的自绘风格。
void CSortHeaderCtrl::SetSortColomn(int nColumn, BOOL bAscend)
{
m_nSortColumn = nColumn; //设置排序列
m_bAscend = bAscend; //设置排序方式
HD_ITEM hItem;
hItem.mask = HDI_FORMAT;
GetItem( nColumn, &hItem ) ; //获取列信息
hItem.fmt |= HDF_OWNERDRAW; //设置列自绘风格
SetItem( nColumn, &hItem ); //设置列信息
Invalidate(); //更新控件
}
(4)改写CSortHeaderCtrl类的DrawItem方法,根据排序方式绘制排序列的箭头符号。
void CSortHeaderCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
CDC dc; //定义设备上下文
dc.Attach( lpDrawItemStruct->hDC ); //附加设备上下文句柄
const int nSavedIndex = dc.SaveDC(); //保存设备上下文
CRect rc( lpDrawItemStruct->rcItem ); //获取当前列区域
CBrush brush( GetSysColor( COLOR_3DFACE ) ); //定义背景画刷dc.FillRect( rc, &brush ); //填充画刷
TCHAR szText[ 256 ]; //定义字符数组,存储列文本
HD_ITEM hditem;
hditem.mask = HDI_TEXT | HDI_FORMAT;
hditem.pszText = szText;
hTextMax = 255;
GetItem( lpDrawItemStruct->itemID, &hditem ); //获取当前的项目信息
UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP |
DT_VCENTER | DT_END_ELLIPSIS ; //设置绘制的文本格式if( hditem.fmt & HDF_CENTER)
uFormat |= DT_CENTER;
else if( hditem.fmt & HDF_RIGHT)
uFormat |= DT_RIGHT;
else
uFormat |= DT_LEFT;
if( lpDrawItemStruct->itemState == ODS_SELECTED )//列是否被选中{
rc.left++; //调整列的区域
rc.top += 2;
rc.right++;
}
CRect rcIcon( lpDrawItemStruct->rcItem ); //定义箭头显示区域
const int iOffset = ( rcIcon.bottom - rcIcon.top ) / 4;
if( lpDrawItemStruct->itemID == (UINT) m_nSortColumn )
rc.right -= 3 * iOffset;
rc.left += iOffset;
rc.right -= iOffset;
if( rc.left < rc.right )
dc.DrawText( szText, -1, rc, uFormat ); //绘制列文本
//绘制箭头
if( lpDrawItemStruct->itemID == (UINT) m_nSortColumn )
{
CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) ); //定义
浅颜色画笔