📄 userdlg.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 + -