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

📄 lancommuniondlg.cpp

📁 局域网实现聊天,并传输文件,功能较齐全,可添加用户!欢迎大家下载!
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	if(!Shell_NotifyIcon(NIM_DELETE,&m_nid))
	{
		MessageBox("删除托盘失败。");
//		return;
	}

	CDialog::OnClose();
}

//初始化广播上线消息用套接字。
void CLANCommunionDlg::InitBSocket()
{
	//Init	m_sockBSend;
	int				err;
	m_sockBSend=socket(AF_INET,SOCK_DGRAM,0);
	if(	INVALID_SOCKET ==m_sockBSend	)
	{
		MessageBox("创建广播套接字失败。");
		exit(	0	);
	}

	bool	bbroadcast=true;
	err=setsockopt(m_sockBSend,SOL_SOCKET,SO_BROADCAST,(char*)&bbroadcast,sizeof(bool));
	if(SOCKET_ERROR ==err)
	{
		MessageBox("设置广播属性失败。");
		closesocket(m_sockBSend);
		exit(	0	);
	}

	sockaddr_in		addrSrv;
	addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(	SENDPORT	);

	err=bind(m_sockBSend,(sockaddr*)&addrSrv,sizeof(sockaddr));
	if(SOCKET_ERROR==err)
	{
		MessageBox("广播套接字绑定失败。");
		closesocket(m_sockBSend);
		exit(	0	);
	}

	//Init	m_sockBRecv;

	m_sockBRecv=socket(AF_INET,SOCK_DGRAM,0);
	if(	INVALID_SOCKET ==m_sockBSend	)
	{
		MessageBox("创建接收套接字失败。");
		exit(	0	);
	}

	sockaddr_in		addrRecv;
	addrRecv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	addrRecv.sin_family=AF_INET;
	addrRecv.sin_port=htons(	RECVPORT	);

	err=bind(m_sockBRecv,(sockaddr*)&addrRecv,sizeof(sockaddr));
	if(SOCKET_ERROR==err)
	{
		MessageBox("接收套接字绑定失败。");
		closesocket(m_sockBSend);
		exit(	0	);
	}
	BROADCAST*	p=new	BROADCAST;
	p->pCLAN=this;
	p->sock=m_sockBRecv;
	AfxBeginThread(ReceiveBroadcast,(LPVOID)p);

}
void CLANCommunionDlg::FlushListBox()		
{
	m_list.DeleteAllItems(	);//清空在线用户列表
	
	BroadCastHello(	);//请求在线用户返回在线确认消息。
}

void CLANCommunionDlg::BroadCastHello()		
{	//发请求返回在线确认消息,以获得在线用户信息。
	sockaddr_in		addrTo;
	addrTo.sin_addr.S_un.S_addr=htonl(INADDR_BROADCAST);
	addrTo.sin_family=AF_INET;
	addrTo.sin_port=htons(	RECVPORT	);
	
	//获取主机名
	char	phost[200];
	char	temp[400];
	memset(phost,0,200);
	memset(temp,0,400);
	if(	0==gethostname(phost,200)	);
	else	strcpy(phost,"Anony");
	
	strcpy(temp,"\t\t\t\t");//指定报头为请求返回在线确认消息。
	strcat(temp,phost);
	
	//向本子网内请求返回在线确认消息。
	int	err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
	if(SOCKET_ERROR==err)
	{
//		MessageBox("广播发送数据失败。");
		return;
	}
	err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
	if(SOCKET_ERROR==err)
	{
//		MessageBox("广播发送数据失败。");
		return;
	}

	//向用户添加的不同子网用户请求返回在线确认消息。
	int		i,count;
	count=m_userInfo.GetSize(	);
	for(i=0;i<count;i++)		//检测用户添加的不在同一子网内的用户是否在线。
	{
		addrTo.sin_addr.S_un.S_addr=inet_addr(	((CUserInfo*)m_userInfo.GetAt(i))->m_ip	);
		err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
		if(SOCKET_ERROR==err)
		{
//			MessageBox("发送确认新添加用户是否在线请求失败。"+GetError(GetLastError()));
			continue;
		}
		err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
		if(SOCKET_ERROR==err)
		{
//			MessageBox("发送确认新添加用户是否在线请求失败。"+GetError(GetLastError()));
			continue;
		}
	}
}
void CLANCommunionDlg::BroadCastExit()		//发送广播消息,通知其它主机我下线了。
{
	sockaddr_in		addrTo;
	addrTo.sin_addr.S_un.S_addr=htonl(INADDR_BROADCAST);
	addrTo.sin_family=AF_INET;
	addrTo.sin_port=htons(	RECVPORT	);

	int		err;
	char	phost[200];
	char	temp[400];
	memset(phost,0,200);
	memset(temp,0,400);
	if(	0==gethostname(phost,200)	);
	else	strcpy(phost,"Anony");
	sprintf(temp,"EXIT");
	strcat(temp,phost);

	err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
	if(SOCKET_ERROR==err)
	{
//		MessageBox("广播发送数据失败。");
		return;
	}
	err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
	if(SOCKET_ERROR==err)
	{
//		MessageBox("广播发送数据失败。");
		return;
	}

	//向不在同一子网的用户发送下线通知消息。
	int		i,count;
	count=m_userInfo.GetSize(	);
	for(i=0;i<count;i++)		
	{
		addrTo.sin_addr.S_un.S_addr=inet_addr(	((CUserInfo*)m_userInfo.GetAt(i))->m_ip	);
		err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
		if(SOCKET_ERROR==err)
		{
//			MessageBox("向不在同一子网的用户发送下线通知消息失败。"+GetError(GetLastError()));
			continue;
		}
		err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrTo,sizeof(sockaddr));
		if(SOCKET_ERROR==err)
		{
//			MessageBox("向不在同一子网的用户发送下线通知消息失败。"+GetError(GetLastError()));
			continue;
		}
	}
}

void CLANCommunionDlg::OnAddUser() 
{
	// TODO: Add your command handler code here
	CAddUserDlg		dlg;
	
	if(IDOK==dlg.DoModal())
	{
//		bool			bExist=false;
		int				nCount;
		CUserInfo*		p;
		p=new		CUserInfo();
		p->m_ip=dlg.m_strAddr;
		
		nCount=m_userInfo.GetSize(	);
		for(int	i=0;i<nCount;i++)
		{
			if(	(	(CUserInfo*)m_userInfo.GetAt(i)	)->m_ip==p->m_ip	)
			{
				MessageBox("此用户已添加过了。");
				return	;
			}
		}
		//添加用户信息。
		m_userInfo.Add(p);
		//发送消息到新加的用户请求返回信息。
		sockaddr_in		addrDest;
		addrDest.sin_addr.S_un.S_addr=inet_addr(dlg.m_strAddr);
		addrDest.sin_family=AF_INET;
		addrDest.sin_port=htons(RECVPORT);

		
		//获取主机名
		char	phost[200];
		char	temp[400];
		memset(phost,0,200);
		memset(temp,0,400);
		if(	0==gethostname(phost,200)	);
		else	strcpy(phost,"Anony");

		strcpy(temp,"\t\t\t\t");//指定报头为确认新添加用户是否在线。
		strcat(temp,phost);
		

		int	err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrDest,sizeof(sockaddr));
		if(SOCKET_ERROR==err)
		{
//			MessageBox("广播发送数据失败。");
			return;
		}
		err=sendto(m_sockBSend,temp,strlen(temp)+1,0,(sockaddr*)&addrDest,sizeof(sockaddr));
		if(SOCKET_ERROR==err)
		{
//			MessageBox("发送确认新添加用户是否在线请求失败。"+GetError(GetLastError()));
			return;
		}
	}
}

void CLANCommunionDlg::OnUsage() 
{
	// TODO: Add your command handler code here
	CUseageDlg		dlg;
	dlg.DoModal(	);
}

void CLANCommunionDlg::OnDropFiles(HDROP	hDropInfo)
{
	CString		ip;
	if(!GetIPAddr(ip))
	{
		return	;
	}
	
	UINT	nCount;
	int		nIndex,nCount2,nCount3;
	nCount=DragQueryFile(hDropInfo,0xFFFFFFFF,NULL,0);
	CString		strDirectory,strName;
	CFileFind	find;
	char		FileName[NAMELENGTH];
	
	for(UINT	i=0;i<nCount&&i<NAMELENGTH;i++)
	{
		memset(FileName,0,NAMELENGTH);
		DragQueryFile(hDropInfo,i,FileName,NAMELENGTH);
	
		if(FILE_ATTRIBUTE_DIRECTORY&::GetFileAttributes(FileName))
		{
			strDirectory.Format("%s\t为文件夹,本程序不支持文件夹的传输。",FileName);
			MessageBox(strDirectory);
			continue;
			
		}
		else
		{
			SENDFILEPARAM*	p=new	SENDFILEPARAM;
			p->pathName.Format("%s",FileName);
			nIndex=p->pathName.ReverseFind('\\');
			nCount2=p->pathName.GetLength();
			strName=p->pathName.Right(nCount2-(nIndex+1));
			memset(p->fileName,0,NAMELENGTH);
			nCount3=strName.GetLength(	);
			for(int	i=0;i<nCount3&&i<NAMELENGTH;i++)
			{
				p->fileName[i]=strName.GetAt(i);
			}
			p->pCLAN=(this);
			p->ip=ip;
			//发送文件。
			::AfxBeginThread(SendFileSingle,(LPVOID)p);
		}
		
	}
}

void CLANCommunionDlg::OnBtnFlush() 
{
	// TODO: Add your control notification handler code here
	FlushListBox(	);
}


void CLANCommunionDlg::SaveUserInfo()
{
	CFile	file(USERINFOPATH,
				CFile::modeCreate |CFile::modeReadWrite|CFile::typeBinary );
	CArchive	ar(&file,CArchive::store);
	
	int	size=m_userInfo.GetSize(	);
	ar<<size;
	int		i;
	for(i=0;i<size;i++)
		ar<<m_userInfo.GetAt(i);
	//释放分配给	m_userInfo	的资源。
	CUserInfo*	p;
	for(i=0;i<size;i++)
	{
		p=(CUserInfo*)m_userInfo.GetAt(i);
		delete	p;
	}
	m_userInfo.RemoveAll(	);

}

void CLANCommunionDlg::ReadUserInfo()
{
	CFileFind	ff;
	CString	s=USERINFOPATH;
	if(!ff.FindFile(USERINFOPATH))   //若该用户信息文件不存在,则直接返回不再读文件.
	{
//		MessageBox("can not find the file\t\"userinfo.dat\"	");
		return;
	}
	
	///////////////////////////////////////////////
	CUserInfo*	p;
	int			size;
	CFile	file(USERINFOPATH,CFile::modeRead |CFile::typeBinary );
	CArchive	ar(&file,CArchive::load );
	ar>>size;
	for(int	i=0;i<size;i++)
	{
		ar>>p;
		m_userInfo.Add(p);
	}
}

void CLANCommunionDlg::OnMaxtextEditReceive() 
{
	// TODO: Add your control notification handler code here
	SetDlgItemText(IDC_EDIT_RECEIVE,"");
}

void CLANCommunionDlg::OnMaxtextEditSandchat() 
{
	// TODO: Add your control notification handler code here
	SetDlgItemText(IDC_EDIT_SANDCHAT,"");
}

HBRUSH CLANCommunionDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	
	// TODO: Return a different brush if the default is not desired
	return hbr;
}

bool CLANCommunionDlg::GetIPAddr(CString&	s)
{
	////////////////////////////////////////////////
	//获取目的主机IP地址。
	
	bool	bChoosed=false;
	int		nListIndex=-1;
	int		nListCount=this->m_list.GetItemCount();
	for(int	i=0; i<nListCount; i++)
	{
		if( this->m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
		{
			bChoosed=true;		//有已经选择的项。
			nListIndex=i;		//已经选择的项序号。
			break;
		}
	}
	if(!bChoosed)		//用户还没有选择。
	{
		AfxMessageBox("你还没有选择发送的目的用户呢,请选择后再重新发送。");
		return	false;
	}	
	s=this->m_list.GetItemText(nListIndex,1);
	return	true;
	////////////////////////////////////////////////
}

void CLANCommunionDlg::OnNotifyIcon(WPARAM	wParam,LPARAM	lParam)
{
	static	bool	bShowHide=false;

	if(wParam!=IDR_MAINFRAME) 
		return;
	switch(	lParam	)
	{
	case	WM_LBUTTONDOWN:
		{
			if(!bShowHide)
			{
				Invalidate(	);
				ShowWindow(SW_SHOWNORMAL );
				this->SetActiveWindow(	);
				this->SetFocus(	);
				this->SetWindowPos(&CWnd::wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
				UpdateWindow(	);
				bShowHide=true;
			}
			else
			{
				ShowWindow(SW_HIDE);
				bShowHide=false;
			}
			break;
		}
	case	WM_RBUTTONUP:
		{
			LPPOINT		lpPoint=new		POINT;
			::GetCursorPos(lpPoint);
			if(!m_menu.m_hMenu)
				m_menu.LoadMenu(IDR_POPUP_MENU);
			this->SetForegroundWindow(	);
			m_menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN ,lpPoint->x,lpPoint->y,this);	
		}
	default:
		return;
	}
	
}

void CLANCommunionDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	if(SIZE_MINIMIZED==nType)//点击最小化菜单。
	{
		ShowWindow(SW_HIDE);
	}
}

void CLANCommunionDlg::OnPopupQuit() 
{
	// TODO: Add your command handler code here
	OnButtonQuit() ;
}

void CLANCommunionDlg::OnPopupAdduser() 
{
	// TODO: Add your command handler code here
	OnAddUser();
}

void CLANCommunionDlg::OnPopupAbout() 
{
	// TODO: Add your command handler code here
	OnUsage();
}

void CLANCommunionDlg::OnCreateTransportInfoDlg(WPARAM	wParam,LPARAM	lParam	)
{
	CTransportInfoDlg*	p=(CTransportInfoDlg*)wParam;
	p->Create(IDD_TRANSPORTINFO_DLG,this);
	p->ShowWindow(SW_SHOW);	
}

void CLANCommunionDlg::OnDeleteDlg(WPARAM	wParam,LPARAM	lParam	)
{
	CTransportInfoDlg*	p=(CTransportInfoDlg*)wParam;
	
	p->DestroyWindow(	);
	p=NULL;
	
	

}

⌨️ 快捷键说明

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