使用MFC对FTP文件或者文件夹进行下载、断点续传等功能的个人理解

    xiaoxiao2021-04-18  91

    函数功能:VS2010 —— MFC —— 基于对话框 —— 输入ftp服务器数据、本地下载路径 —— 连接后显示ftp服务器文件情况在列表控件上,有操作功能

    从ftp服务器下载指定文件或文件夹到指定的本地路径,保存需要下载的文件大小 ,然后计算本地下载文件大小,比对下载完成度 ,有错误提示。  

        断点续传功能在第二种方法才有。

    使用到的头文件:

    #include "stdafx.h" #include "ftpDL.h" #include "ftpDLDlg.h" #include "afxdialogex.h" #include "afxinet.h" #include "afxwin.h" #include  <vector> #include "TipDlg.h"  //这个是建立的一个新的对话框,主要在双击的时候弹出选择

    教程在此:http://www.jizhuomi.com/software/160.html

    全局变量定义:

        vector <CString> m_string;       //创建Vector保存目录     vector <CString> m_dotstring;    //保存文件     vector <CString> V_counterpart;  //进入下一层按钮时创建当前层副本,记录列表项的数据     CString m_ftppath;                       //函数需要的输入路径,及搜索当前路径的文件以及目录     vector <CString> V_ftppath;              //副本保存路径,显示下一层时用m_ftppath加上**,返回上层时减去**     int n;                           //记录当前显示的层数,根目录为0层,     int  ig = 0 ;                    //控制一下创建目录选择哪个     int dir[20];                     //创建一个可以保存20个数的数组来保存目录存储时每一层有多少个文件和目录,现在可以存储10层目录,控制这个数组大小可以控制目录的层数     int size[20];                    //存储每层多少目录,20表示可以存储20层目录的数据,即每层目录内的文件数量保存在一个数组元素中     LONGLONG m_dirsize = 0;          //保存文件的大小     LONGLONG m_fdirsize = 0;         //保存ftp要下载的文件或文件夹大小

        int nDownloaded; //断点续传的控制

    对话框部分的变量输入:(有一项控件是作为重新绘制使用的,如果不需要只需要弄好输入变量的)

            DDX_Control(pDX, IDC_localpt_STATIC, m_localpathpos); DDX_Text(pDX, IDC_localpath_EDIT1, m_localpath); DDX_Control(pDX, IDC_localpath_EDIT1, m_editlocalpath); DDX_Control(pDX, IDC_ftppt_STATIC, m_ftppt); DDX_Text(pDX, IDC_ftpadress_EDIT1, m_ftpadress); DDX_Control(pDX,IDC_ftpadress_EDIT1, m_editftpadress); DDX_Control(pDX, IDC_usernm_STATIC, m_usernm); DDX_Text(pDX, IDC_username_EDIT2, m_username); DDX_Control(pDX,IDC_username_EDIT2,m_editusername); DDX_Control(pDX,IDC_passwd_STATIC, m_passwd); DDX_Text(pDX, IDC_password_EDIT3, m_password); DDX_Control(pDX,IDC_password_EDIT3,m_editpassword); DDX_Control(pDX,IDC_pt_STATIC,m_pt); DDX_Text(pDX, IDC_port_EDIT4, m_port); DDX_Control(pDX, IDC_port_EDIT4,m_editport); DDX_Control(pDX,IDC_Fareason_STATIC,m_Fareason); DDX_Text(pDX, IDC_Freason_EDIT5, m_Freason); DDX_Control(pDX,IDC_Freason_EDIT5,m_editFreason); DDX_Control(pDX, IDC_dirshow_LIST1, m_listBox); DDX_Control(pDX, IDC_RIGHTWND,m_rightwnd); DDX_Control(pDX, IDC_connect_BUTTON,m_btconnect); DDX_Control(pDX, IDC_shownextdir_BUTTON,m_btshownextdir); DDX_Control(pDX, IDC_Return_BUTTON,m_btreturn); DDX_Control(pDX, IDC_download_BUTTON,m_btdownload); DDX_Control(pDX, IDCANCEL, m_btcancel);

    连接ftp服务器,显示目录在list控件中:

    BOOL FtpList(CString &ftppath,CString ftpaddress,CString username,CString &Freason,CString password,int port)   //定义ftp目录遍历函数 { CInternetSession sess(_T("List Files Session"));   //创建CInternetSession类对象 sess     CFtpConnection *pFtpCon=NULL;                      //创建cftpconnection类对象指针* pFtpCon 为默认值 try { pFtpCon=sess.GetFtpConnection(ftpaddress,username,password,port);  //调用GetFtpConnection连接FTP服务器 if(pFtpCon==NULL)    {     Freason = "connection is false"; return FALSE; }    CFtpFileFind ftpDirFinder (pFtpCon);  //创建CFtpFileFind类对象ftpDirFinder,"()"内为格式中要求填写的cftpconnection类对象指针 CStringArray  m_dir1;          //定义一个数组保存目录,一个保存文件 CStringArray  m_dir2;   BOOL bWorking = ftpDirFinder.FindFile(ftppath);     while (bWorking) //循环进行目录调用,保存FTP第一层文件或者文件夹在数组中  { bWorking=ftpDirFinder.FindNextFile(); //循环条件:如果bWork为找不到下一个文件了,循环跳出  if(ftpDirFinder.IsDots())   //这一段为跳过"."和"..“文件,不跳过会无线重复。  {      continue;   }  if(ftpDirFinder.IsDirectory())  {        m_dir1.Add( ftpDirFinder.GetFileName());  //如果是目录的话,就保存在数组1 //只需要一层,不用递归,如果用递归,则遍历多层。  }     else  //找到的不是目录(即文件),保存在数组2  {        m_dir2.Add( ftpDirFinder.GetFileName()); //文件保存在数组2中  } } ftpDirFinder.Close(); //关闭ftp连接,开始显示数组中每一项目录 for (int i=0;i<m_dir1.GetSize();i++)    //通过循环保存每一项目录或者文件 { m_string.push_back(m_dir1.GetAt(i));   //目录保存在m_string中 }    for (int j=0;j<m_dir2.GetSize();j++)   { m_dotstring.push_back(m_dir2.GetAt(j));   //文件保存在m_dotstring中 } } catch(CInternetException* pEx) {    TCHAR sz[1024];           pEx->GetErrorMessage(sz, 1024);             Freason = sz;           printf("%s",sz);           pEx->Delete(); } if (pFtpCon != NULL)       {           pFtpCon->Close();           delete pFtpCon;           pFtpCon = NULL;       }       return TRUE; }

    下载部分主程序:

    下载程序使用到3个另外的自定义函数,一个为检测目录是否存在,另一个是创建多级目录,此2个函数来自csdn的博客,还一个是文件大小比对的自写函数

    检测函数:

    BOOL FolderExists(CString s)    {        DWORD attr;         attr = GetFileAttributes(s);         return (attr != (DWORD)(-1) ) &&            ( attr & FILE_ATTRIBUTE_DIRECTORY);     }

    创建目录函数:

    BOOL CreateMuliteDirectory(CString P)    {        int len=P.GetLength();        if ( len <2 ) return false;         if('/'==P[len-1])       {           P=P.Left(len-1);           len=P.GetLength();       }       if ( len <=0 )  return false;       if (len <=3)        {           if (FolderExists(P)) return true;           else return false;        }       if (FolderExists(P)) return true;       CString Parent;       Parent=P.Left(P.ReverseFind('/') );      if(Parent.GetLength()<=0) return false;         BOOL Ret=CreateMuliteDirectory(Parent);         if(Ret)         {            SECURITY_ATTRIBUTES sa;            sa.nLength=sizeof(SECURITY_ATTRIBUTES);            sa.lpSecurityDescriptor=NULL;            sa.bInheritHandle=0;            Ret=(CreateDirectory(P,&sa)==TRUE);            return Ret;        }        else   return FALSE;    }

    int LocalFileCompa(CString folderpath,LONGLONG netfilesize)  //下载文档是文件夹的时候 { int index = folderpath.ReverseFind('/'); if(index == -1) { return FALSE; } CFileFind  finder; CString str_path(folderpath); str_path += _T("\\*.*"); vector <LONGLONG> V_nsize; BOOL bWorking = finder.FindFile(folderpath); while (bWorking) {    bWorking = finder.FindNextFile(); if (finder.IsDots()) {   continue; } else if(finder.IsDirectory()) {   LocalFileCompa(finder.GetFilePath(),netfilesize); } else { LONGLONG m_filesize;        m_filesize = finder.GetLength();    V_nsize.push_back(m_filesize); } } LONGLONG m_sumsize = 0; for(int i=0;i<V_nsize.size();i++) { m_sumsize +=  V_nsize[i];     } V_nsize.clear(); LONGLONG comresult; comresult = netfilesize / m_dirsize * 100; CString str; str.Format(_T("%d"),comresult); str = "%"+str; AfxMessageBox(_T("下载程度为")+str); return TRUE; }

    以下为下载文件或者文件夹程序:

    有两种做法,第一种,使用类cftpconnection::Getfile 函数进行下载:

    使用到的类有:

    cinternetsession 、 cftpconnection 、 cftpfilefind 、 CInternetFile 、 vector类

    可以根据msdn上的例子进行ftp连接和操作,链接:https://msdn.microsoft.com/zh-cn/library/hf9x9wb4.aspx 

    下载程序代码如下:

    BOOL DownloadFromFTP(CString remotepath,CString localpath,CString ftpaddr,CString username,CString &falreason,CString password,int port)  

    //定义布尔函数DownloadFromFTP {       int index = remotepath.ReverseFind('/');      //定义索引本index表示找到与remotepath中最后一个'/'时的值     if (index == -1)       {   falreason = "'/' can't found";         return FALSE;    //表示没有找到     }       CString remotefile = remotepath.Mid(index+1,remotepath.GetLength());  //返回'/'后的字符     CInternetSession sess(_T("Download Files Session"));    //创建class sess     CFtpConnection* pFtpCon = NULL;        //创建class pFtpCon为默认值        BOOL b = 0;     CInternetFile *fTargFile;     //计算文件大小时的指针,以下为一些保存的数据定义     vector <LONGLONG> V_nsize;  

        int outfs;                CString FileSize; try       {           pFtpCon = sess.GetFtpConnection(ftpaddr,username,password,port);  //调用GetFtpConnection连接FTP服务器         if (pFtpCon == NULL)    //如果连接失败           {   falreason = "connection is false";             return FALSE;  //连接失败时的返回结果         }           CFtpFileFind ftpFinder(pFtpCon);  //定义CFtpFileFind对象         BOOL bWorking = ftpFinder.FindFile(remotepath); // 在FTP上查找remotepath(findfile为文件搜索函数,这里应该是查找FTP上有无此路径)         if (bWorking != TRUE)   //如果在FTP服务器上没有找到remotepath           {   falreason = remotepath+ "can't found";             return FALSE;  //没找到路径时的返回结果         } CString remotepath1;    /*此处为路径处理,思路为先把remotepath当成文件进行下载,如果失败则当初目录下载*/ if(index == 0 | ig == 0)    //如果remotepath直接是文件路径(这里是根目录)那么直接下载,//ig,n都是用来表示当前进入了目录的哪一层 {    remotepath1 = remotepath.Left(index); } else { index = remotepath.GetLength() - index;    remotepath1=remotepath.Right(index); } if(!FolderExists(localpath+remotepath1)) { CreateMuliteDirectory(localpath+remotepath1);   //如果最后一个'/'后面还有文件名,那么此程序会创一个名为此文件名的文件夹 } b=pFtpCon->GetFile(remotepath, localpath+remotepath1+'/'+remotefile  ,TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1);    //GetFile第三项为ture,使得如果目标目录存在此名称的文件,则下载失败返回0导致后面的判断错误  //要问一下是否提示,是否要改为false if ( !b)  {                 while(bWorking)  //此循环为下载目录文件的循环               {                    bWorking = ftpFinder.FindNextFile();                    if (ftpFinder.IsDots())     //如果找到的是"."(表示返回顶级目录)或者".."(表示返回上一级目录)                    {                     TRACE("%s\n",ftpFinder.GetFileName());    ig --;                   continue;                     }                    else if(ftpFinder.IsDirectory())    //如果找到的是文件夹,递归调用DownloadFromFTP()                    {                    TRACE("%s\n",ftpFinder.GetFileName());  ig ++ ;                  DownloadFromFTP(remotepath+'/'+ftpFinder.GetFileName(),localpath+'/'+remotefile,ftpaddr,username,falreason,password, port);                    }                    else    //如果找到的是文件,直接下载                    {                    TRACE("%s\n",ftpFinder.GetFileName());  CString remotepath2; remotepath2 += ftpFinder.GetFileName();     int index1 = remotepath.ReverseFind('/'); if (index1==-1) { return false; } index1 = remotepath.GetLength() - index1 ; remotepath2 = remotepath.Right(index1);     if(!FolderExists(localpath+remotepath2))        {          CreateMuliteDirectory(localpath+remotepath2);       }   BOOL c;       c=pFtpCon->GetFile(remotepath+'/'+ftpFinder.GetFileName(), localpath+remotepath2+'/'+ftpFinder.GetFileName(),TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1);           remotepath2.Empty();

    /* 下载完成后保存大小*/   if(c)   {   LONGLONG  m_filesize = 0;   m_filesize = ftpFinder.GetLength(); //这里使用 cstring保存的时候要考虑cstringa和w的不同   V_nsize.push_back(m_filesize);   }  }        }

    /*计算文件夹中文件大小之和*/  LONGLONG m_sumsize = 0;  for(int i=0;i<V_nsize.size();i++)  {  m_sumsize +=  V_nsize[i];      }  m_dirsize += m_sumsize;   //要下载的文件大小之和  CString aa =_T("");  m_sumsize = m_dirsize;  aa.Format( _T("%d"),m_sumsize );  AfxMessageBox(aa);  V_nsize.clear();            }  else   //要下载路径直接代表的是文件的情况    { ij =1;             fTargFile = pFtpCon->OpenFile(remotepath,GENERIC_READ,FTP_TRANSFER_TYPE_BINARY,1 ); __int64 filesize2 = fTargFile->GetLength(); CString aa =_T(""); m_dirsize = filesize2;   //储存好了ftp文件大小 aa.Format( _T("%d"),filesize2 ); AfxMessageBox(aa); fTargFile->Close(); CFile *pFile = NULL; pFile = new CFile(localpath+remotepath1+'/'+remotefile,CFile::modeRead | CFile::shareDenyNone); LONGLONG dwLength = pFile->GetLength(); if(m_dirsize == 0 && dwLength == 0) { AfxMessageBox(_T("下载文件为空文件")); } else { LONGLONG comresult; comresult = m_dirsize / dwLength * 100;   //空文件时内存泄露,加了判断后没问题了 CString str; str.Format(_T("%d"),comresult); str = "%"+str; AfxMessageBox(_T("下载程度为")+str); } } }     catch (CInternetException* pEx)       {           TCHAR sz[1024];           pEx->GetErrorMessage(sz, 1024);   falreason = sz;           printf("%s",sz);           pEx->Delete();       }       if (pFtpCon != NULL)       {           pFtpCon->Close();           delete pFtpCon;           pFtpCon = NULL;       }       return TRUE;   }  

    第二种:使用读写函数,可以直接在下载的时候就保存文件大小,故不需要使用自写的那个LocalFileCompa函数

    BOOL DownloadFromFTP(CString remotepath,CString localpath,CString ftpaddr,CString username,CString &falreason,CString password,int port)  //定义布尔函数DownloadFromFTP {       int index = remotepath.ReverseFind('/');      //定义索引本index表示找到与remotepath中最后一个'/'时的     if (index == -1)       {   falreason = "'/' can't found";         return FALSE;    //表示没有找到     }       CString remotefile = remotepath.Mid(index+1,remotepath.GetLength());  //返回'/'后的字符     CInternetSession sess(_T("Download Files Session"));    //创建class sess      CFtpConnection* pFtpCon = NULL;        //创建class pFtpCon为默认值    BOOL b = 0; CInternetFile *fTargFile; vector <LONGLONG> V_nsize; vector <LONGLONG> V_fsize; CString FileSize; //以下加入断点续传的变量定义 unsigned char filebuf[512]; LONGLONG outfs; CString KBin,Perc;     try       {           pFtpCon = sess.GetFtpConnection(ftpaddr,username,password,port);  //调用GetFtpConnection连接FTP服务器         if (pFtpCon == NULL)    //如果连接失败           {   falreason = "connection is false";             return FALSE;  //连接失败时的返回结果         }           CFtpFileFind ftpFinder(pFtpCon);  //定义CFtpFileFind对象 CString str_path(remotepath); str_path += (_T("\\*.*"));  //意思是当前目录下以“任意文件名,任意扩展名”命名的文件         BOOL bWorking = ftpFinder.FindFile(str_path); // 在FTP上查找remotepath(findfile为文件搜索函数,这里应该是查找FTP上有无此路径)         if (bWorking != TRUE)   //如果在FTP服务器上没有找到remotepath           {   falreason = remotepath+ "can't found";             return FALSE;  //没找到路径时的返回结果         }                 while(bWorking)  //此循环为下载目录文件的循环               {                    bWorking = ftpFinder.FindNextFile();                    if (ftpFinder.IsDots())     //如果找到的是"."(表示返回顶级目录)或者".."(表示返回上一级目录)                    {                     TRACE("%s\n",ftpFinder.GetFileName());    ig --;                   continue;                     }                    else if(ftpFinder.IsDirectory())    //如果找到的是文件夹,递归调用DownloadFromFTP()                    {                    TRACE("%s\n",ftpFinder.GetFileName());  ig ++ ;                  DownloadFromFTP(remotepath+'/'+ftpFinder.GetFileName(),localpath+'/'+remotefile,ftpaddr,username,falreason,password, port);   }                  else    //如果找到的是文件,直接下载   /223.jpg   /220/223.jpg  /521/522/223/1.jpg  /220 4种情况                  {   CString openpath ;   //这种遍历的改写会导致判断文件与文件夹出错 CString remotepath2;  //本地目录创建路径 CString openlocpath;   //本地将要写的文件路径 /*以下为路径的拼接,可在调试的时候细看*/ if(remotefile == ftpFinder.GetFileName())//此判断主要用于/223.jpg和/220的区别 { openpath = remotepath; int index1 = openpath.ReverseFind('/'); if (index1==-1)  { return false; } else  { remotepath2 = openpath.Left(index);  openlocpath =  localpath + remotepath; } } else if(ig == 0)    //根目录文件情况 { openpath = remotepath + '/'+ ftpFinder.GetFileName(); remotepath2 =  remotepath; openlocpath =  localpath + openpath; } else {         openpath = remotepath + '/' + ftpFinder.GetFileName();     remotepath2 = '/'+ remotefile ; openlocpath = localpath + '/'+remotefile+'/'+ftpFinder.GetFileName(); } LONGLONG filesize = ftpFinder.GetLength();   //计算要下载的ftp文件大小 outfs = filesize / 1024; if(filesize == 0) //此处的文件计算改为网络连接 { falreason = "文件大小为0"; return FALSE; } V_fsize.push_back(outfs); FileSize.Format("%d",outfs); fTargFile = pFtpCon->OpenFile(openpath,GENERIC_READ,FTP_TRANSFER_TYPE_BINARY,1 );//getlength必须放在openfile之前才可行 /*   添加openfile错误时的处理代码   */ nDownloaded = 1;  if(FolderExists(localpath+remotepath2) == FALSE) //调用函数创建目录 { CreateMuliteDirectory(localpath+remotepath2);   } CFile fDestFile;  BOOL k; k = fDestFile.Open(openlocpath,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);  //打开目标必须是文件,不然后面的读和写都会错误 if(k == 0) {    return FALSE; } LONGLONG byteswrite = 0 ;    //保存写入大小 LONGLONG pos = 0 ;       //保存已写入数据 LONGLONG nperc, kbrecv;   

      //百分比 ,已收到数据  ,此百分比只表示当前下载的文件,如果是文件夹,那么会分别显示每一项文件下载的百分比   //与之类似,文件夹时会显示每一项文件的大小 while(byteswrite = fTargFile->Read(filebuf,512)) {     pos = pos + byteswrite; fDestFile.Write(filebuf, byteswrite); //..上面的open问题,,改成功 nperc = pos * 100 / filesize;    kbrecv = pos / 1024; Perc.Format("%d",nperc);                // 格式化进度百分比   KBin.Format("%d",kbrecv);               // 格式化已下载数据大小(KB)            //AfxMessageBox(Perc); // AfxMessageBox(KBin); } // AfxMessageBox(Perc); // AfxMessageBox(KBin); V_nsize.push_back(kbrecv); fDestFile.Close();                  TRACE("%s\n",ftpFinder.GetFileName());   }        }  LONGLONG m_sumsize = 0;  LONGLONG m_fsumsize = 0 ;  for(int i=0;i<V_nsize.size();i++)  {  m_sumsize +=  V_nsize[i];      }  for (int j=0;j<V_fsize.size();j++)  {      m_fsumsize += V_fsize[j];  }  m_dirsize  += m_sumsize ;  m_fdirsize += m_fsumsize;  V_nsize.clear();  V_fsize.clear(); }     catch (CInternetException* pEx)       {           TCHAR sz[1024];           pEx->GetErrorMessage(sz, 1024);   falreason = sz;           printf("%s",sz);           pEx->Delete();       }       if (pFtpCon != NULL)       {           pFtpCon->Close();           delete pFtpCon;           pFtpCon = NULL;       }       return TRUE;   }  

    按钮函数、控件函数 放在下面

    void CobjplayerDlg::OnBnClickedconnectButton() { // TODO: Add your control notification handler code here m_string.clear(); m_dotstring.clear(); m_ftppath=(_T("")); m_listBox.ResetContent(); V_counterpart.clear(); n=0; UpdateData(TRUE);    FtpList(m_ftppath,(m_ftpadress),(m_username),m_Freason,(m_password),m_port); UpdateData(FALSE); size[n]=m_string.size();  for(unsigned int i=0;i<m_string.size();i++)        //显示根目录  0层 { m_listBox.AddString(m_string.at(i)); } if (m_dotstring.size()!=0) { for(unsigned int j=0;j<m_dotstring.size();j++) { m_listBox.AddString(m_dotstring.at(j)); } } } void CobjplayerDlg::OnBnClickedshownextdirButton() { // TODO: Add your control notification handler code here CString n_ftppath; int NcurSel; NcurSel = m_listBox.GetCurSel(); if(m_listBox.GetCount()!=0)        //判断是否为空目录,果然为空目录就不执行循环 {  if(NcurSel!=-1)     //加一个判断,如果未选择列表项则不执行程序并弹出提示框,  未选择时不为1  {    if(NcurSel<size[n])    //加一个判断,如果是文件则报错,不执行下面创建副本以及进入下一层目录操作    {     if(n+1)          //按下显示下一层按钮时创建副本存储当前层数据     {        vector <CString> V_n;       //创建临时副本V_n      CString strText;              int numlist;    numlist= m_listBox.GetCount();        //当前列表项数量    for(int k=0;k<numlist;k++)    {    m_listBox.GetText(k,strText);                    V_n.push_back(strText);          //把当前的列表信息保存在当临时副本,数据数量为numlist    }    for(int l=0;l<numlist;l++)          {    V_counterpart.push_back(V_n[l]) ;      //当前副本信息转移到公共副本    }    dir[n]=numlist;          //当前目录包含文件数,记录此层存放在公共副本的数据数dir【0】=4 dir【1】=3        //第0层为""  第一层为/521    numlist=m_listBox.GetCurSel();    m_listBox.GetText(numlist,strText);    V_ftppath.push_back("/"+strText);    V_n.clear();     //清除临时副本    n++;            //当前层数     }     m_string.clear();                    //此处开始为进入下一层目录的代码     m_dotstring.clear();     m_listBox.GetText(NcurSel, n_ftppath);     m_ftppath=m_ftppath+L"/"+n_ftppath;    //"/520"     m_listBox.ResetContent(); UpdateData(TRUE);     FtpList(m_ftppath,(m_ftpadress),(m_username),m_Freason,(m_password),m_port); UpdateData(FALSE); size[n]=m_string.size();     for(unsigned int i=0;i<m_string.size();i++)     {     m_listBox.AddString(m_string.at(i));     }     if (m_dotstring.size()!=0)     {     for(unsigned int j=0;j<m_dotstring.size();j++)     {     m_listBox.AddString(m_dotstring.at(j));     }     }     }     else     {                INT_PTR nRes;             // 用于保存DoModal函数的返回值                   CTipDlg tipDlg;           // 构造对话框类CTipDlg的实例                   nRes = tipDlg.DoModal();  // 弹出对话框                   if (IDCANCEL == nRes)     // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行                       return;    m_listBox.GetText(NcurSel, n_ftppath);             m_ftppath=m_ftppath+L"/"+n_ftppath;   UpdateData(TRUE);           DownloadFromFTP(m_ftppath,(m_localpath),(m_ftpadress),(m_username),m_Freason,(m_password),m_port);             UpdateData(FALSE);     }  }  else        {    CString m_false;    m_false="请选择列表项";    AfxMessageBox(m_false);  }     } else     { CString n_false; n_false="空目录,无法进入下一层"; AfxMessageBox(n_false); } } void CobjplayerDlg::OnBnClickedReturnButton() { // TODO: Add your control notification handler code here if(n>0)           //n现在是2 { m_string.clear();       m_dotstring.clear();    m_listBox.ResetContent();    //先清除当前列表数据 int l=0; for(int j=0;j<n-1;j++)    //除了返回层以外的其他数据数量 {   l=l+dir[j]; }//需要显示第1层数据,即后面3个数据,V_counterpart[4] [5] [6]   dir[0]=4  dir [1]=3 V_counterpart.size()=7       循环为    for(unsigned int i=l;i<V_counterpart.size();i++)      //根据N显示哪一个副本          {     m_listBox.AddString(V_counterpart.at(i));    //根据条件显示副本中数据    }     V_counterpart.resize(l); m_ftppath.TrimRight(V_ftppath[n-1]); V_ftppath.resize(n-1);    //在公共副本中清除当前显示数据层以及之后层的数据 dir[n-1]=0;          size[n]=0;  n--;       //返回处理之后层数,逻辑为显示下一层n+1,返回上一层n-1                   } else { CString d_false; d_false="已到达顶层"; AfxMessageBox(d_false); } } void CobjplayerDlg::OnBnClickeddownloadButton() { // TODO: Add your control notification handler code here CString n_ftppath; int NcurSel; NcurSel = m_listBox.GetCurSel(); if(m_listBox.GetCount()!=0)        //判断是否为空目录,果然为空目录就不执行循环 {  if(NcurSel!=-1)     //加一个判断,如果未选择列表项则不执行程序并弹出提示框,  未选择时不为1  {    m_listBox.GetText(NcurSel, n_ftppath); CString c_remotepath = m_ftppath; CString c_remotepath1 = m_ftppath; UpdateData(TRUE); m_ftppath=c_remotepath+L"/"+n_ftppath;     DownloadFromFTP(m_ftppath,(m_localpath),(m_ftpadress),(m_username),m_Freason,(m_password),m_port); if (ij == 0) { LocalFileCompa(m_localpath+m_ftppath,m_dirsize); } m_ftppath = c_remotepath;       UpdateData(FALSE);       }  else        {    CString m_false;    m_false="请选择列表项";    AfxMessageBox(m_false);  }     } else     { CString n_false; n_false="空目录,无法下载"; AfxMessageBox(n_false); } } void CobjplayerDlg::OnDblclkDirshowList1() { // TODO: Add your control notification handler code here CString n_ftppath; int NcurSel; NcurSel = m_listBox.GetCurSel(); if(m_listBox.GetCount()!=0)        //判断是否为空目录,果然为空目录就不执行循环 {  if(NcurSel!=-1)     //加一个判断,如果未选择列表项则不执行程序并弹出提示框,  未选择时不为1  {    if(NcurSel<size[n])    //加一个判断,如果是文件则报错,不执行下面创建副本以及进入下一层目录操作    {     if(n+1)          //按下显示下一层按钮时创建副本存储当前层数据     {        vector <CString> V_n;       //创建临时副本V_n      CString strText;              int numlist;    numlist= m_listBox.GetCount();        //当前列表项数量    for(int k=0;k<numlist;k++)    {    m_listBox.GetText(k,strText);                    V_n.push_back(strText);          //把当前的列表信息保存在当临时副本,数据数量为numlist    }    for(int l=0;l<numlist;l++)          {    V_counterpart.push_back(V_n[l]) ;      //当前副本信息转移到公共副本    }    dir[n]=numlist;          //当前目录包含文件数,记录此层存放在公共副本的数据数dir【0】=4 dir【1】=3        //第0层为""  第一层为/521    numlist=m_listBox.GetCurSel();    m_listBox.GetText(numlist,strText);    V_ftppath.push_back("/"+strText);    V_n.clear();     //清除临时副本    n++;            //当前层数     }     m_string.clear();                    //此处开始为进入下一层目录的代码     m_dotstring.clear();     m_listBox.GetText(NcurSel, n_ftppath);     m_ftppath=m_ftppath+L"/"+n_ftppath;    //"/520"     m_listBox.ResetContent(); UpdateData(TRUE);     FtpList(m_ftppath,(m_ftpadress),(m_username),m_Freason,(m_password),m_port); UpdateData(FALSE); size[n]=m_string.size();     for(unsigned int i=0;i<m_string.size();i++)     {     m_listBox.AddString(m_string.at(i));     }     if (m_dotstring.size()!=0)     {     for(unsigned int j=0;j<m_dotstring.size();j++)     {     m_listBox.AddString(m_dotstring.at(j));     }     }     }     else     {                INT_PTR nRes;             // 用于保存DoModal函数的返回值                   CTipDlg tipDlg;           // 构造对话框类CTipDlg的实例                   nRes = tipDlg.DoModal();  // 弹出对话框                   if (IDCANCEL == nRes)     // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行                       return;    m_listBox.GetText(NcurSel, n_ftppath);             m_ftppath=m_ftppath+L"/"+n_ftppath;   UpdateData(TRUE);           DownloadFromFTP(m_ftppath,(m_localpath),(m_ftpadress),(m_username),m_Freason,(m_password),m_port);             UpdateData(FALSE);     }  }  else        {    CString m_false;    m_false="请选择列表项";    AfxMessageBox(m_false);  }     } else     { CString n_false; n_false="空目录,无法进入下一层"; AfxMessageBox(n_false); } }

    转载请注明原文地址: https://ju.6miu.com/read-675199.html

    最新回复(0)