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

📄 chat.cpp

📁 基于TCP/IP的网络通信技术实现了面向连接的用户与服务器间点对点异步通信
💻 CPP
字号:
// Chat.cpp : implementation file
//

#include "stdafx.h"
#include "Client.h"
#include "Chat.h"
#include "MyIntro.h"

#define DEST_IP_ADDR "127.0.0.1"
#define PORT 56790
#define NO_FLAGS_SET 0
#define MAXBUFLEN 5025

#define WM_SYSTEMTRAY WM_USER+1
#define WM_RECVDATA   WM_USER+2

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

HWND recvWnd;
/////////////////////////////////////////////////////////////////////////////
// CChat dialog
UINT Recv_Thread(void* cs)
{
	char buffer[MAXBUFLEN];
	int numrcv;
	SOCKET clientSocket=(SOCKET)cs;
	while(1)
	{
		numrcv=recv(clientSocket, buffer, MAXBUFLEN, NO_FLAGS_SET);
		if ((numrcv == 0) || (numrcv == SOCKET_ERROR))
		{
			AfxMessageBox("Connection terminated!",MB_OK);
			break;
		}
		buffer[numrcv]='\0';
		::PostMessage(recvWnd,WM_RECVDATA,DWORD((LPSTR)buffer),numrcv);
	}
	return 1;
}

CChat::CChat(CWnd* pParent /*=NULL*/)
	: CDialog(CChat::IDD, pParent)
{
	//{{AFX_DATA_INIT(CChat)
	m_room = _T("");
	m_recv = _T("");
	//}}AFX_DATA_INIT
	m_hIcon=AfxGetApp()->LoadIcon(131);
}


void CChat::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChat)
	DDX_Control(pDX, IDC_FRIEND, m_friend);
	DDX_Control(pDX, IDC_PETNAME, m_petname);
	DDX_Control(pDX, IDC_MESSAGE, m_message);
	DDX_Control(pDX, IDC_TUBIAO, m_tubiao);
	DDX_Control(pDX, IDC_MORE, m_more);
	DDX_Text(pDX, IDC_ROOM, m_room);
	DDX_Text(pDX, IDC_RECEIVE, m_recv);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChat, CDialog)
	//{{AFX_MSG_MAP(CChat)
	ON_BN_CLICKED(IDC_MORE, OnMore)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_SEND, OnSend)
	ON_BN_CLICKED(IDC_REPLY, OnReply)
	ON_CBN_SELCHANGE(IDC_PETNAME, OnSelchangePetname)
	ON_MESSAGE(WM_RECVDATA,RecvData)
	ON_COMMAND(ID_ABOUT, OnAbout)
	ON_COMMAND(ID_CLOSE, OnClose)
	ON_COMMAND(ID_SHOW, OnShow)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_SYSTEMTRAY,OnSystemTray)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChat message handlers

BOOL CChat::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	// TODO: Add extra initialization here
/////////////////////////////网络初始化//////////////////////////////////////
//	clientsocket.SetParent(this);
	Init_net();
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////对话框大小控制//////////////////////////////////
	GetWindowRect(&m_rectFull);
	m_rectHalf=m_rectFull;
	CRect rect;
	m_more.GetWindowRect(&rect);
	m_rectHalf.bottom=rect.bottom+5;
	m_bToggleSize=false;
	ToggleSize();
/////////////////////////////////////////////////////////////////////////////
///////////////////////////读用户信息文件//////////////////////////////////////
	CString str;
	int j=0;
	char *pos=new char;
	char *pos1=new char;
	char temp[40],temp1[40];
	filename.Format(".\\data\\%s.db",m_username);
/*	filename+=m_username;
	filename+=".db";*/
	m_file.Open(filename, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite | CFile::shareDenyWrite);
	m_file.SeekToBegin();
	while(m_file.ReadString(str))
	{
		str.TrimRight();
		str.TrimLeft();
		pos=strchr(str,',');
		int len_str=strlen(str);
		int len_pos=strlen(pos);
		int len=len_str-len_pos;
		pos+=1;
		pos1=pos;
		for(int i=0;i<len;i++)
			temp[i]=str[i];
		temp[len]='\0';
		if(strcmp(temp,m_username)!=0)
			m_petname.InsertString(m_petname.GetCount(),temp);
		len_str=strlen(pos1);
		pos=strchr(pos1,',');
		len_pos=strlen(pos);
		len=len_str-len_pos;
		pos+=1;
		for(i=0;i<len;i++)
			temp1[i]=pos1[i];
		temp1[len]='\0';
		pet[j]=atoi(temp1);
		if(strcmp(temp,m_username)==0)
			res=pet[j];
//		room[j]=pos;
		map.SetAt(temp,pos);
		j++;
	}
	m_petname.SetCurSel(0);
	CString aa;
	m_petname.GetLBText(0,aa);
	m_room=map[aa];
	m_file.Close();
///////////////////////////////////////////////////////////////////////////////
/////////////////////////系统托盘////////////////////////////////////////////
	NOTIFYICONDATA nid;
	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(res);
	strcpy(nid.szTip,"网际飞标");
	::Shell_NotifyIcon(NIM_ADD,&nid);

	if(res!=280)
	{
		HICON hIcon=AfxGetApp()->LoadIcon(res);
		m_tubiao.SetIcon(hIcon);
	}

	m_netsel=res;
	res_own.Format("%d",res);
	flag=false;
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////界面///////////////////////////////////////////
	GetDlgItem(IDC_REPLY)->EnableWindow(false);
	recvWnd=m_hWnd;
	CString title;
	title.Format("%s%s",m_username,"的好友");
	m_friend.SetWindowText(title);
	bReply=false;
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////读文档////////////////////////////////////
	filename.Format(".\\data\\%s.fly",m_username);
	m_file.Open(filename, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite | CFile::shareDenyWrite);
	m_file.SeekToBegin();
//	CString str1;
	while(m_file.ReadString(str))
	{
		str.TrimRight();
		m_recv+=str;
		m_recv+="\r\n";
	}
	m_file.Close();
///////////////////////////////////////////////////////////////////////////////
	UpdateData(false);
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

BOOL CChat::Init_net()
{
/////////////////////////网络初始化///////////////////////////////////
	status=WSAStartup(MAKEWORD(1, 1), &Data);
	if (status != 0)
		MessageBox("ERROR: WSAStartup unsuccessful!","网际飞标",MB_OK);
	destAddr=inet_addr(DEST_IP_ADDR);		//暂时定为本机使用
	memcpy(&destSockAddr.sin_addr, &destAddr,sizeof(destAddr));
	destSockAddr.sin_port=htons(PORT);
	destSockAddr.sin_family=AF_INET;
	destSocket=socket(AF_INET, SOCK_STREAM, 0);
	if (destSocket == INVALID_SOCKET)
	{
		MessageBox("ERROR: socket unsuccessful!","网际飞标",MB_OK);
		status=WSACleanup();
		if (status == SOCKET_ERROR)
			MessageBox("ERROR: WSACleanup unsuccessful!","网际飞标",MB_OK);
		return false;
	}
//////////////////////////////////////////////////////////////////////
///////////////////////////连接网络////////////////////////////////////////////
	status=connect(destSocket, (LPSOCKADDR) &destSockAddr,sizeof(destSockAddr));
	if (status == SOCKET_ERROR)
	{
		MessageBox("ERROR: connect unsuccessful!","网际飞标",MB_OK);
		status=closesocket(destSocket);
		if (status == SOCKET_ERROR)
			MessageBox("ERROR: closesocket unsuccessful!","网际飞标",MB_OK);
		status=WSACleanup();
		if (status == SOCKET_ERROR)
			MessageBox("ERROR: WSACleanup unsuccessful!","网际飞标",MB_OK);
		return false;
	}
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
/*	if(clientsocket.Create()==0)
	{
		MessageBox("ERROR: Create unsuccessful!","网际飞标",MB_OK);
		return false;
	}
	if(clientsocket.Connect(DEST_IP_ADDR,56790)==0)
	{
 		MessageBox("ERROR: Connect unsuccessful!","网际飞标",MB_OK);
		return false;
	}
	int p=clientsocket.GetLastError();*/
	send(destSocket,m_username,m_username.GetLength(),0);
	AfxBeginThread(Recv_Thread,(LPVOID)destSocket);
	return true;
}

/*void CChat::Receive()
{
	m_message.SetReadOnly(true);
	GetDlgItem(IDC_REPLY)->EnableWindow(true);
	SetTimer(0,200,NULL);
}*/

void CChat::OnMore() 
{
	// TODO: Add your control notification handler code here
	ToggleSize();
}

void CChat::ToggleSize()
{
	CRect rect;
	CString str;
	if(m_bToggleSize)
	{
		str="<<&Less";
		rect=m_rectFull;
	}
	else
	{
		str="&More>>";
		rect=m_rectHalf;
	}
	SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),SWP_NOZORDER|SWP_NOMOVE);
	m_more.SetWindowText(str);
	m_bToggleSize=!m_bToggleSize;
}

LRESULT CChat::OnSystemTray(WPARAM wParam, LPARAM lParam)
{

	if(wParam=ID_SYSTEMTRAY)
	{
		switch(lParam)
		{
		case  WM_LBUTTONDBLCLK:
			{
				KillTimer(0);
				NOTIFYICONDATA nid;
	            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(res);
	            strcpy(nid.szTip,"网际飞标");
	            ::Shell_NotifyIcon(NIM_MODIFY,&nid);
				::ShowWindow(m_hWnd,SW_SHOWDEFAULT);
		        sndPlaySound(NULL,SND_ASYNC);
				m_tubiao.SetIcon(AfxGetApp()->LoadIcon(res));
			}
			break;
		case WM_RBUTTONDOWN:
			{
				CMenu pMenu;
	            pMenu.LoadMenu(IDR_MENU1);
	            CMenu* pMenu1=pMenu.GetSubMenu(0);
	            ASSERT(pMenu1!=NULL);
                CPoint point;
				GetCursorPos(&point);
	            pMenu1->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);
				PostMessage(WM_NULL);
			}
		default:
			break;
		}
	}
	return 1;
}

BOOL CChat::DestroyWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	CString close="Close!";
	send(destSocket,close,close.GetLength(),0);
///////////////////////////////////////////////////////////////////////////////
	NOTIFYICONDATA nid;
	nid.cbSize=sizeof(NOTIFYICONDATA);
	nid.hWnd=m_hWnd;
	nid.uID=ID_SYSTEMTRAY;
	nid.uFlags=0;
	::Shell_NotifyIcon(NIM_DELETE,&nid);

	KillTimer(0);
/////////////////////////////////////////////////////////////////////////////
	FILE *file;
	if((file = fopen(filename, "w"))!=NULL)
	{
		fprintf(file,"%s",m_recv);
	}
	fclose(file);
	return CDialog::DestroyWindow();
}

void CChat::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(!flag)
	{
		NOTIFYICONDATA nid;
	    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(m_netsel);
	    strcpy(nid.szTip,"网际飞标");
	    ::Shell_NotifyIcon(NIM_MODIFY,&nid);
		m_tubiao.SetIcon(AfxGetApp()->LoadIcon(m_netsel));
	}
	else
	{
		NOTIFYICONDATA nid;
	    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(IDI_NULL);
	    strcpy(nid.szTip,"网际飞标");
	    ::Shell_NotifyIcon(NIM_MODIFY,&nid);
		m_tubiao.SetIcon(AfxGetApp()->LoadIcon(IDI_NULL));
	}
	flag=!flag;
	CDialog::OnTimer(nIDEvent);
}

void CChat::OnSend() 
{
	// TODO: Add your control notification handler code here
	GetDlgItem(IDC_REPLY)->EnableWindow(false);
	UpdateData(true);
///////////////////////////////////////////////////////////////////////////////
	int count=m_petname.GetCurSel();
	m_petname.GetLBText(count,m_netuser);
	CString date;
	CTime time;
	time=CTime::GetCurrentTime();
	date=time.Format("%A,%B,%d,%Y,%H:%M:%S");

	CString temp;

	if(m_message.GetModify())
	{
		temp+="(";
		temp+=date;
		temp+=")";
		temp+=m_username;
		temp+="\r\n";

		char str[100][200];
		int len=0;
		int count=m_message.GetLineCount();
		if(count<=100)
		{
			for(int i=0;i<count;i++)
			{
				len=m_message.LineLength(m_message.LineIndex(i));
				m_message.GetLine(i,str[i]);
				str[i][len]='\0';
				temp+=str[i];
				temp+="\r\n";
			}
		}
		temp+="\r\n";
		send_data=m_netuser;
		send_data+=":";
		send_data+=res_own;
		send_data+="~";
		send_data+=temp;
		m_recv+=temp;
		numsnd=send(destSocket,send_data,send_data.GetLength(),0);
		if(numsnd==SOCKET_ERROR||numsnd==0)
		{
			MessageBox("传输失败","警告",MB_OK);
		}
		else
		{	
			UpdateData(false);
		}
	}
	m_message.SetWindowText("");
	::ShowWindow(m_hWnd,SW_HIDE);
	bReply=false;
}

void CChat::OnReply() 
{
	// TODO: Add your control notification handler code here
	GetDlgItem(IDC_REPLY)->EnableWindow(false);
	m_message.SetWindowText("");
	m_message.SetReadOnly(false);
	bReply=true;
}

void CChat::OnSelchangePetname() 
{
	// TODO: Add your control notification handler code here
	UpdateData();
	CString str;
	int p=m_petname.GetCurSel();
	m_petname.GetLBText(p,str);
//	m_room=room[p];
	m_room=map[str];
	UpdateData(false);

}

void CChat::RecvData(WPARAM wParam,LPARAM lParam)
{
	char *recvdata=(LPSTR)wParam;
	char source[5];
	int len_data=(int)lParam;
	char *pos=strchr(recvdata,'~');
	int len_pos=strlen(pos);
	pos+=1;
	int len=len_data-len_pos;
	for(int i=0;i<len;i++)
		source[i]=recvdata[i];
	source[len]='\0';
	m_netsel=atoi(source);

//	m_recv+="\r\n";
	m_recv+=pos;
	if(!bReply)
	{	
		m_message.SetWindowText(pos);
		m_message.SetReadOnly(true);
		GetDlgItem(IDC_REPLY)->EnableWindow(true);
	}
	SetTimer(0,200,NULL);
	sndPlaySound(".\\music\\msg.wav",SND_ASYNC|SND_LOOP);
//	MessageBox(m_recv);
	UpdateData(false);
}

BOOL CChat::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	HINSTANCE hInst=AfxGetResourceHandle();
	LPCTSTR lpID=MAKEINTRESOURCE(IDR_ACCELERATOR1);
	HACCEL d_hAccel=LoadAccelerators(hInst,lpID);
	if(d_hAccel==NULL)
		return false;
	return ::TranslateAccelerator(m_hWnd,d_hAccel,pMsg);
//	return CDialog::PreTranslateMessage(pMsg);
}

void CChat::OnAbout() 
{
	// TODO: Add your command handler code here
	CMyIntro dlg;
	dlg.DoModal();
}

void CChat::OnClose() 
{
	// TODO: Add your command handler code here
	CDialog::OnCancel();
	NOTIFYICONDATA nid;
	nid.cbSize=sizeof(NOTIFYICONDATA);
	nid.hWnd=m_hWnd;
	nid.uID=ID_SYSTEMTRAY;
	nid.uFlags=0;
	::Shell_NotifyIcon(NIM_DELETE,&nid);

	KillTimer(0);
}

void CChat::OnShow() 
{
	// TODO: Add your command handler code here
	::ShowWindow(m_hWnd,SW_SHOWDEFAULT);
}

⌨️ 快捷键说明

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