//basedef.h
//此头文件定义了结构体和消息
#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_Client.h: interface for the CFtp_Client class.////////////////////////////////////////////////////////////////////////
#if !defined(AFX_FTP_CLIENT_H__CB684F7E_C9B5_4025_AA2E_F307234CA75C__INCLUDED_)#define AFX_FTP_CLIENT_H__CB684F7E_C9B5_4025_AA2E_F307234CA75C__INCLUDED_
#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "basedef.h"
#define WM_CONNECTERROR WM_USER + 301
class CFtp_Client {public: CFtp_Client(); virtual ~CFtp_Client();
//创建线程发送请求 void SendRequest(MSGPARAM msgParam); //设置服务器参数 BOOL InitParam(CWnd* pWnd, char* sIP, int nPort);
//停止所有线程 void StopThread(); protected: //请求线程 static DWord WINAPI RequestThread(LPVOID lpParam); private: //服务器IP char m_sIP[15]; //服务器端口 int m_nPort; //指向窗口的指针 CWnd* m_pWnd;
//停止线程 static BOOL m_bEndThread;};
#endif // !defined(AFX_FTP_CLIENT_H__CB684F7E_C9B5_4025_AA2E_F307234CA75C__INCLUDED_)
//cpp 文件
// Ftp_Client.cpp: implementation of the CFtp_Client class.////////////////////////////////////////////////////////////////////////
#include "stdafx.h"#include "Ftp_Client.h"
#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif
BOOL CFtp_Client::m_bEndThread = FALSE;//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////
CFtp_Client::CFtp_Client(){ strcpy(m_sIP, "127.0.0.1"); m_nPort = 7000; m_pWnd = NULL;}
CFtp_Client::~CFtp_Client(){ }
BOOL CFtp_Client::InitParam(CWnd* pWnd, char* sIP, int nPort){ if (!AfxSocketInit()) { return FALSE; } //保留参数 strcpy(m_sIP, sIP); m_nPort = nPort; m_pWnd = pWnd; return TRUE;}
//向服务器请求文件列表void CFtp_Client::SendRequest(MSGPARAM msgParam){ //为结构体赋值,作为参数传递到线程 MSGPARAM* pMsgParam = new MSGPARAM; pMsgParam->ptr = m_pWnd; strcpy(pMsgParam->sIP, m_sIP); pMsgParam->iPort = m_nPort; pMsgParam->msgFile.iCommand = msgParam.msgFile.iCommand; pMsgParam->msgFile.lFileLength = msgParam.msgFile.lFileLength; pMsgParam->msgFile.lFileOffset = msgParam.msgFile.lFileOffset; strcpy(pMsgParam->msgFile.sFilePath, msgParam.msgFile.sFilePath); DWORD id; HANDLE h = CreateThread(NULL, 0, RequestThread, pMsgParam, 0, &id); //创建发送请求并接收反馈的线程 CloseHandle(h); }
DWORD WINAPI CFtp_Client::RequestThread(LPVOID lpParam){ MSGPARAM* pMsgParam = (MSGPARAM*)lpParam; CWnd* pWnd = (CWnd*)pMsgParam->ptr; SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr(pMsgParam->sIP); sin.sin_port = htons(pMsgParam->iPort); //连接成功 if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) { //发送请求 int iSendCnt = send(sock, (char*)&pMsgParam->msgFile, sizeof(pMsgParam->msgFile), 0); if(pMsgParam->msgFile.iCommand == FILELIST) //如果是请求文件列表 { pWnd->SendMessage(WM_FILELIST, sock, 0); } else if (pMsgParam->msgFile.iCommand == FILEUPDATE) { char sRecvBuf[RECVSIZE] = "/0"; //接收缓冲区置空 long lFileOffset = pMsgParam->msgFile.lFileOffset; //打开文件,打不开则不上传 CFile file; BOOL bResult = file.Open(pMsgParam->msgFile.sFilePath, CFile::modeRead|CFile::shareDenyNone, NULL); if(bResult) { char sSendBuf[RECVSIZE];//发送缓冲区,16K while(!CFtp_Client::m_bEndThread && lFileOffset < pMsgParam->msgFile.lFileLength) { int iSeek = file.Seek(lFileOffset, CFile::begin);//寻找新的文件偏移,距离开始处 int iReadCnt = file.Read(sSendBuf, RECVSIZE);//读计数器,读到发送缓冲区,一次16K if (iReadCnt ==0)//读出字节数为0 break; int iSendCnt = send(sock, sSendBuf, iReadCnt, 0); if (iSendCnt == -1) break; else lFileOffset += iSendCnt;//修改偏移量 MSGFILESTATUS msgFileStatus;//文件状态结构体 msgFileStatus.lFileOffset = lFileOffset; strcpy(msgFileStatus.sFilePath, pMsgParam->msgFile.sFilePath); pWnd->SendMessage(WM_FILEUPDATE, (WPARAM)&msgFileStatus, 0);
}
file.Close(); } } else if(pMsgParam->msgFile.iCommand == FILEDOWNLOAD) //如果是请求下载文件 { char sRecvBuf[RECVSIZE] = "/0"; //接收缓冲区置空 long lFileOffset = pMsgParam->msgFile.lFileOffset; CFile file; BOOL bResult = file.Open(pMsgParam->msgFile.sFilePath, CFile::modeWrite|CFile::modeNoTruncate, NULL); //打开接收端文件,写模式||若创建的文件已存在,不截短。 while(!CFtp_Client::m_bEndThread && bResult && lFileOffset < pMsgParam->msgFile.lFileLength) { int iRecvCnt = recv(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, pMsgParam->msgFile.sFilePath); pWnd->SendMessage(WM_FILEDOWNLOAD, (WPARAM)&msgFileStatus, 0); } file.Close(); if(lFileOffset < pMsgParam->msgFile.lFileLength && !CFtp_Client::m_bEndThread) //如果没有下载完,请求续传 {//接收线程未结束&&偏移<文件长度 MSGPARAM* pMsgParamResume = new MSGPARAM;//指向请求线程参数结构体的指针 strcpy(pMsgParamResume->sIP, pMsgParam->sIP); pMsgParamResume->iPort = pMsgParam->iPort; pMsgParamResume->ptr = pMsgParam->ptr; pMsgParamResume->msgFile.iCommand = pMsgParam->msgFile.iCommand ; pMsgParamResume->msgFile.lFileLength = pMsgParam->msgFile.lFileLength; pMsgParamResume->msgFile.lFileOffset = lFileOffset; strcpy(pMsgParamResume->msgFile.sFilePath, pMsgParam->msgFile.sFilePath); DWORD id; HANDLE h = CreateThread(NULL, 0, RequestThread, pMsgParamResume, 0, &id); //递归调用 CloseHandle(h); } } } else { pWnd->SendMessage(WM_CONNECTERROR, 0, 0); } closesocket(sock); delete pMsgParam; return 0;}
void CFtp_Client::StopThread(){ m_bEndThread = TRUE;}
//对话框头文件
// Client_FTPDlg.h : header file//
#if !defined(AFX_CLIENT_FTPDLG_H__E7F99F34_0BD2_4B11_8FF7_D958887D2368__INCLUDED_)#define AFX_CLIENT_FTPDLG_H__E7F99F34_0BD2_4B11_8FF7_D958887D2368__INCLUDED_
#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "Label.h"#include "Ftp_Client.h"
/////////////////////////////////////////////////////////////////////////////// CClient_FTPDlg dialog class CClient_FTPDlg : public CDialog{// Constructionpublic:
void InitListColumn(); CClient_FTPDlg(CWnd* pParent = NULL); // standard constructor
CFtp_Client *m_pFtpClient; //上传下载类对象
BOOL m_bConnected; //连接状态 long m_lFileSize; //文件大小 CString m_strFileName;//文件名 CString m_strFilePath;//文件路径// Dialog Data //{{AFX_DATA(CClient_FTPDlg) enum { IDD = IDD_CLIENT_FTP_DIALOG }; CProgressCtrl m_Progress; CListCtrl m_ListFile; CIPAddressCtrl m_IPAddr; CLabel m_LabProgress; //}}AFX_DATA
// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CClient_FTPDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL
// Implementationprotected: HICON m_hIcon;
// Generated message map functions //{{AFX_MSG(CClient_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 OnBtnScan(); afx_msg void OnBtnUpdate(); afx_msg void OnDestroy(); afx_msg void OnDblclkListFile(NMHDR* pNMHDR, LRESULT* pResult); //}}AFX_MSG
afx_msg LRESULT OnFileDownload(WPARAM wp, LPARAM lp); afx_msg LRESULT OnFileUpdate(WPARAM wp, LPARAM lp); afx_msg LRESULT OnFileList(WPARAM wp, LPARAM lp); afx_msg LRESULT OnConnectError(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_CLIENT_FTPDLG_H__E7F99F34_0BD2_4B11_8FF7_D958887D2368__INCLUDED_)
//对话框 cpp 文件
// Client_FTPDlg.cpp : implementation file//
#include "stdafx.h"#include "Client_FTP.h"#include "Client_FTPDlg.h"
#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic 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
// Implementationprotected: //{{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_MAPEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////// CClient_FTPDlg dialog
CClient_FTPDlg::CClient_FTPDlg(CWnd* pParent /*=NULL*/) : CDialog(CClient_FTPDlg::IDD, pParent){ //{{AFX_DATA_INIT(CClient_FTPDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_bConnected = FALSE; m_strFileName = _T(""); m_lFileSize = 0;
}
void CClient_FTPDlg::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CClient_FTPDlg) DDX_Control(pDX, IDC_PROGRESS1, m_Progress); DDX_Control(pDX, IDC_LIST_FILE, m_ListFile); DDX_Control(pDX, IDC_IPADDRESS1, m_IPAddr); DDX_Control(pDX, IDC_STATIC_PROGRESS, m_LabProgress); //}}AFX_DATA_MAP}
BEGIN_MESSAGE_MAP(CClient_FTPDlg, CDialog) //{{AFX_MSG_MAP(CClient_FTPDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_ERASEBKGND() ON_BN_CLICKED(IDC_BTN_SCAN, OnBtnScan) ON_BN_CLICKED(IDC_BTN_UPDATE, OnBtnUpdate) ON_WM_DESTROY() ON_NOTIFY(NM_DBLCLK, IDC_LIST_FILE, OnDblclkListFile) //}}AFX_MSG_MAP ON_MESSAGE(WM_FILELIST, OnFileList) ON_MESSAGE(WM_FILEUPDATE, OnFileUpdate) ON_MESSAGE(WM_FILEDOWNLOAD, OnFileDownload) ON_MESSAGE(WM_CONNECTERROR, OnConnectError)END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////// CClient_FTPDlg message handlers
BOOL CClient_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
m_LabProgress.SetFontSize(20); m_LabProgress.SetBkColor(BACKCOLOR); m_Progress.SetRange(0, 100); m_Progress.SetPos(0); m_LabProgress.SetText(_T("0%"));
m_IPAddr.SetAddress(127, 0, 0, 1); SetDlgItemInt(IDC_EDIT_PORT, 7000); InitListColumn();
m_pFtpClient = new CFtp_Client(); // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control}
void CClient_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 CClient_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 CClient_FTPDlg::OnQueryDragIcon(){ return (HCURSOR) m_hIcon;}
BOOL CClient_FTPDlg::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default //更改背景颜色 CRect rect; GetClientRect(&rect); pDC->FillSolidRect(&rect, BACKCOLOR); return TRUE; // return CDialog::OnEraseBkgnd(pDC);}
void CClient_FTPDlg::OnBtnScan() { // TODO: Add your control notification handler code here //文件选择 CFileDialog fileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "All Files(*.*)|*.*||", this); if(fileDlg.DoModal() == IDOK) { //获取文件路径 CString strPathName = fileDlg.GetPathName(); CFile file; BOOL bOpen = file.Open(strPathName, CFile::modeRead|CFile::shareDenyNone, NULL); if(!bOpen) { MessageBox("打开失败,请确认路径再重试!"); return; }
m_lFileSize = file.GetLength(); m_strFilePath = strPathName; m_strFileName = fileDlg.GetFileName(); file.Close();
SetDlgItemText(IDC_EDIT_PATH, strPathName);
//获取服务器IP和端口 BYTE btye1, btye2, btye3, btye4; m_IPAddr.GetAddress(btye1, btye2, btye3, btye4); char sIP[15]; sprintf(sIP, "%d.%d.%d.%d", btye1, btye2, btye3, btye4);//显示IP地址 int nPort = GetDlgItemInt(IDC_EDIT_PORT); CString strIP(sIP); if (strIP.IsEmpty()) { AfxMessageBox(_T("请输入服务器IP地址!")); return; } if (nPort<0) { AfxMessageBox(_T("请输入服务器端口!")); return; } m_pFtpClient->InitParam(this, sIP, nPort);
//发送文件信息到服务器 MSGPARAM msgParam; msgParam.msgFile.iCommand = FILELIST; msgParam.msgFile.lFileLength = m_lFileSize; msgParam.msgFile.lFileOffset = 0; strcpy(msgParam.msgFile.sFilePath, strPathName); m_pFtpClient->SendRequest(msgParam); }}
void CClient_FTPDlg::OnBtnUpdate() { // TODO: Add your control notification handler code here CString strPathName; GetDlgItemText(IDC_EDIT_PATH, strPathName); //是否有要上传的文件 if (strPathName.IsEmpty()) { AfxMessageBox(_T("请先选择要上传的文件!")); return; } //上传文件 MSGPARAM msgParam; msgParam.msgFile.iCommand = FILEUPDATE; msgParam.msgFile.lFileLength = m_lFileSize; msgParam.msgFile.lFileOffset = 0; strcpy(msgParam.msgFile.sFilePath, strPathName); m_pFtpClient->SendRequest(msgParam);}
void CClient_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 CClient_FTPDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here if(m_pFtpClient != NULL) { m_pFtpClient->StopThread(); delete m_pFtpClient; }}
LRESULT CClient_FTPDlg::OnFileList(WPARAM wp, LPARAM lp){ SOCKET sock = (SOCKET)wp; MSGFILELIST msgFileList; msgFileList.lFileLength = m_lFileSize; strcpy(msgFileList.sFilePath, m_strFilePath.GetBuffer(0)); //发送文件信息 int iSendCnt = send(sock, (char*)&msgFileList, sizeof(msgFileList), 0);
return 0;}
LRESULT CClient_FTPDlg::OnFileUpdate(WPARAM wp, LPARAM lp){ MSGFILESTATUS* pmsg = (MSGFILESTATUS*)wp; int nPos = int((float)pmsg->lFileOffset/m_lFileSize*100); m_Progress.SetPos(nPos); CString strStatus; strStatus.Format("%d%%", nPos); m_LabProgress.SetText(strStatus); if (nPos<100) return 0;
CString strFileSize;//显示文件大小 strFileSize.Format("%0.2fk", (float)m_lFileSize/1024);
int iItem = m_ListFile.GetItemCount();//获取文件列表元素个数 LV_ITEM lvi;//结构体ListView Item,指定或接收属性 lvi.mask = LVIF_TEXT|LVIF_PARAM; lvi.iItem = iItem; lvi.iSubItem = 0; lvi.lParam = m_lFileSize; lvi.pszText = m_strFileName.GetBuffer(0);//返回CString中指向字符串的指针 m_ListFile.InsertItem(&lvi);//插入列表 m_ListFile.SetItemText(iItem, 1, strFileSize.GetBuffer(0)); m_ListFile.SetItemText(iItem, 5, m_strFilePath.GetBuffer(0)); return 0;}
LRESULT CClient_FTPDlg::OnFileDownload(WPARAM wp, LPARAM lp){ MSGFILESTATUS* pmsg = (MSGFILESTATUS*)wp; CString strPath, strName; strPath.Format("%s", pmsg->sFilePath); int iPos = strPath.ReverseFind('//'); strName = strPath.Right(strPath.GetLength() - iPos - 1); int iTotal = m_ListFile.GetItemCount(); int iSel = 0; for(; iSel<iTotal; iSel++) { CString strListPath; strListPath = m_ListFile.GetItemText(iSel, 0); if(strName.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 CClient_FTPDlg::OnConnectError(WPARAM wp, LPARAM lp){ AfxMessageBox(_T("服务器连接失败!")); return 0;}
void CClient_FTPDlg::OnDblclkListFile(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here NMLISTVIEW* pListView = (NMLISTVIEW*)pNMHDR;//结构体,ListView的通知信息 int iSel = pListView->iItem; if(iSel == -1) return; CString strFileName = m_ListFile.GetItemText(iSel, 0); CFileDialog dlg(FALSE, NULL, strFileName.GetBuffer(0), OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "All Files(*.*)|*.*||", this); //打开一个保存对话框,隐藏readonly||覆盖确认 if(dlg.DoModal() != IDOK) return; CString strClientPath = dlg.GetPathName(); //得到客户端保存路径 CFile file; BOOL bOpen = file.Open(strClientPath, CFile::modeCreate|CFile::modeWrite, NULL); if(!bOpen) { MessageBox("文件创建或打开失败,请确认路径再重试!"); return; } file.Close();
MSGPARAM msgParam; msgParam.msgFile.iCommand = FILEDOWNLOAD; msgParam.msgFile.lFileLength = m_ListFile.GetItemData(iSel); msgParam.msgFile.lFileOffset = 0; strcpy(msgParam.msgFile.sFilePath, strClientPath); //子项目,第6列 DWORD dwStartTick = GetTickCount(); char sStartTick[20]; sprintf(sStartTick, "%u", dwStartTick); m_ListFile.SetItemText(iSel, 6, sStartTick); m_pFtpClient->SendRequest(msgParam);//调用请求线程
*pResult = 0;}
新闻热点
疑难解答