📄 im1.cpp
字号:
// IM1.cpp : implementation file
//
#include "stdafx.h"
#include "user.h"
#include "IM.h"
#include "IMDlg.h"
#include "IM1.h"
#include "AddUser.h"
#include "MngDlg.h"
#include "hatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// IM dialog
IM::IM(CWnd* pParent /*=NULL*/)
: CDialog(IM::IDD, pParent)
{
//{{AFX_DATA_INIT(IM)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void IM::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(IM)
DDX_Control(pDX, IDC_TREE, m_TreeCtl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(IM, CDialog)
//{{AFX_MSG_MAP(IM)
ON_BN_CLICKED(ID_ADDUSER, OnAdduser)
ON_BN_CLICKED(IDC_BTN_MNG, OnBtnMng)
ON_NOTIFY(NM_DBLCLK, IDC_TREE, OnDblclkTree)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_RECVDATA,OnRecvData)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// IM message handlers
BOOL IM::OnInitDialog()
{
CDialog::OnInitDialog();
IMhWnd=m_hWnd;
m_nToP=FALSE;
m_ImgCs.Create(IDB_BITMAP4,16,1,RGB(255,255,255));
HICON hIcon = AfxGetApp() ->LoadIcon(IDI_ICON1);
m_ImgCs.Add(hIcon);
hIcon = AfxGetApp() ->LoadIcon(IDI_ICON2);
m_ImgCs.Add(hIcon);
hIcon = AfxGetApp() ->LoadIcon(IDI_ICON3);
m_ImgCs.Add(hIcon);
hIcon = AfxGetApp() ->LoadIcon(IDI_ICON4);
m_ImgCs.Add(hIcon);
m_TreeCtl.SetImageList(&m_ImgCs, LVSIL_NORMAL);
UpdateIM(TRUE);
//初始化UDP套接字
InitSocket();
//创建子进程接受UDP消息 传递参数为UDP套接字 处理函数为RecvProc
HANDLE udphThread=CreateThread(NULL,0,RecvProc,(LPVOID)m_socket,0,NULL);
CloseHandle(udphThread);
return TRUE;
}
void IM::OnCancel()
{
// TODO: Add extra cleanup here
CString str;char buffer[1024];
//离线通知 e标志代表e类服务 离线后关闭TCP套接字
str.Format("e%d",m_uid);
::send(TCPsocket,str,str.GetLength()+1,0);
::recv(TCPsocket,buffer,1024,0);
closesocket(TCPsocket);
CDialog::OnCancel();
}
void IM::OnAdduser()
{
//添加好友模块
// TODO: Add your control notification handler code here
AddUser adu;
if(adu.DoModal()==IDOK)
{
m_TreeCtl.DeleteAllItems();
UpdateIM(TRUE);
}
}
//更新客户端好友列表 参数代表是否需访问数据库
void IM::UpdateIM(BOOL AccessDB)
{
CString str;
str.Format("%d的全部好友",m_uid);
//判断时候有广播消息
if(HaveStoreMsg(1000))
hItemRoot=m_TreeCtl.InsertItem(str,4,4,TVI_ROOT);
else hItemRoot=m_TreeCtl.InsertItem(str,-1,-1,TVI_ROOT);
char buf[20][16];
int grpnum=GetPrivateProfileInt("FriendGroup","Groupnum",0,CRdir+"\\fenzu.ini");
//读本地好友列表分组信息 添加树枝节点
HTREEITEM hItem[100];
for(int i=1;i<=grpnum;i++)
{
str.Format("Groupname%d",i);
GetPrivateProfileString("FriendGroup",str,NULL,buf[i],16,CRdir+"\\fenzu.ini");
hItem[i]=m_TreeCtl.InsertItem(buf[i],0,0,hItemRoot);
}
if(AccessDB)
{
//需要访问数据库时 请求读取好友信息
//f标志代表 f类服务
char buffer[2048];
str.Format("f%d",m_uid);
::send(TCPsocket,str,str.GetLength()+1,0);
//读好友个数
::recv(TCPsocket,buffer,4,0);
str.Format("%s",buffer);
//全局变量 好友总数
total=atoi(str);
::recv(TCPsocket,buffer,1024,0);
str.Format("%s",buffer);
str.Delete(0,1);
//将接受到的流转换保存为好友信息
StreamToStruct(str);
}
int k;
for(i=total;i>=1;i--)
{
//读分组文件 插入叶子节点
k=GetFriendGrp(fuser[i].uid);
str.Format("%s(%d)",fuser[i].fnicheng,fuser[i].uid);
//根据会员,在线,离线,有消息。判断关联哪个图片
//从而给出相应提示
if(fuser[i].fonline)
{
if(HaveStoreMsg(fuser[i].uid))
m_TreeCtl.InsertItem(str,4,4,hItem[k],TVI_FIRST);
else if(fuser[i].fvip)
m_TreeCtl.InsertItem(str,1,1,hItem[k],TVI_FIRST);
else
m_TreeCtl.InsertItem(str,2,2,hItem[k],TVI_FIRST);
}
else if(m_nToP==FALSE)
{
m_TreeCtl.InsertItem(str,3,3,hItem[k],TVI_LAST);
}
}
}
void IM::OnBtnMng()
{
// TODO: Add your control notification handler code here
MngDlg mdlg;
mdlg.DoModal();
if(mdlg.m_nOnline==0)
m_nToP=TRUE;
else if(mdlg.m_nOnline==1)
m_nToP=FALSE;
m_TreeCtl.DeleteAllItems();
if(mdlg.m_nDeID!=0)
UpdateIM(TRUE);
else UpdateIM(FALSE);
}
void IM::OnDblclkTree(NMHDR* pNMHDR, LRESULT* pResult)
{
//双击好友叶结点 弹出对话框 处理函数
// TODO: Add your control notification handler code here
HTREEITEM hItem=m_TreeCtl.GetSelectedItem();
if(m_TreeCtl.GetChildItem(hItem )==NULL&&m_TreeCtl.GetParentItem(hItem)!=hItemRoot)
{
CString s,str=m_TreeCtl.GetItemText(hItem);
int length=str.GetLength();
//获取好友 昵称
for(int i=length-2;i>=0;i--)
{
s=str.GetAt(i)+s;
if(str.GetAt(i)=='(')
{
str.SetAt(i,'\0');
break;
}
}
int digital,num=0;
//获取好友ID
for(int j=1;j<length-i-1;j++)
{
digital=s.GetAt(j)-48;//-48什么意思?
num=num*10+digital;
}
ChatDlg cd;
cd.m_nuid=num;
m_iding=num;
cd.m_nicheng=str;
cd.m_socket=m_socket;
cd.DoModal();
ChathWnd=NULL;
m_iding=-1;
}
else if(hItem == hItemRoot && HaveStoreMsg(1000))
{
//当有广播时双击根节点弹出广播消息
ChatDlg cd;
cd.m_nuid=1000;
m_iding=1000;
cd.m_nicheng="系统广播";
cd.m_socket=m_socket;
cd.DoModal();
ChathWnd=NULL;
m_iding=-1;
}
m_TreeCtl.DeleteAllItems();
UpdateIM(FALSE);
*pResult = 0;
}
BOOL IM::InitSocket()
{
m_socket=socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET==m_socket)
{
AfxMessageBox("套接字创建失败!");
exit(1);
}
SOCKADDR_IN addrSock;
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(m_nPort);
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/*inet_addr("59.72.27.169")*/;
int retval;
retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));
if(SOCKET_ERROR==retval)
{
int t;
t = WSAGetLastError();
closesocket(m_socket);
MessageBox("UDP绑定失败!");
exit(1);
}
//int z= ntohs(addrSock.sin_port);
return TRUE;
}
DWORD WINAPI IM::RecvProc(LPVOID lpParameter)
{
//接收到UDP包的处理函数
SOCKET sock= (SOCKET)lpParameter;
SOCKADDR_IN addrFrom;
int len=sizeof(SOCKADDR);
char recvBuf[1024];
char IPPortBuf[32];
int retval;
while(TRUE)
{
retval=recvfrom(sock,recvBuf,1024,0,(SOCKADDR*)&addrFrom,&len);
if(SOCKET_ERROR==retval)
break;
if(-1==retval)
{
AfxMessageBox("与服务器断开,谢谢您的使用!");
exit(0);
}
sprintf(IPPortBuf,"%s:%d",inet_ntoa(addrFrom.sin_addr),ntohs(addrFrom.sin_port));
//传递消息
::PostMessage(IMhWnd,WM_RECVDATA,(WPARAM)IPPortBuf,(LPARAM)recvBuf);
}
return 0;
}
void IM::OnRecvData(WPARAM wParam,LPARAM lParam)
{
//接收到消息的处理函数
CString recvBuf=(char*)lParam;
char c=recvBuf.GetAt(0);;
for(int i=1;i<=total;i++)
{
if(fuser[i].fipport==(char*)wParam)
break;
}
switch(c)
{
case 'a'://A类 普通聊天信息
if(i<=total)
{
if(m_iding!=-1&&fuser[i].uid==m_iding)
{
::PostMessage(ChathWnd,WM_RECVDATA,wParam,lParam);
}
else
{
//如果聊天对话框未打开则插入临时消息链表
apacket.msg =recvBuf;
apacket.uid=fuser[i].uid;
if(head==NULL)
head->InsertRear(head,apacket);
head->InsertRear(head,apacket);
}
}
break;
case 'b':break;//好友上线通知
case 'c':break;//好友离线通知
case 'd':
//广播
recvBuf.Delete(0,1);
apacket.msg =recvBuf;
apacket.uid=1000;
if(head==NULL)
head->InsertRear(head,apacket);
head->InsertRear(head,apacket);
break;
default:;
}
m_TreeCtl.DeleteAllItems();
UpdateIM(TRUE);
}
void IM::StreamToStruct(CString str)
{
//将接收到的好友信息流转化为本地好友数据
int j=1;
CString s;
for(int n=1;n<=total;n++)
{
for(int i=0;i<str.GetLength();i++)
{
if(str.GetAt(i)!='#')
s=s+str.GetAt(i);
else
{
if(j==1)
{
fuser[n].uid=atoi(s);
s="";
j++;
}
else if(j==2)
{
fuser[n].fipport=s;
s="";
j++;
}
else if(j==3)
{
fuser[n].fvip=atoi(s);
s="";
j++;
}
else if(j==4)
{
fuser[n].fonline=atoi(s);
s="";
j++;
}
else break;
}
}
fuser[n].fnicheng=s;
s="";
j=1;
str.Delete(0,i+1);
}
}
BOOL IM::HaveStoreMsg(int uid)
{
//判断用户 uid 在消息链表中是否有存储的数据
if(head!=NULL)
{
Node <struct APacket> *tempnode=head->NextNode();
while(tempnode!=NULL)
{
if(tempnode->data.uid==uid)
return TRUE;
tempnode = tempnode->NextNode();
}
}
return FALSE;
}
int IM::GetFriendGrp(int uid)
{
//从本地好友分组文件中读取好友 uid 所属组号码并返回
int friendnum,k=1;
CString str,s;
char buf[20][16];
int grpnum=GetPrivateProfileInt("FriendGroup","Groupnum",0,CRdir+"\\fenzu.ini");
for(int i=1;i<=grpnum;i++)
{
str.Format("Groupname%d",i);
GetPrivateProfileString("FriendGroup",str,NULL,buf[i],16,CRdir+"\\fenzu.ini");
friendnum=GetPrivateProfileInt(buf[i],"Friendnum",0,CRdir+"\\fenzu.ini");
for(k=1;k<=friendnum;k++)
{
str.Format("Friend%d",k);
if(uid==(int)GetPrivateProfileInt(buf[i],str,0,CRdir+"\\fenzu.ini"))
return i;
}
}
if(i>grpnum)
{
friendnum=GetPrivateProfileInt("我的好友","Friendnum",0,CRdir+"\\fenzu.ini");
str.Format("Friend%d",++friendnum);
s.Format("%d",uid);
WritePrivateProfileString("我的好友",str,s,CRdir+"\\fenzu.ini");
str.Format("%d",friendnum);
WritePrivateProfileString("我的好友","Friendnum",str,CRdir+"\\fenzu.ini");
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -