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

📄 userdlg.cpp

📁 我为聊狂的聊天软件,又一款UDP聊天软件
💻 CPP
字号:
//***********************************************
//***    软件名称:我为聊狂客户端
//***    文件名称:UserDlg.cpp 
//***    功能:   实现列出所有上线用户
//***    软件开发:顾加平
//***    邮箱地址:jiapingboy@163.com
//***   更多软件下载:jiaping.9xc.com
//***********************************************
//以下代码全是作者个人写的,版权属于作者个人,不准随意复制传播!!


#include "stdafx.h"
#include "Client.h"
#include "UserDlg.h"
#include "ReciveMessage.h"
#include "RecieveDlg.h"
#include <afxmt.h>    //互斥体对象

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

#define PORT (unsigned short)9614        //定义通信服务器的端口号
#define IPADDRESS  "127.0.0.1"           //定义通隹服务器的IP地址
#define MYTIMERID    1                   //定时我的时间ID号
#define WM_SYSTEMTRAY     WM_USER+2
#define ID_SYSTEMTRAY      3200

//***************************************************
//**    共享数据结构
CList <userList, userList&> user_List;    //所有在线用户
CList <messageList, messageList&> message_List;  //消息链表
bool   bChanged;
CMutex mutex;                             //实现互斥体对象
CMutex mutex2;         
//***************************************************
/////////////////////////////////////////////////////////////////////////////
// CUserDlg dialog


CUserDlg::CUserDlg(CWnd* pParent /*=NULL*/)
: CDialog(CUserDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CUserDlg)
	// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CUserDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CUserDlg)
	DDX_Control(pDX, IDC_USERLIST, m_userList);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CUserDlg, CDialog)
//{{AFX_MSG_MAP(CUserDlg)
ON_WM_TIMER()
	ON_WM_CLOSE()
	ON_NOTIFY(NM_DBLCLK, IDC_USERLIST, OnDblclkUserlist)
	ON_MESSAGE(WM_SYSTEMTRAY , OnSystemTray)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUserDlg message handlers

BOOL CUserDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	char sendBuffer[500];
	int iStatus;
	char recvBuff[20];
	

		//*******************************
		//把图标加入图像列表

		HICON hIconTemp;

		m_imageList.Create (32, 32, 0, 25, 5);  //建立图像列表
		
		for(int i=1; i<=25; ++i)
		{
			CString strIconTemp;

			strIconTemp.Format ("face\\%d.ico", i);
			hIconTemp = ::ExtractIcon (::AfxGetInstanceHandle (), 
				strIconTemp, 0);

			if(hIconTemp!=NULL)
			{
				m_imageList.Add (hIconTemp);
			}
		}

		m_userList.SetImageList (&m_imageList, LVSIL_NORMAL);
	

       //***********************************
	//网络初始化
	Net_Init();
	
	//组合发送字段
	sprintf(sendBuffer, "%i,%s,%i,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\0",
		userInfo.m_imyIcon , userInfo.m_strPetName , userInfo.m_iAge ,
		userInfo.m_strSex ,userInfo.m_strPassword ,
		userInfo.m_strRealName ,userInfo.m_strSx ,userInfo.m_strBlood ,
		userInfo.m_strConstallation , userInfo.m_strSchool ,userInfo.m_strJob ,
		userInfo.m_strHoemPage , userInfo.m_strAddress ,
		userInfo.m_strMail);
	
	//发送数据
	iStatus = send(m_destSocket, sendBuffer, strlen(sendBuffer)+1, 0);
	if(iStatus == SOCKET_ERROR)
	{
		closesocket(m_destSocket);
		
		MessageBox(_T("用户信息数据发送失败!"), _T("我为聊狂"),
			MB_ICONINFORMATION);
		return FALSE;
	}
	
	//接收返回信息
	iStatus = recv(m_destSocket, recvBuff, 20, 0);
	recvBuff[iStatus]='\0';

	TRACE("Line 96 %s", recvBuff);
	
	if(strcmp(recvBuff, "repeat") ==0)
	{
		//如果该用户已经上线
		closesocket(m_destSocket);
		
		MessageBox(_T("对不起,该用户已经上线!"), _T("我为聊狂"),
			MB_ICONINFORMATION);
		return FALSE;
	}
	else if(strcmp(recvBuff, "success") ==0)
	{
		TRACE("登陆成功\n");

		//如果登陆成功
		CWinThread *hHandle;
		hHandle = AfxBeginThread(RecvThread, (LPVOID)m_destSocket);
		if(hHandle == NULL)
		{
			MessageBox(_T("无法开辟新的线程了!"), _T("我为聊狂"),
				MB_ICONINFORMATION);
		}


		SetTimer(1, 1000, NULL);  
	}
	else
	{
		closesocket(m_destSocket);
		
		MessageBox(_T("对不起,登陆出错!"), _T("我为聊狂"),
			MB_ICONINFORMATION);
		return FALSE;
	}
	

		//设置托盘
	nid.cbSize=sizeof(NOTIFYICONDATA);
	nid.hWnd=m_hWnd;
	nid.uID=ID_SYSTEMTRAY;
	nid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
	nid.uCallbackMessage=WM_SYSTEMTRAY;
	nid.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	strcpy(nid.szTip , "我为聊狂");
	::Shell_NotifyIcon(NIM_ADD,&nid);
	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

//网络初始化
void CUserDlg::Net_Init()
{
	int err;
	
	WSADATA data;
	err = WSAStartup(MAKEWORD(1,1), &data);
	if(err !=0) 
	{
		MessageBox(_T("网络初始化失败!"), _T("我为聊狂"),
			MB_ICONINFORMATION);
		return;
	}
	
	m_destSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(m_destSocket== INVALID_SOCKET)
	{
		MessageBox(_T("无法创建SOCKET!"), _T("我为聊狂"),
			MB_ICONINFORMATION);
		return;
	}
	
	//填充服务器字段
	m_destSockAddr.sin_family =AF_INET;
	m_destSockAddr.sin_addr.s_addr = inet_addr(IPADDRESS);
	m_destSockAddr.sin_port = htons(PORT);
	
	//连接至目的主机
	err = connect(m_destSocket, (sockaddr *)&m_destSockAddr, sizeof(m_destSockAddr));
	if(err ==SOCKET_ERROR)
	{
		closesocket(m_destSocket);
		MessageBox(_T("服务器连接失败!"), _T("我为聊狂"),
			MB_ICONINFORMATION);
		return;
	}
}

//接收线程
UINT CUserDlg::RecvThread(LPVOID destSocket)
{
	SOCKET mySocket;
	mySocket = (SOCKET)destSocket;
	
	while(1)
	{
		char tempRecv[500];
		int iStatus;
		
		//读取消息
		iStatus = ::recv(mySocket, tempRecv, 500, 0);
		if(iStatus >0)
		{
			tempRecv[iStatus]='\0';
			
			TRACE("Line 185 %s\n", tempRecv);
			
			//如果收到了用户列表信息
			if(strcmp(tempRecv, "userInfoList")==0)
			{	
				userList userListTemp;
				
				iStatus = recv(mySocket, tempRecv, 100, 0);
				if(iStatus == SOCKET_ERROR)
				{
					AfxMessageBox("用户数据接收错误");
					return FALSE;
				}
				tempRecv[iStatus]='\0';
				
				int imyIcon;
				char struserName[20];
				char myIcontemp[5];
				char *pos;
				int i;
				
				//取得头像号
				pos = strchr(tempRecv, ',');
				int len = strlen(tempRecv) - strlen(pos);
				for(i=0; i<len; ++i)
				{
					myIcontemp[i]=tempRecv[i];
				}
				myIcontemp[i]='\0';
				imyIcon = atoi(myIcontemp);
				
				//取妮称
				pos= pos+1;
				len = strlen(pos);
				for(i=0 ; i<len; ++i)
				{
					struserName[i] = pos[i];
				}
				struserName[i]='\0';
				
				userListTemp.imyIcon = imyIcon;
				strcpy(userListTemp.userName , struserName);
				user_List.AddTail (userListTemp);

				bChanged = true;
			}
			//添加用信息结束*****************************************************************
			else if(strcmp(tempRecv, "closed") == 0)
			{
				closesocket(mySocket);
				AfxEndThread(0);
			}
			//*******************一般消息处理
			else
			{
				char *pos;
				char toUser[20];
				char *messageTemp;
				int  imyIcon;
				char strIconTemp[10];
				int i, count;
				
				pos = strchr(tempRecv, ',');
				count = strlen(tempRecv) - strlen(pos);
				for(i=0; i< count; ++i)
				{
					toUser[i] = tempRecv[i];
				}
				toUser[i] = '\0';       //取得对方用户妮称
				messageTemp  = pos +1;
				pos = strchr(messageTemp, ',');
				count = strlen(messageTemp) - strlen(pos);
				for(i=0; i<count; ++i)
				{
					strIconTemp[i] = messageTemp[i];
				}
				strIconTemp[i] = '\0';
				imyIcon = atoi(strIconTemp);   //取得用户头像
				
				messageTemp = pos +1;         //取得消息内容

				//查找该用户是否在列表中
				POSITION position;
				position = user_List.GetHeadPosition ();
				int listCount = user_List.GetCount ();
			
				userList tempUserList;
				int ii;

				for(ii=0; ii < listCount; ++ii)
				{
					tempUserList = user_List.GetNext (position);
					if(strcmp(tempUserList.userName , toUser) == 0)
					{
						break;
					}
				}

				if(ii >=listCount )   //如果用户不在原先表中
				{
					//添加进去 
					tempUserList.imyIcon = imyIcon;
					strcpy(tempUserList.userName , toUser);
					user_List.AddTail (tempUserList);
					bChanged = true;
				}

				//添加消息列表
				messageList tempMesList;
				tempMesList.imyIcon = imyIcon;
				strcpy( tempMesList.strMessage, messageTemp);
				strcpy( tempMesList.userName , toUser);
				
				CTime t = CTime::GetCurrentTime ();  //取得当前时间
				tempMesList.strTime = t.Format (_T("%A, %B %d, %Y   %H:%M:%S"));
				
				mutex2.Lock ();
				message_List.AddHead (tempMesList);
				mutex2.Unlock ();
				sndPlaySound(_T("msg.wav"), SND_ASYNC | SND_LOOP);
			}
		}
	}
	return TRUE;
}


void CUserDlg::OnTimer(UINT nIDEvent) 
{
	if(nIDEvent == 1)
	{
		if(bChanged == true)
		{
			bChanged = false;

			//刷新用户列表
			int i =0;
			POSITION pos;
			
			pos= user_List.GetHeadPosition ();
			if(m_userList.GetItemCount () >= 0)
			{
				m_userList.DeleteAllItems ();
			}

			while( pos != NULL)
			{
				CString strUserName;
				userList userListTemp;
				int nImage;

				userListTemp = user_List.GetNext (pos);		
				strUserName.Format ("%s", userListTemp.userName );
				nImage = userListTemp.imyIcon ;

				m_userList.InsertItem (i, strUserName, nImage);
				++i;
			}
		}
	}
	CDialog::OnTimer(nIDEvent);
}


//当用户退出时则断开与服务器的连接
void CUserDlg::OnClose() 
{
	send(m_destSocket, "closed", strlen("closed") +1, 0);  //请求关闭与服务器连接

	closesocket(m_destSocket);
	::WSACleanup ();              //关闭网络服务

	KillTimer(1);

	CDialog::OnClose();
}


//双击用户头像开始发送消息
void CUserDlg::OnDblclkUserlist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;
	CString strText;

	if(phdn->iItem >= 0)	
	{
		//获取好友信息,好友信息保存在列表项的附加数据里
		strText = m_userList.GetItemText (phdn-> iItem, 0);

		//得到用户图标
		POSITION pos;
		userList tempUserList;
		int i_myIcon =1 ;
		pos = user_List.GetHeadPosition ();
		while(pos != NULL)
		{
			tempUserList = user_List.GetNext (pos);
			if(strcmp(strText, tempUserList.userName ) ==0)
			{
				i_myIcon =tempUserList.imyIcon ;
			}
		}

		HICON tempIcon;
		CString tempstrIcon;
		tempstrIcon.Format ("face\\%d.ico", i_myIcon);
		tempIcon = ::ExtractIcon (::AfxGetInstanceHandle (),
			tempstrIcon, 0);

    	//显示“发送讯息”窗口
		CRecieveDlg dlg;
		dlg.m_hIcon = tempIcon;
		dlg.m_strPetName .Format ("%s", strText);

		//如果用户发送数据
		if (dlg.DoModal () == IDOK)
		{
			char sendBuff[400];
			int iStatus;
			sprintf(sendBuff, "%s,%d,%s\0", dlg.m_strPetName , i_myIcon, dlg.m_strMessage );
			MessageBox(sendBuff);
			iStatus =send(m_destSocket, sendBuff, strlen(sendBuff) +1, 0);
			if(iStatus == SOCKET_ERROR)
			{
				MessageBox(_T("用户发送信息失败"), _T("我为聊狂"), MB_ICONERROR);
			}
		}
	}
	*pResult = 0;
}


//用户的托盘响应
LRESULT CUserDlg::OnSystemTray (WPARAM uID, LPARAM lEvent)
{
    CReciveMessage   dlg;
	if(uID == ID_SYSTEMTRAY)
	{
		switch(lEvent)
		{
		case WM_LBUTTONDOWN:
			if(FindWindow(NULL, _T("我为聊狂(消息接收)")) == NULL)
			{
				//取得消息队列中的消息
				messageList tempMessage;

				

				mutex.Lock ();   //实现线程互斥
				if(message_List.GetCount () >0)
				{
					sndPlaySound(NULL , SND_ASYNC);   //停止声音
					tempMessage = message_List.GetHead ();
					HICON hIcon;
					CString tempStrIcon;
					tempStrIcon.Format ("face\\%d.ico", tempMessage.imyIcon );
					hIcon = ::ExtractIcon (::AfxGetInstanceHandle (),
					tempStrIcon, 0);

					dlg.m_strTime.Format ("%s",tempMessage.strMessage);
					dlg.m_strPetName.Format ("%s", tempMessage.userName);
					dlg.m_strTime = tempMessage.strTime ;
					dlg.m_hIcon = hIcon;

					//如果是回信息
					if( dlg.DoModal () == IDOK)
					{

						CRecieveDlg sendDlg;
						sendDlg.m_hIcon = hIcon;
						sendDlg.m_strPetName = tempMessage.userName ;
					
						if(sendDlg.DoModal () == IDOK)
						{
							//发送消息
							char sendBuff[400];
							int iStatus;
							sprintf(sendBuff, "%s,%d,%s\0", sendDlg.m_strPetName , userInfo.m_imyIcon  ,sendDlg.m_strMessage  );
							iStatus =send(m_destSocket, sendBuff, strlen(sendBuff) +1, 0);
							if(iStatus <= 0)
							{
								MessageBox(_T("用户发送信息失败"), _T("我为聊狂"), MB_ICONERROR);
							}
						}	
					}
					message_List.RemoveHead ();   //删除队列消息
				}
				mutex.Unlock ();
			}
			break;

		default:
			break;
		}
	}
	return TRUE;
}

⌨️ 快捷键说明

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