VC++ 实现文件上传下载服务器端

来源:互联网 发布:数据报告ppt模板 编辑:程序博客网 时间:2024/06/10 08:00


#pragma once
#include <afxsock.h>

#define   WM_FILELIST   WM_USER + 101  //接收文件列表
#define   WM_FILEUPDATE  WM_USER + 102  //反映文件下载状态
#define   WM_FILEDOWNLOAD  WM_USER + 103    //发送文件列表


#define   FILELIST      1000    //请求文件列表
#define   FILEUPDATE   2000    //请求文件上传
#define   FILEDOWNLOAD  3000    //请求文件下载

#define   RECVSIZE   1024*16       //一次性发送/接收的数据块大小

//与服务器通信语言结构
typedef struct
{
 int  iCommand;
 long lFileOffset;
 long lFileLength;
 char sFilePath[128];
}MSGFILE;

//请求线程参数
typedef struct
{
 char sIP[15];  //IP地址
 int  iPort;   //端口
 MSGFILE msgFile; //通信语言结构
 LPVOID ptr;  //指针
}MSGPARAM;

//文件列表结构
typedef struct
{
 long lFileLength;
 char sFilePath[128];
}MSGFILELIST;

//反映文件状态的结构
typedef struct
{
 long lFileOffset;//偏移
 char sFilePath[128];//路径
}MSGFILESTATUS;

//接收线程参数
typedef struct
{
 SOCKET sock;
 LPVOID ptr;
}PARAMRECV;



//服务器端 类 头文件

// Ftp_Server.h: interface for the CFtp_Server class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FTP_SERVER_H__DCFE7BE8_C212_475E_AAC8_811898047B46__INCLUDED_)
#define AFX_FTP_SERVER_H__DCFE7BE8_C212_475E_AAC8_811898047B46__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "basedef.h"
#define WM_FINISHUPDATE WM_USER+401

class CFtp_Server 
{
public:
 CFtp_Server();
 virtual ~CFtp_Server();

 BOOL StartListen(CWnd *pWnd, int nPort, char *sPath);
 void StopListen();

protected:
 //监听线程
 static DWORD WINAPI ListenThread(LPVOID lpParam);
 
 //接收线程
 static DWORD WINAPI RecvThread(LPVOID lpParam);
private:
 //监听线程结束符
 BOOL m_bEndListenThread;

 //监听端口
 int m_iListenPort;

 //窗口指针
 CWnd* m_pWnd;

 //服务器套接字
 SOCKET m_socket;

 //保存本机地址
 SOCKADDR_IN m_sin;

 //存储路径
 char m_sPath[128];
};

#endif // !defined(AFX_FTP_SERVER_H__DCFE7BE8_C212_475E_AAC8_811898047B46__INCLUDED_)



//服务器端 类 CPP

// Ftp_Server.cpp: implementation of the CFtp_Server class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Ftp_Server.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFtp_Server::CFtp_Server()
{
}


CFtp_Server::~CFtp_Server()
{
}


BOOL CFtp_Server::StartListen(CWnd *pWnd, int nPort, char *sPath)
{
 //初始化套接字
 if (!AfxSocketInit())
 {
  return FALSE;
 }

 //获得端口号和窗口指针
 m_iListenPort = nPort;
 m_pWnd = pWnd;
 strcpy(m_sPath, sPath);

 m_bEndListenThread = FALSE;//开始监听

 DWORD id;
 HANDLE h = CreateThread(NULL, 0, ListenThread, this, 0, &id);//创建句柄
 //线程要执行的函数为ThreadListen,将this指针传递给线程,线程ID为id,创建成功,返回新线程的一个句柄
 CloseHandle(h); //关闭句柄,并不终止线程

 return TRUE;
}


void CFtp_Server::StopListen()
{
 m_bEndListenThread = TRUE;
 Sleep(100);
 closesocket(m_socket);
}


DWORD WINAPI CFtp_Server::ListenThread(LPVOID lpParam)
{
 CFtp_Server* pServer = (CFtp_Server*)lpParam;

 SOCKET sockListen = socket(AF_INET, SOCK_STREAM, 0);//创建socket
 //地址家族为internet,用于TCP和UDP,字节流,特定的协议

 SOCKADDR_IN sin; //转换地址
 sin.sin_family = AF_INET;
 sin.sin_addr.s_addr = 0; //ip地址,以网路字节顺序。
 sin.sin_port = htons(pServer->m_iListenPort);

 if (bind(sockListen, (SOCKADDR*)&sin, sizeof(sin)) == SOCKET_ERROR)
 {
  closesocket(sockListen); //关闭socket
  return FALSE;
 }

 if (listen(sockListen, 5) == SOCKET_ERROR)
 {//若将socket置于监听失败
  closesocket(sockListen);
  return FALSE;
 }

 fd_set fdListen;//结构体,将socket放进一个集合
 timeval seltime;//结构体,指定时间值(秒+毫秒)
 seltime.tv_sec = 0; //秒
 seltime.tv_usec = 10000;//毫秒==10秒

 while (!pServer->m_bEndListenThread)
 {//服务器在监听状态
  FD_ZERO(&fdListen);//将集合清零
  FD_SET(sockListen, &fdListen);//将socket添加到set中

  if (select(0, &fdListen, NULL, NULL, &seltime) <= 0 || !FD_ISSET(sockListen, &fdListen))
   continue;
  //如果在规定时间内,set中无socket可读出||socket不在set中,结束本次循环,继续下次循环

  int len = sizeof(sin);
  SOCKET sock = accept(sockListen, (SOCKADDR*)&sin, &len);
  //接受socket上的连接

  PARAMRECV* pParamRecv = new PARAMRECV;//结构体,接收线程参数
  pParamRecv->sock = sock;
  pParamRecv->ptr = pServer;

  DWORD id;
  HANDLE h = CreateThread(NULL, 0, RecvThread, pParamRecv, 0, &id);
  //创建ThreadRecv线程,将pParamRecv传递给线程
  CloseHandle(h);
 }

 return 0;
}

DWORD WINAPI CFtp_Server::RecvThread(LPVOID lpParam)
{
 PARAMRECV* pParam = (PARAMRECV*)lpParam;//指向接收线程的指针
 CFtp_Server* pServer = (CFtp_Server*)pParam->ptr;//指向Server的指针

 fd_set fdRecv;//结构体,接收线程集合
 timeval seltime;//结构体,指定时间值==10s
 seltime.tv_sec = 0;
 seltime.tv_usec = 10000;

 while (1)
 {
  FD_ZERO(&fdRecv);//集合清零
  FD_SET(pParam->sock, &fdRecv);//将已连接的socket加入集合

  if (select(0, &fdRecv, NULL, NULL, &seltime) <= 0 || !FD_ISSET(pParam->sock, &fdRecv))
   continue;
  //如果在指定时间内,结构体内无可读接收线程||sock不在结构体内

  MSGFILE msgFile;
  int iRecvCnt = recv(pParam->sock, (char*)&msgFile, sizeof(msgFile), 0);
  //成功,返回接收字节数;正常结束,返回0;否则<0
  if (iRecvCnt <= 0)
   break;

  //请求文件列表
  if (msgFile.iCommand == FILELIST)
  {
   while (!pServer->m_bEndListenThread)
   {
    MSGFILELIST msgFileList;
    iRecvCnt = recv(pParam->sock, (char*)&msgFileList, sizeof(msgFileList), 0);
    if (iRecvCnt <= 0)
     break;

    pServer->m_pWnd->SendMessage(WM_FILELIST, (WPARAM)&msgFileList, 0);
   }
  }

  //请求文件下载
  else if (msgFile.iCommand == FILEDOWNLOAD)
  {
   long lFileOffset = msgFile.lFileOffset;//文件偏移

   CFile file;
   CString strPath, strName;
   strPath.Format("%s", msgFile.sFilePath);
   int iPos = strPath.ReverseFind('\\');
   strName = strPath.Right(strPath.GetLength() - iPos - 1);
   strPath.Format("%s", pServer->m_sPath);
   strPath += strName;

   BOOL bResult = file.Open(strPath, CFile::modeRead | CFile::shareDenyNone, NULL);
   //打开指定路径的文件,只读||可共享,成功,返回非零;否则,0
   if (!bResult)
   {
    break;
   }

   char sSendBuf[RECVSIZE];//发送缓冲区,16K   
   while (lFileOffset < msgFile.lFileLength)
   {
    int iSeek = file.Seek(lFileOffset, CFile::begin);//寻找新的文件偏移,距离开始处
    int iReadCnt = file.Read(sSendBuf, RECVSIZE);
    if (iReadCnt == 0)
     break;

    int iSendCnt = send(pParam->sock, sSendBuf, iReadCnt, 0);
    //如果发送失败就终止线程
    if (iSendCnt == -1)
     break;
    else
     lFileOffset += iSendCnt;//修改偏移量
   }

   file.Close();
  }

  //请求文件上传
  else if (msgFile.iCommand == FILEUPDATE)
  {
   char sRecvBuf[RECVSIZE] = "\0"; //接收缓冲区置空
   long lFileOffset = msgFile.lFileOffset;
   CFile file;

   //将客户端路径改为服务端保存路径
   CString strPath, strName;
   strPath.Format("%s", msgFile.sFilePath);
   int iPos = strPath.ReverseFind('\\');
   strName = strPath.Right(strPath.GetLength() - iPos - 1);
   strPath.Format("%s", pServer->m_sPath);
   strPath += strName;

   BOOL bResult = file.Open(strPath, CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate, NULL);
   //打开接收端文件,写模式||若创建的文件已存在,不截短。
   while (bResult && lFileOffset < msgFile.lFileLength)
   {
    int iRecvCnt = recv(pParam->sock, sRecvBuf, RECVSIZE, 0);
    if (iRecvCnt <= 0)
     break;

    file.Seek(lFileOffset, CFile::begin);
    file.Write(sRecvBuf, iRecvCnt);
    lFileOffset += iRecvCnt;//修改偏移

    MSGFILESTATUS msgFileStatus;//文件状态结构体
    msgFileStatus.lFileOffset = lFileOffset;
    strcpy(msgFileStatus.sFilePath, msgFile.sFilePath);
    pServer->m_pWnd->SendMessage(WM_FILEUPDATE, (WPARAM)&msgFileStatus, 0);
   }
   file.Close();
   pServer->m_pWnd->SendMessage(WM_FINISHUPDATE, 0, 0);
  }

  break;
 }
 delete pParam;

 return 0;
}

//对话框 头文件

// Server_FTPDlg.h : header file
//

#if !defined(AFX_SERVER_FTPDLG_H__492B251E_B713_4E0F_A5A4_C1BC9EB8EF08__INCLUDED_)
#define AFX_SERVER_FTPDLG_H__492B251E_B713_4E0F_A5A4_C1BC9EB8EF08__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Ftp_Server.h"
/////////////////////////////////////////////////////////////////////////////
// CServer_FTPDlg dialog

class CServer_FTPDlg : public CDialog
{
// Construction
public:
 void InitListColumn();
 CServer_FTPDlg(CWnd* pParent = NULL); // standard constructor

 CFtp_Server *m_pFtp_Server;

 BOOL m_bConnected; //已连接
 int m_nUpdateNum; //已上传文件
// Dialog Data
 //{{AFX_DATA(CServer_FTPDlg)
 enum { IDD = IDD_SERVER_FTP_DIALOG };
 CListCtrl m_ListFile;
 int  m_nPort;
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CServer_FTPDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CServer_FTPDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
 afx_msg void OnBtnListen();
 afx_msg void OnBtnScan();
 afx_msg void OnDestroy();
 //}}AFX_MSG
 afx_msg LRESULT OnFileList(WPARAM wp, LPARAM lp);
 afx_msg LRESULT OnFileUpdate(WPARAM wp, LPARAM lp);
 afx_msg LRESULT OnFinishUpdate(WPARAM wp, LPARAM lp);

 DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SERVER_FTPDLG_H__492B251E_B713_4E0F_A5A4_C1BC9EB8EF08__INCLUDED_)


//对话框 CPP文件

// Server_FTPDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Server_FTP.h"
#include "Server_FTPDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 //{{AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 //{{AFX_MSG(CAboutDlg)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{{AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{{AFX_MSG_MAP(CAboutDlg)
  // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CServer_FTPDlg dialog

CServer_FTPDlg::CServer_FTPDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CServer_FTPDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CServer_FTPDlg)
 m_nPort = 7000;
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 m_bConnected = FALSE;
 m_nUpdateNum = 0;
}

void CServer_FTPDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CServer_FTPDlg)
 DDX_Control(pDX, IDC_LIST_FILE, m_ListFile);
 DDX_Text(pDX, IDC_EDIT_PORT, m_nPort);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CServer_FTPDlg, CDialog)
 //{{AFX_MSG_MAP(CServer_FTPDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_WM_ERASEBKGND()
 ON_BN_CLICKED(IDC_BTN_LISTEN, OnBtnListen)
 ON_BN_CLICKED(IDC_BTN_SCAN, OnBtnScan)
 ON_WM_DESTROY()
 //}}AFX_MSG_MAP
 ON_MESSAGE(WM_FILELIST, OnFileList)
 ON_MESSAGE(WM_FILEUPDATE, OnFileUpdate)
 ON_MESSAGE(WM_FINISHUPDATE, OnFinishUpdate)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CServer_FTPDlg message handlers

BOOL CServer_FTPDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // Set the icon for this dialog.  The framework does this automatically
 //  when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 
 InitListColumn();

 m_pFtp_Server = new CFtp_Server();
 // TODO: Add extra initialization here
 
 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CServer_FTPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CServer_FTPDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CServer_FTPDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

BOOL CServer_FTPDlg::OnEraseBkgnd(CDC* pDC)
{
 // TODO: Add your message handler code here and/or call default
 //更改背景颜色
 CRect rect;
 GetClientRect(&rect);
 pDC->FillSolidRect(&rect, RGB(202, 225, 243));
 return TRUE;
 // return CDialog::OnEraseBkgnd(pDC);
}

void CServer_FTPDlg::OnBtnListen()
{
 // TODO: Add your control notification handler code here
 if (m_bConnected)
 {
  m_pFtp_Server->StopListen();
  SetDlgItemText(IDC_BTN_LISTEN, _T("启动监听"));
  GetDlgItem(IDC_EDIT_PORT)->EnableWindow(TRUE);
  m_bConnected = FALSE;
  return;
 }
 CString sPath;
 GetDlgItemText(IDC_EDIT_PATH, sPath);
 if (sPath.IsEmpty())
 {
  AfxMessageBox(_T("请先设置文件存储路径!"));
  return;
 }
 int nPort = GetDlgItemInt(IDC_EDIT_PORT);
 if (m_pFtp_Server->StartListen(this, nPort, sPath.GetBuffer(0)))
 {
  SetDlgItemText(IDC_BTN_LISTEN, _T("停止监听"));
  GetDlgItem(IDC_EDIT_PORT)->EnableWindow(FALSE);
  m_bConnected = TRUE;
  return;
 }

 AfxMessageBox(_T("服务器启动失败!"));
}

void CServer_FTPDlg::OnBtnScan()
{
 // TODO: Add your control notification handler code here
 BROWSEINFO bi; //定义后面将被SHBrowseForFolder调用参数
 char buffer[MAX_PATH];
 ZeroMemory(buffer,MAX_PATH);
 bi.hwndOwner = this->m_hWnd;
 bi.pidlRoot = NULL;
 bi.pszDisplayName=buffer;
 bi.lpszTitle = "指定文件夹";
 bi.ulFlags = BIF_RETURNONLYFSDIRS;
 bi.lpfn = NULL;
 bi.lParam = 0;
 bi.iImage = 0;
 LPITEMIDLIST pList = NULL;
 if((pList=SHBrowseForFolder(&bi)) != NULL)
 {
  char path[MAX_PATH];
  ZeroMemory(path,MAX_PATH);
  SHGetPathFromIDList(pList,path);//根据你设置的属性  打开 返回路径到path
  SetDlgItemText(IDC_EDIT_PATH, path);
 }
}

void CServer_FTPDlg::InitListColumn()
{
 int iWidth = 50;
 m_ListFile.InsertColumn(0, "文件名", LVCFMT_LEFT, 3*iWidth, -1);
 m_ListFile.InsertColumn(1, "文件大小", LVCFMT_LEFT, 2*iWidth, -1);
 m_ListFile.InsertColumn(2, "上传速度", LVCFMT_LEFT, 2*iWidth, -1);
 m_ListFile.InsertColumn(3, "上传状态", LVCFMT_LEFT, 2*iWidth, -1);
 m_ListFile.InsertColumn(4, "上传时间", LVCFMT_LEFT, 2*iWidth, -1);
 m_ListFile.InsertColumn(5, "文件保存路径", LVCFMT_LEFT, 5*iWidth, -1);
 m_ListFile.InsertColumn(6, "时间标记", LVCFMT_LEFT, 2*iWidth, -1);
 //插入列:左对齐,无子列
 m_ListFile.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
}

void CServer_FTPDlg::OnDestroy()
{
 CDialog::OnDestroy();
 
 // TODO: Add your message handler code here
 if(m_pFtp_Server != NULL)
 {
  m_pFtp_Server->StopListen();
  delete m_pFtp_Server;
 }
}

LRESULT CServer_FTPDlg::OnFileUpdate(WPARAM wp, LPARAM lp)
{
 MSGFILESTATUS* pmsg = (MSGFILESTATUS*)wp;
 CString strPath;
 strPath.Format("%s", pmsg->sFilePath);
 int iTotal = m_ListFile.GetItemCount();
 int iSel = 0;
 for(; iSel<iTotal; iSel++)
 {
  CString strListPath;
  strListPath = m_ListFile.GetItemText(iSel, 5);
  if(strPath.Compare(strListPath) == 0)//路径相同
   break;
 }
 if(iSel == iTotal)
  return 1;

 long lFileLength = m_ListFile.GetItemData(iSel);
 CString strStatus;
 strStatus.Format("%0.2f%%", (float)pmsg->lFileOffset/lFileLength*100);
 //显示状态 %,精确到小数点后两位
 m_ListFile.SetItemText(iTotal-1, 3, strStatus.GetBuffer(0));
 
 //显示时间
 DWORD dwNowTick, dwStartTick;//毫秒
 dwNowTick = GetTickCount();
 sscanf(m_ListFile.GetItemText(iSel, 6), "%u", &dwStartTick);
 
 long iEllapsed = (dwNowTick-dwStartTick);//间隔:微秒
 strStatus.Format("%dms", iEllapsed);
 m_ListFile.SetItemText(iSel, 4, strStatus.GetBuffer(0));
 
 //显示速度
 if(iEllapsed > 0)
 {
  strStatus.Format("%dk/s", (pmsg->lFileOffset/1024/iEllapsed)*1000);
  m_ListFile.SetItemText(iSel, 2, strStatus.GetBuffer(0));
 }


 return 0;
}

LRESULT CServer_FTPDlg::OnFileList(WPARAM wp, LPARAM lp)
{
 MSGFILELIST* pmsgList = (MSGFILELIST*)wp;
 int iItem = m_ListFile.GetItemCount();
 for (int i = m_nUpdateNum; i < iItem; i++)
 {
  m_ListFile.DeleteItem(i);
 }
 iItem = m_nUpdateNum;

 CString strServerPath, strFileName, strFileSize;
 strServerPath.Format("%s", pmsgList->sFilePath);
 int iPos = strServerPath.ReverseFind('\\');
 //设置文件名到缓冲区
 strFileName = strServerPath.Right(strServerPath.GetLength()-iPos-1);
 strFileSize.Format("%0.2fk", (float)pmsgList->lFileLength/1024);
 
 LV_ITEM lvi;
 lvi.mask = LVIF_TEXT|LVIF_PARAM;
 lvi.iItem = iItem;
 lvi.iSubItem = 0;
 lvi.lParam = pmsgList->lFileLength;
 //显示
 lvi.pszText = strFileName.GetBuffer(0);
 m_ListFile.InsertItem(&lvi);
 m_ListFile.SetItemText(iItem, 1, strFileSize.GetBuffer(0));
 m_ListFile.SetItemText(iItem, 5, strServerPath.GetBuffer(0));

 //设置初始时间点
 DWORD dwStartTick = GetTickCount();
 char sStartTick[20];
 sprintf(sStartTick, "%u", dwStartTick);
 m_ListFile.SetItemText(iItem, 6, sStartTick);

 return 0;
}

LRESULT CServer_FTPDlg::OnFinishUpdate(WPARAM wp, LPARAM lp)
{
 ++ m_nUpdateNum;
 return 0;
}

0 0
原创粉丝点击