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

📄 maindlg.cpp

📁 局域网内聊天传输文件
💻 CPP
字号:
/*
  取之于斯,用之于斯。
  我自己的学习成长,有一大部分要归功于在互联网上接触到的一些开源的代码和开源项目。作者的精湛技艺,尤其是他们博大的胸怀,让我敬仰不已。
  因此我也将自己写的一些代码及工具,只要是比较完整的,不涉及到工作中保密信息的,整理出来。放到网上,希望能对其他人有用。
  你可以自由的拷贝,分发,使用这些代码,最好是能提到它的出处,我保留除此之外的所有权利。由于是非商业性的软件及代码,在使用过程中造成的所有损失,我不承担任何责任。 :)
  我的邮件:pankkk@hotmail.com
  我的名字:潘凯
  欢迎和我交流技术方面的问题。


  我已经发布的一些代码及工具。这些代码及工具我一般发布在vchelp及vccode的论坛上,这两个地方是我常去的地方,只是近来都是潜水,很少发言。:)

1、一个从codeproject下载文章及源码的工具,可以将上面所有的文章及源码都下载到本机,并保留原来的分类信息,去掉页面上的广告。发布日期2003/1
  这个软件是用MFC做的。现在可能已经不能用了,因为当时不用登录也可以下载源码,现在必须要是会员,而且要登录后才能下载。而且网站的组织结构也变了。有兴趣的朋友可以自己试着改源码。

2、一个上网计时的小软件。发布时期2003/11
  这个软件主要也是自用,当时家里办了ADSL上网,一个月60小时。当时下了一些计时软件,感觉不好用,功能太多,就自己写了一个。界面比较简陋,但也够用了。

3、一个点对点的局域网聊天软件,有QQ的Emotion功能,可以一对多的传文件。发布日期2004/12,发布版本1.13。
  界面部分用WTL做的,聊天用UDP协议,传文件是TCP协议。由于不需要服务器,很多功能实现起来还是很麻烦的。

*/

#include "maindlg.h"
#include "main.h"

LRESULT CLoginDlg::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{	//PK 2004-09 - 10-18

	CEdit edit(GetDlgItem(IDC_EDIT_USER));
	char buf[25];
	buf[24] = '\0';
	edit.GetWindowText(buf, 25);
	m_username = buf;

	//PK delete the head and tail space
	size_t pos = m_username.find_first_not_of(' ');
	if (0 != pos) m_username.erase(0, pos);
	pos = m_username.find_last_not_of(' ') + 1;
	if (pos != m_username.length()) m_username.erase(pos, m_username.length() - pos);

	if (CSender::is_name_conflict(m_username) || (m_username.empty())) {
		MessageBox("与已有的用户名重名了,请换一个更帅的名字试试!", "重名");
		return 0;
	}
	else EndDialog(wID);
	return 0;
}
LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{	//PK 2004/09 - 11/01
	CLoginDlg dlg;
	if (IDCANCEL == dlg.DoModal()) {
		PostMessage(WM_CLOSE);
		return FALSE;
	}

	// center the dialog on the screen
	CenterWindow();

	// set icons
	HICON hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
		IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
	SetIcon(hIcon, TRUE);
	HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
		IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
	SetIcon(hIconSmall, FALSE);

	// register object for message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->AddMessageFilter(this);
	pLoop->AddIdleHandler(this);

	UIAddChildWindowContainer(m_hWnd);

	m_List.SubclassWindow(GetDlgItem(IDC_LIST_USER));

	//PK 2004/09/13 - 10/27 initial control
	::RegisterHotKey(m_hWnd, 1001, MOD_ALT | MOD_SHIFT, 'z');
	::RegisterHotKey(m_hWnd, 1002, MOD_ALT | MOD_SHIFT, 'Z');
	SetTimer (1, g_online_interval * 1000);
	CListViewCtrl list(GetDlgItem(IDC_LIST_USER));
	list.SetExtendedListViewStyle(LVS_EX_CHECKBOXES);
	list.InsertColumn(0, "四海之内皆兄弟姐妹", LVCFMT_LEFT, 200, -1);
	list = GetDlgItem(IDC_LIST_BLACKLIST);
	list.SetExtendedListViewStyle(LVS_EX_CHECKBOXES);
	list.InsertColumn(0, "黑名单", LVCFMT_CENTER, 200, -1);
	//PK 2004/09/10 - 10/14 start receive thread
	if (!CSender::start()) {
		PostMessage(WM_CLOSE);
		return FALSE;
	}
	write_title(dlg.m_username);
	start_receive((void*)this);
	CSender::set_myname(dlg.m_username);
	CSender::login();

	return TRUE;
}
LRESULT CMainDlg::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{	//PK 2004/09 - 10/25
	WTL::CEdit edit(GetDlgItem(IDC_EDIT_SEND));
	CEdit edit_recv(GetDlgItem(IDC_EDIT_RECV));
	char buf[VALIDLOAD + 1];
	buf[VALIDLOAD] = '\0';
	this->GetDlgItemText(IDC_EDIT_SEND, buf, VALIDLOAD);
	string str_send = buf;
	edit.SetWindowText("");
	edit.SetFocus();
	CSender::trim_string(str_send);
	if (str_send.empty()) return 0;
	//PK send to all or someone
	int emotion_index = -1;
	u_long user = 0;
	if (CSender::is_emotion_command(str_send, emotion_index, user)) CSender::emotion(emotion_index, user);
	else say(str_send);
	return 0;
}
void CMainDlg::OnDestroy()
{	//PK 2004/09 - 10/27
	UnregisterHotKey(m_hWnd, 1001);
	UnregisterHotKey(m_hWnd, 1002);
	CSender::logout();
	KillTimer(1);
	SetMsgHandled(false);
}
void CMainDlg::OnTimer ( UINT uTimerID, TIMERPROC pTimerProc )
{	//PK 2004/09 - 10/20
	if ( 1 != uTimerID ) {
		SetMsgHandled(false);
		return;
	}
	CSender::update_users();
	CSender::update_tasks();
}
bool CMainDlg::rename()
{	//PK 2004/10/09 - 23
	CLoginDlg dlg;
	if (IDCANCEL == dlg.DoModal(m_hWnd)) return false;
	write_title(dlg.m_username);
	string temp;
	_my_time time;
	temp = "(" + time.get_time() + ")" + g_system_info + " 你已经将名字由 " + CSender::get_myname() +
		" 改名为: " + dlg.m_username;
	CSender::rename(dlg.m_username);
	someone_talk(temp);
	return true;
}
bool CMainDlg::get_sel_users(int id, addresses_type & users)
{	//PK 2004/10/15
	//PK if have selected users return true, and add these users to [users]
	//PK if not, return false, and add all users to [users]
	bool has_sel = false;
	CListViewCtrl list(GetDlgItem(id));
	int user_count = list.GetItemCount();
	for (int i = 0; i < user_count; ++i) {
		if (list.GetCheckState(i)) {
			users.push_back(list.GetItemData(i));
			has_sel = true;
		}
	}
	if (!has_sel)
		for (int i = 0; i < user_count; ++i) users.push_back(list.GetItemData(i));
	return has_sel;
}
LRESULT CMainDlg::OnSendFile(WORD, WORD wID, HWND, BOOL&)
{	//PK 2004/10/15 - 27
	CFileDialog dlg(true);
	if (IDCANCEL == dlg.DoModal()) return 0;
	string fname = dlg.m_szFileName;
	addresses_type users;
	get_sel_users(IDC_LIST_USER, users);
	if (users.empty()) return 0;
	_task_send_file * task = CSender::add_a_send_file_task(fname, users);
	CSender::send_a_file(task);
	return 0;
}
LRESULT CMainDlg::OnRecvFile(UINT, WPARAM wParam, LPARAM lParam, BOOL&)
{	//PK 2004/10/18 - 12/17
	_task_recv_file * task = (_task_recv_file*)wParam;
	u_long task_id = task->task_id;
	u_long addr = (u_long)lParam;
	string temp = CSender::get_user_name(addr) + " 向你发送了文件: " + task->file_name +
		"\n文件大小为: " + number_to_string(task->file_size) +
		"\n你想要接收吗?";
	bool is_recv = (IDYES == MessageBox(temp.c_str(), "收到发送文件请示", MB_YESNO));
	if (!CSender::is_task_exist(task_id)) {
		_my_time now;
		string message;
		message = g_system_info + " (" + now.get_time() + ") 本次文件接收任务因超时已经取消了。如果需要请再向发送方请求!";
		someone_talk(message);
		return 0;
	}
	if (!is_recv) { //PK reject
		CSender::reject_a_file(task);
		return 0;
	}
recv:
	CFolderDialog dlg;
	if (IDOK == dlg.DoModal()){
		string folder = dlg.m_szFolderPath;
		
		unsigned long SecPerClu, BtsPerSec, FreeClu, TolClu;
		if (GetDiskFreeSpace(folder.substr(0,3).c_str(), &SecPerClu, &BtsPerSec, &FreeClu, &TolClu)) {
			if (SecPerClu * BtsPerSec * FreeClu <= task->file_size) {
				MessageBox("没有足够的磁盘空间接收该文件!", MB_OK);
				goto recv;
			}
		}

		int i = folder.find_last_of('\\');
		int j = folder.length();
		if (folder.find_last_of('\\') != folder.length()) folder += '\\';
		task->file_name = folder + task->file_name;
		task->state = _task::recv;
		_beginthreadex(NULL, 0,	CSender::recv_file_thread, (void*)task, 0, 0);
		CSender::confirm_recv_a_file(task);

	} else {
		CSender::reject_a_file(task);
	}
	return 0;
}
void CMainDlg::someone_talk(CRStr content)
{	//PK 2004/09 - 10/20
	CEdit edit(GetDlgItem(IDC_EDIT_RECV));
	if (edit.GetWindowTextLength() + content.length() > edit.GetLimitText()) {
		edit.SetSel(0, BUFSIZE * 2);
		edit.ReplaceSel("");
	}
	string message = string("\r\n") + content + "\r\n";
	CSender::m_history << message;
	edit.AppendText(message.c_str());
}

void CMainDlg::say(CRStr msg)
{	//PK 2004/10/22 - 27
	string message;
	_my_time time;
	addresses_type users;
	bool send_to_all = !get_sel_users(IDC_LIST_USER, users);
	if (!send_to_all) { 
		addresses_type::iterator pos = users.begin();
		addresses_type::iterator end = users.end();
		for (; pos != end; ++pos) CSender::whisper(msg, *pos);
		message = "(" + time.get_time() + ") " + CSender::get_myname() +
			" 悄悄的说 :\r\n    " + msg;
		someone_talk(message);
	} else {
		CSender::said_to_all(msg.c_str());
//		message = "(" + time.get_time() + ") " + CSender::get_myname() +
//			" 说 :\r\n    " + msg;
	}
	
}
LRESULT CMainDlg::OnDBList(UINT wParam, CPoint point)
{	//PK 2004/10/22
	CListViewCtrl list(GetDlgItem(IDC_LIST_USER));
	int index = list.HitTest(point, NULL);
	if (-1 == index) return 0;
	char buf[26];
	buf[25] = '\0';
	list.GetItemText(index, 0, buf, 26);
	CEdit edit(GetDlgItem(IDC_EDIT_SEND));
	string temp = buf;
	buf[temp.find_last_of('[')] = '\0';
	edit.AppendText(buf);
	return 0;
}
LRESULT CMainDlg::OnBlacklist(WORD, WORD wID, HWND, BOOL&)
{	//PK 2004/10/26 - 27
	addresses_type add_users, remove_users;
	addresses_type::iterator apos, aend, rpos, rend;
	bool add = get_sel_users(IDC_LIST_USER, add_users);
	if (!add) add_users.clear();
	bool remove = get_sel_users(IDC_LIST_BLACKLIST, remove_users);
	if (!remove) remove_users.clear();
	if (add && remove) { //PK if there are same users in the adds and removes, delete it 
		for (apos = add_users.begin(); apos != add_users.end();) {
			bool need_del = false;
			for (rpos = remove_users.begin(); rpos != remove_users.end(); ++rpos) {
				if (*apos == *rpos) {
					remove_users.erase(rpos);
					need_del = true;
					break;
				}
			}
			if (need_del) apos = add_users.erase(apos);
			else ++apos;
		}
	}
	if (!add_users.empty()) //PK add users to blacklist
		for (apos = add_users.begin(); apos != add_users.end(); ++apos) {
			add_user_to_list(IDC_LIST_BLACKLIST, *apos);
			CSender::modify_blacklist(*apos);
		}
	if (!remove_users.empty()) //PK remove users from blacklist
		for (rpos = remove_users.begin(); rpos != remove_users.end(); ++rpos) {
			remove_user_from_list(IDC_LIST_BLACKLIST, *rpos);
			CSender::modify_blacklist(*rpos);
		}
	remove_all_sel(IDC_LIST_USER);
	remove_all_sel(IDC_LIST_BLACKLIST);
	return 0;
}
bool CMainDlg::add_user_to_list(int id, u_long addr)
{	//PK 2004/10/27
	CListViewCtrl list(GetDlgItem(id));
	int index = list.InsertItem(65535, CSender::get_full_name(addr).c_str());
	list.SetItemData(index, (DWORD)addr);
	return true;
}
bool CMainDlg::remove_user_from_list(int id, u_long addr)
{	//PK 2004/10/27
	CListViewCtrl list(GetDlgItem(id));
	for ( int index = 0; index < list.GetItemCount(); ++ index)
		if (list.GetItemData(index) == addr) list.DeleteItem(index);
	return true;
}
bool CMainDlg::remove_all_sel(int id)
{	//PK 2004/10/27
	CListViewCtrl list(GetDlgItem(id));
	for ( int index = 0; index < list.GetItemCount(); ++ index)
		list.SetCheckState(index, false);
	return true;
}

⌨️ 快捷键说明

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