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

📄 clientdlg.cpp

📁 WInsock32的客户端哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (userInfo.m_eStatus == CUserInfo::ONLINE)	//在线状态
		{
			lvItem.iImage = CUserInfo::ONLINE;
		}else										
		{
			lvItem.iImage = CUserInfo::OFFLINE;			//离线状态	
		}		
		lvItem.lParam = (LPARAM)userInfo.m_strName.GetBuffer(10);

		m_ctlUserList.InsertItem(&lvItem);				//添加数据项

		userInfo.m_strName.ReleaseBuffer();		
		nIndex++;		
	}	
}


/*
 * 显示离线消息
 */
void CClientDlg::ShowOfflineMsg(CChatPacket *pPacket)
{
	CChatDlg chatDlg(this, pPacket);//创建显示离线消息对话框
	chatDlg.DoModal();	
	SaveChatLog(&chatDlg);			//保存聊天记录
}


/*
 * 发送数据
 */
void  CClientDlg::SendPacket(CChatPacket &packet)
{
	m_pArchiveOut = new CArchive(m_pFile,CArchive::store);	//初始化写入流	
	
	if (NULL != m_pArchiveOut)
	{
		TRY
		{
			packet.Serialize(*m_pArchiveOut);
			m_pArchiveOut->Flush();
		}
		CATCH(CFileException, e)
		{
			m_pArchiveOut->Abort();
			delete m_pArchiveOut;
			m_pArchiveOut = NULL;
			MessageBox(_T("发送数据包错误"));	
		}
		END_CATCH
	}
	
	if (NULL != m_pArchiveOut)
	{
		delete m_pArchiveOut;
		m_pArchiveOut = NULL;
	}
	
}		


void CClientDlg::CreateUserList(CObList *pObList)
{
	POSITION pos = NULL;
	CUserInfo *pUserInfo = NULL;

	//删除原来链表
	for (pos = m_UserList.GetHeadPosition(); NULL != pos;)
	{
		pUserInfo = (CUserInfo*)m_UserList.GetNext(pos);
		delete pUserInfo;
		pUserInfo = NULL;
	}
	m_UserList.RemoveAll();

	//复制链表
	CUserInfo *pNewUserInfo = NULL;
	for (pos = pObList->GetHeadPosition(); NULL != pos;)
	{
		pUserInfo = (CUserInfo*)pObList->GetNext(pos);
		pNewUserInfo= new CUserInfo();
		pNewUserInfo->m_strName = pUserInfo->m_strName;	//名称
		pNewUserInfo->m_eStatus = pUserInfo->m_eStatus;	//状态
		pNewUserInfo->m_lIP = pUserInfo->m_lIP;			//地址
		pNewUserInfo->m_nPort = pUserInfo->m_nPort;		//端口
		m_UserList.AddTail(pNewUserInfo);				//加入链表
		delete pUserInfo;
		pUserInfo = NULL;
	}
	
	pObList->RemoveAll();
}

/*
 * 双击列表视图控件消息消息响应函数
 */
void CClientDlg::OnDblclkClientList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	if(pNMListView->iItem != -1)
	{
		int nSelectItem = pNMListView->iItem;
		CString strPeerName = m_ctlUserList.GetItemText(nSelectItem, 0);
		CreateChatDlg(strPeerName);
	}
	*pResult = 0;
}


/*
 * 创建聊天窗口
 */
void CClientDlg::CreateChatDlg( CString strPeerName )
{
	//不给自己发送消息
	if (strPeerName == m_UserInfo.m_strName)
		return;

	//在用户链表中找到该用户
	CUserInfo *pPeerInfo = NULL;
	POSITION pos = NULL;
	BOOL bFinder = FALSE;
	for (pos = m_UserList.GetHeadPosition(); NULL != pos; )
	{
		pPeerInfo = (CUserInfo*)m_UserList.GetNext(pos);
		if (pPeerInfo->m_strName == strPeerName)
		{
			bFinder = TRUE;
			break;
		}
	}

	ASSERT(TRUE == bFinder);//找到该用户
	if (pPeerInfo->m_eStatus == CUserInfo::ONLINE)		//用户在线
	{
		CChatDlg chatDlg(this, *pPeerInfo, m_UserInfo);	//定义对话框
		if (chatDlg.ConnectToPeer())					//连接对方
		{		
			chatDlg.DoModal();//显示聊天窗口
			//保存聊天记录
			SaveChatLog(&chatDlg);
		}
	}else//发送离线消息
	{
		CChatDlg chatDlg(this, *pPeerInfo, m_UserInfo);//定义对话框
		chatDlg.DoModal();//显示聊天窗口
		
		//离线数据包
		CChatPacket packet;
		packet.m_type = CChatPacket::MESSAGE;	//类型
		packet.m_UserInfo = m_UserInfo;			//发送离线消息的用户信息
		packet.m_OfflineUserInfo = *pPeerInfo;	//接收离线消息的用户信息
		packet.m_strMsg = chatDlg.m_strRec;		//离线消息
		packet.m_time = CTime::GetCurrentTime();//发送消息的时间

		//发送离线数据包
		SendPacket(packet);	
		//保存聊天记录
		SaveChatLog(&chatDlg);
	}	
}

/*
 * 开始监听
 */
BOOL CClientDlg::BegingListen( void )
{
	m_pListenSocket = new CListenSocket(this);	//创建监听对象
	if (m_pListenSocket->Create())				//创建绑定套接字
	{
		if (!m_pListenSocket->Listen())			//开始监听
		{
			delete m_pListenSocket;
			m_pListenSocket = NULL;
			AfxMessageBox(_T("创建套接字失败!"));
			return FALSE;			
		}
	}
	//获取地址信息
	SOCKADDR_IN hostAddr;
	int hostAddrLen = sizeof(SOCKADDR_IN);
	m_pListenSocket->GetSockName((SOCKADDR*)&hostAddr,&hostAddrLen);

	m_hostAddr.sin_port = hostAddr.sin_port;//保存监听端口
	return TRUE;
}

/*
 *接受对方的连接
 */
void CClientDlg::ProcessPendingAccept(void)
{
	CChatDlg	chatDlg(this);	//聊天对话框
	chatDlg.InitSocket();		//创建CChatSocket对象

	//接受对方连接
	CChatSocket *pChatSocket = chatDlg.GetChatSocket();
	SOCKADDR_IN	peerAddr;
	int socketLen = sizeof(SOCKADDR_IN);
 	m_pListenSocket->Accept(*pChatSocket,(SOCKADDR*)&peerAddr, &socketLen);

	//在用户链表中查找该用户
	POSITION	pos;
	CUserInfo	*pPeerInfo = NULL;
	BOOL		bFinder = FALSE;
	for (pos = m_UserList.GetHeadPosition(); NULL != pos;)
	{
		pPeerInfo = (CUserInfo*)m_UserList.GetNext(pos);
		if (pPeerInfo->m_lIP == peerAddr.sin_addr.S_un.S_addr &&//找到该用户
			pPeerInfo->m_eStatus == CUserInfo::ONLINE)				
		{
			bFinder = TRUE;
			break;
		}
	}

	ASSERT(TRUE == bFinder);

	//获取对方信息
	CUserInfo peerInfo;
	peerInfo.m_strName = pPeerInfo->m_strName;		//名字
	peerInfo.m_eStatus = pPeerInfo->m_eStatus;		//状态
	peerInfo.m_lIP = peerAddr.sin_addr.S_un.S_addr;	//地址
	peerInfo.m_nPort = peerAddr.sin_port;			//端口


	chatDlg.SetPeerInfor(peerInfo);					//设置对方信息	
	chatDlg.SetUserInfor(m_UserInfo);				//设置用户信息
	chatDlg.InitArchive();							//设置套接字读入文档

	//打开聊天对话框
	chatDlg.DoModal();	
	//保存聊天记录
	SaveChatLog(&chatDlg);	
}



/*
 * 初始化列表视图控件
 */
BOOL CClientDlg::InitListCtrlSetting( void )
{
	//创建图标列表
	m_pImageList = new CImageList();
	
	//32*32,8位,初始化为2个图标,每次增长2个图标
	m_pImageList->Create(32, 32, ILC_COLOR8|ILC_MASK, 2, 2);
	CWinApp* pApp = AfxGetApp();								//获得应用程序指针
	HICON hIconOnline = pApp->LoadIcon(IDI_CHATTER_ONLINE);		//在线图标
	HICON hIconOffline = pApp->LoadIcon(IDI_CHATTER_OFFLINE);	//离线图标

	m_pImageList->Add(hIconOnline);								//加入图标
	m_pImageList->Add(hIconOffline);							//加入图标
	
	//将图标列表赋值给列表控件
	m_ctlUserList.SetImageList(m_pImageList, LVSIL_SMALL);
	
	//设置列表头
	m_ctlUserList.InsertColumn(0,_T("Chatter"),LVCFMT_IMAGE|LVCFMT_LEFT);

	//设置第一列的宽度为这个列表控件的宽度
	CRect rect;
	m_ctlUserList.GetClientRect(&rect);
	m_ctlUserList.SetColumnWidth(0,rect.Width());

	return TRUE;
	
}

/*
 * 保存聊天记录
 */
void CClientDlg::SaveChatLog(CChatDlg *pChatDlg)
{
	//没有聊天消息
	if (pChatDlg->m_strRec.IsEmpty())
		return;
	
	//保存聊天记录
	char appPath[256];
	GetCurrentDirectory(256,appPath);	//取得应用程序当前路径
	CString  filePath;					//文件名
	filePath.Format("%s",appPath);
	filePath +="\\";
	filePath += CHATLOG;
	
	TRY
	{
		CFile file;
		if (!file.Open(filePath, CFile::modeReadWrite))					//文件已经存在
		{
			file.Open(filePath, CFile::modeCreate|CFile::modeReadWrite);//新建文件			
			
		}else
		{
			file.SeekToEnd();//移动文件指针到文件尾部
		}
		
		int nRecLen = pChatDlg->m_strRec.GetLength();	//聊天记录长度			
		file.Write(pChatDlg->m_strRec, nRecLen);		//写入数据
		file.Flush();
		file.Close();									//关闭文件 		
	}
	CATCH(CFileException, e)
	{
		MessageBox(_T("保存聊天记录异常"),MB_OK, -1);
	}
	END_CATCH	
}

⌨️ 快捷键说明

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