⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendfiledlg.cpp

📁 icpq的开发技术类书籍
💻 CPP
字号:
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   copyright            : (C) 2002 by Zhang Yong                         *
 *   email                : z-yong163@163.com                              *
 ***************************************************************************/

// SendFileDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SendFile.h"
#include "SendFileDlg.h"
#include "icqlinkbase.h"
#include "contactinfo.h"

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

#define IDT_BROWSE_FILE		1001
#define IDT_ANIM			1002

static CSendFileDlg *pSendFileDlg;

static VOID CALLBACK onTimer(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
	KillTimer(hwnd, idEvent);

	pSendFileDlg->destroy();
}

/////////////////////////////////////////////////////////////////////////////
// CSendFileDlg dialog

CSendFileDlg::CSendFileDlg(TcpSessionBase *tcp, CWnd* pParent /*=NULL*/)
: CDialog(CSendFileDlg::IDD, pParent), FileSession(tcp)
{
	//{{AFX_DATA_INIT(CSendFileDlg)
	//}}AFX_DATA_INIT

	bytesSent = 0;
	lastBytes = 0;
	lastTime = 0;
	frame = 0;

	//TcpSessionBase* tcp 基本上这个tcp作用是很大的
	isSend = tcp->isSendSession();
	icqLink = tcp->getLink();

	QID qid;
	tcp->getRemoteQID(qid);
	contact = icqLink->getContactInfo(&qid);

	m_uin.Format("%lu", qid.uin);
	m_nick = contact->nick.c_str();
}

CSendFileDlg::~CSendFileDlg()
{
}


//这个回导致,窗口的自删除
void CSendFileDlg::destroy()
{
	tcp->destroy();

	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	DestroyWindow();
}

//这个竟然是个虚拟函数,
//好像是如果要是 还是如果把虚拟函数看成接口的好理解写
//再本地创建的文件路径
const char *CSendFileDlg::getPathName(const char *name, uint32 size)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	fileName = name;
	fileSize = size;

	CString str; //默认了只回在 接受出现
	str.Format(IDS_FILESIZE, fileSize);
	SetDlgItemText(IDC_FILESIZE, str);
	
	str.LoadString(IDS_RECEIVING_FILE);
	SetDlgItemText(IDC_STATUS, str);

	CFileDialog dlg(FALSE, NULL, fileName,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "*.*|*.*||", this);
	
	if (dlg.DoModal() != IDOK)
		return NULL;

	pathName = dlg.GetPathName();
	str.Format(IDS_TITLE_RECVFILE, (LPCTSTR) pathName);
	SetWindowText(str);

	//The member function SetRange32 sets the 32-bit range for the progress control. 
	//下面的一点和这一条语句告知我们不用考虑进度条的粒度太细致
	m_ctlProgress.SetRange32(0, fileSize); //
	                                //这个SetRange32会在接受和发送分别调用
	                               //

	return pathName;
}

//虚函数
void CSendFileDlg::onFileReceive()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	CString str;
	str.LoadString(IDS_SENDING_FILE);
	SetDlgItemText(IDC_STATUS, str);
}


//虚函数
void CSendFileDlg::onFileProgress(uint32 bytes)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	
	DWORD thisTime = GetTickCount();
	
	if (bytesSent == 0) {
	
		lastBytes = 0;
		lastTime = thisTime;
		
		CString str;
		str.LoadString(isSend ? IDS_SENDING_FILE : IDS_RECEIVING_FILE);
		SetDlgItemText(IDC_STATUS, str);
	}
	
	bytesSent = bytes;
	m_ctlProgress.SetPos(bytesSent); //在这里他是没有理会什么东西,最小
	                         //什么的,看来我们在外部调用有时确实不需要想那么多
	                      //如果他本身提供的话

	CString str;
	int percent = (int) (bytesSent * 100.0f / fileSize);
	str.Format(isSend ? IDS_SENDFILE_BYTES : IDS_RECVFILE_BYTES,
		bytesSent, percent);
	SetDlgItemText(IDC_STATUS_DETAIL, str);


	//计算网络速度的一个范例
	if (thisTime - lastTime >= 500) { //定的一个段,看之补缺
	
		//他们之间还有单位上的统一
		float speed = (float) (bytesSent - lastBytes) / (thisTime - lastTime) / 1.024f;
		lastTime = thisTime;
		lastBytes = bytesSent; //关于统计点的选者的一个

		str.Format("%.1fKB/S", speed);
		SetDlgItemText(IDC_SPEED, str);
	}
}


//virtual void onFileFinished () 他这里和本身的destroy()怎么配合
//也可引起自删除
void CSendFileDlg::onFileFinished()
{
	tcp->destroy();

	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	promptFileFinished();
	DestroyWindow();
}


//关于功能的分配,也是一个值得学习的地方
//也可引起自删除
void CSendFileDlg::onClose(bool prompt)
{
	FileSession::onClose(prompt); //基类这个仅是关闭

	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if (prompt)
		promptFileFinished();

	DestroyWindow();
}


//
void CSendFileDlg::promptFileFinished()
{
	CString text, title;
	if (bytesSent == fileSize) {
		
		title.LoadString(IDS_FINISHED);
		text.LoadString(isSend ? IDS_SUCCESS_SENDFILE : IDS_SUCCESS_RECVFILE);
	} else {
		title.LoadString(IDS_FAILED);
		text.LoadString(IDS_ERROR_SENDFILE);
	}
	
	MessageBox(text, title);
}

//
void CSendFileDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSendFileDlg)
	DDX_Control(pDX, IDC_FACE, m_faceStatic);
	DDX_Control(pDX, IDC_PROGRESS, m_ctlProgress);
	DDX_Text(pDX, IDC_UIN, m_uin);
	DDX_Text(pDX, IDC_NICK, m_nick);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CSendFileDlg, CDialog)
	//{{AFX_MSG_MAP(CSendFileDlg)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSendFileDlg message handlers

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

	CString str;
	if (isSend)
		SetTimer(IDT_BROWSE_FILE, 0, NULL); //这里使用时间函数来作一些东西也算技巧
	else {
		
		str.LoadString(IDS_ACCEPT_FILE);
		SetWindowText(str);
	}

	str.LoadString(IDS_PLEASE_WAIT);
	SetDlgItemText(IDC_STATUS, str);

	HICON icon = AfxGetApp()->LoadIcon(IDI_SENDFILE);
	SetIcon(icon, TRUE);
	SetIcon(icon, FALSE);

   //多看几遍,至少从外边把握的 能力要强一点,如果第一次不能丛整体上
	//把握架构的话
	m_faceStatic.SetIcon((HICON) icqLink->getFaceIcon(contact->face, STATUS_ONLINE));

	SetTimer(IDT_ANIM, 500, NULL);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}


//
void CSendFileDlg::OnTimer(UINT nIDEvent) 
{
	if (nIDEvent == IDT_BROWSE_FILE) {
	
		KillTimer(nIDEvent);	// one shot trigger

		CFileDialog dlg(TRUE, NULL, NULL,
			OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "*.*|*.*||", this);
		
		if (dlg.DoModal() != IDOK) {
			//static CSendFileDlg* pSendFileDlg
			pSendFileDlg = this;
			::SetTimer(NULL, 0, 0, onTimer); //这个实现自删除  	pSendFileDlg->destroy();
			return;
		}

		//迅速开启和关闭
		pathName = dlg.GetPathName();
		fileName = dlg.GetFileName();
		CFile file(pathName, CFile::modeRead);
		fileSize = file.GetLength();
		m_ctlProgress.SetRange32(0, fileSize);
		file.Close();
        //



		CString str;
		str.Format(IDS_TITLE_SENDFILE, (LPCTSTR) pathName);
		SetWindowText(str);
		str.Format(IDS_FILESIZE, fileSize);  //%lu  对于32位的
		SetDlgItemText(IDC_FILESIZE, str);

		sendFileInfo(pathName, fileName, fileSize);

	} else if (nIDEvent == IDT_ANIM) {
	
		//通过这个不断的切换图表的frame^=1  int frame
		frame ^= 1;
		m_faceStatic.SetIcon(
			(HICON) icqLink->getFaceIcon(contact->face, frame ? STATUS_AWAY : STATUS_ONLINE));

	} else
		CDialog::OnTimer(nIDEvent);
}

//他这里 OnCancel还实现不了删除自己
void CSendFileDlg::OnCancel() 
{
	CString title, text;
	title.LoadString(IDS_WARNING);
	text.LoadString(IDS_PROMPT_STOP);

	if (MessageBox(text, title, MB_YESNO) == IDYES) {
		pSendFileDlg = this;
		
		::SetTimer(NULL, 0, 0, onTimer);//再这里引起自删除
	}
}

void CSendFileDlg::PostNcDestroy() 
{
	delete this;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -