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

📄 chatdlg.cpp

📁 WInsock32的客户端哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
💻 CPP
字号:
// ChatDlg.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "Client.h"
#include "ChatDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CChatDlg dialog


CChatDlg::CChatDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CChatDlg::IDD, pParent),m_strRec("")
	, FilePath(_T(""))
{
	//{{AFX_DATA_INIT(CChatDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_pSocket = NULL;
	m_pFile = NULL;
	m_pArchiveIn = NULL;
	m_pArchiveOut = NULL;
	m_bOfflineWnd = FALSE;
	m_pOfflinePacket = NULL;

}

/*
 * 在线/离线窗口
 */
CChatDlg::CChatDlg(CWnd* pParent, const CUserInfo &peerInfo, const CUserInfo &userInfor)
:CDialog(CChatDlg::IDD, pParent),m_strRec("")
{
	m_PeerInfo = peerInfo;	//对方用户信息
	m_UserInfo = userInfor;	//用户信息
	m_pSocket = NULL;		//CChatSocket指针
	m_pFile = NULL;			//文件对象
	m_pArchiveIn = NULL;	//读入文档对象
	m_pArchiveOut = NULL;	//写入文档对象
	m_pOfflinePacket = NULL;//离线数据包
	m_bOfflineWnd = FALSE;	//接收离线窗口
}

/*
 * 显示离线消息窗口
 */
CChatDlg::CChatDlg(CWnd* pParent, CChatPacket *pPacket)
:CDialog(CChatDlg::IDD, pParent),m_strRec("")
{
	m_pOfflinePacket = pPacket;	//离线数据包
	m_bOfflineWnd = TRUE;		//接收离线窗口

	m_pSocket = NULL;			//CChatSocket指针
	m_pFile = NULL;				//文件对象
	m_pArchiveIn = NULL;		//读入文档对象
	m_pArchiveOut = NULL;		//写入文档对象

}

void CChatDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChatDlg)
	DDX_Control(pDX, IDC_CLIENT_CHAT_OUTPUT_EDIT, m_ctlOutput);
	DDX_Control(pDX, IDC_CLIENT_CHAT_IPUT_EDIT, m_ctlInput);
	//}}AFX_DATA_MAP
	DDX_Text(pDX, IDC_CLIENT_CHAT_IPUT_EDIT, FilePath);
}


BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
	//{{AFX_MSG_MAP(CChatDlg)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTON3, &CChatDlg::OnBnClickedButton3)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChatDlg message handlers
/*
 * 接收消息
 */
void CChatDlg::ProcessPendingRead(void)
{
	do 
	{		
		CChatPacket chatPact;
		chatPact.Serialize(*m_pArchiveIn);		
		if (CChatPacket::MESSAGE == chatPact.m_type)//消息
		{		
			
			DisplayRecvMessage(&chatPact);	
		}	
		
	} while(!m_pArchiveIn->IsBufferEmpty());
}

/*
 * WM_INITDIALOG消息响应函数
 */
BOOL CChatDlg::OnInitDialog() 
{
	//调用基类函数
	CDialog::OnInitDialog();	

	if (NULL != m_pOfflinePacket && TRUE == m_bOfflineWnd)	//显示离线消息
	{
		DisplayOfflineMessage(m_pOfflinePacket);	
		
	}else if (m_PeerInfo.m_eStatus == CUserInfo::ONLINE)	//在线聊天
	{
		SetWindowText(_T("与") + m_PeerInfo.m_strName + _T("聊天中"));
		
	}else													//发送离线消息
	{
		SetWindowText(m_PeerInfo.m_strName + _T("不在线哦"));
	}	
	return TRUE;  
}

/*
 * 连接对方
 */
BOOL CChatDlg::ConnectToPeer(void)
{
	//创建CChatSocket对象
	if(!InitSocket())
	{
		return FALSE;
	}

	//创建套接字,绑定
	if (!m_pSocket->Create())
	{
		delete m_pSocket;
		m_pSocket = NULL;
		AfxMessageBox(_T("创建套接字失败!"));
		return FALSE;
	}

	m_pFile = new CSocketFile(m_pSocket);				//创建文件对象
 	m_pArchiveIn = new CArchive(m_pFile,CArchive::load);//创建读入文档对象
	
	
	//连接对方
	SOCKADDR_IN peerAddr;
	peerAddr.sin_family = AF_INET;
	peerAddr.sin_addr.S_un.S_addr = m_PeerInfo.m_lIP;
	peerAddr.sin_port = m_PeerInfo.m_nPort;
	while (!m_pSocket->Connect((SOCKADDR*)&peerAddr, sizeof(SOCKADDR_IN)))
	{
		if (AfxMessageBox(_T("连接对方失败,是否再次尝试连接。"),MB_YESNO) == IDNO)
		{
			return FALSE;
		}
	}	
	return TRUE;
}

BOOL CChatDlg::InitSocket(void)
{
	//创建套接字
	m_pSocket = new CChatSocket(this);
	return TRUE;
}

/*
 * 显示主动聊天接收到的消息
 */
void CChatDlg::DisplayRecvMessage(CChatPacket *pPacket)
{
	CString chatHeader = pPacket->m_UserInfo.m_strName;//发送消息的用户名称

	//格式化日期和时间
	CTime timeChatting(pPacket->m_time);				
	int year = timeChatting.GetYear();
	int month = timeChatting.GetMonth();
	int day = timeChatting.GetDay();
	int hour = timeChatting.GetHour();
	int minute = timeChatting.GetMinute();
	int second = timeChatting.GetSecond();
	CString chatTime;
	chatTime.Format(" (%d-%d-%d  %d:%d:%d)", year, month, day, hour, minute, second);

	//显示消息头
	chatHeader += chatTime;
	CString strItem = chatHeader + "\r\n"+ pPacket->m_strMsg + "\r\n";

	//显示消息
	int len = m_ctlOutput.GetWindowTextLength();
	m_ctlOutput.SetSel(len,len);
	m_ctlOutput.ReplaceSel(strItem);

}

/*
 * 处理键盘消息
 */
BOOL CChatDlg::PreTranslateMessage(MSG* pMsg) 
{
	if(pMsg->hwnd == m_ctlInput.GetSafeHwnd())	//输入消息窗口    
	{  
		if (pMsg->wParam == VK_RETURN)			//return键  
		{ 		
			if (TRUE == m_bOfflineWnd )			//显示离线消息窗口
			{
				return TRUE;

			}else								//在线/离线聊天窗口
			{
				SendPeerMessage();				//发送消息
				m_ctlInput.SetWindowText("");	//清空输入消息窗口内容
			}

			return TRUE;
		}  
	}  
	return CDialog::PreTranslateMessage(pMsg); //其他消息
}


/*
 * 发送消息
 */
void CChatDlg::SendPeerMessage( void )
{
	//输入消息窗口内容为空
	if (0 == m_ctlInput.GetWindowTextLength())
	{
		return;
	}
	
	//对方在线
	if(m_PeerInfo.m_eStatus == CUserInfo::ONLINE)	//发送在线消息
	{
		CChatPacket packet;
		packet.m_UserInfo = this->m_UserInfo;		//发送消息用户名称
		packet.m_type = CChatPacket::MESSAGE;		//包的类型
		m_ctlInput.GetWindowText(packet.m_strMsg);	//消息
		packet.m_time = CTime::GetCurrentTime();	//发包时间
		
		//发送消息
		m_pArchiveOut = new CArchive(m_pFile,CArchive::store);//创建写入文档对象	
		packet.Serialize(*m_pArchiveOut);
		m_pArchiveOut->Flush();
		delete m_pArchiveOut;
		m_pArchiveOut = NULL;	
		
		//显示发送的消息
		DisplaySentMessage(&packet);

	}else//对方离线
	{
		//显示发送的离线消息
		DisplaySentMessage();
	}	
	
}


/*
 * 显示发送的消息
 */
void CChatDlg::DisplaySentMessage(CChatPacket *pPacket)
{
	CString chatHeader = pPacket->m_UserInfo.m_strName;	//发送消息用户名称

	//格式化发送消息的时间
	CTime timeChatting =  pPacket->m_time;				
	int year = timeChatting.GetYear();		//年
	int month = timeChatting.GetMonth();	//月
	int day = timeChatting.GetDay();		//日
	int hour = timeChatting.GetHour();		//时
	int minute = timeChatting.GetMinute();	//分
	int second = timeChatting.GetSecond();	//秒
	CString chatTime;
	chatTime.Format(" (%d-%d-%d  %d:%d:%d)", year, month, day, hour, minute, second);
	
	chatHeader += chatTime;//消息头
	//获取输入消息
	CString strMsg;
	m_ctlInput.GetWindowText(strMsg);

	//消息头与消息分行显示
	CString strItem = chatHeader + "\r\n"+ pPacket->m_strMsg + "\r\n";

	//在当前消息行下面显示消息
	int len = m_ctlOutput.GetWindowTextLength();//当前文本长度
	m_ctlOutput.SetSel(len,len);				//移动插入符到当前文本最后
	m_ctlOutput.ReplaceSel(strItem);			//在当前文本后插入消息
}

/*
 * 显示发送的消息
 */
void CChatDlg::DisplaySentMessage(void)
{
	CString chatHeader = m_UserInfo.m_strName;
	CTime timeChatting =  CTime::GetCurrentTime();
	int year = timeChatting.GetYear();		//年
	int month = timeChatting.GetMonth();	//月
	int day = timeChatting.GetDay();		//日
	int hour = timeChatting.GetHour();		//时
	int minute = timeChatting.GetMinute();	//分
	int second = timeChatting.GetSecond();	//秒
	CString chatTime;
	chatTime.Format(" (%d-%d-%d  %d:%d:%d)", year, month, day, hour, minute, second);

	
	chatHeader += chatTime;//消息头

	CString strMsg;
	m_ctlInput.GetWindowText(strMsg);
	CString strItem = chatHeader + "\r\n"+ strMsg + "\r\n";

	//显示消息
	int len = m_ctlOutput.GetWindowTextLength();
	m_ctlOutput.SetSel(len,len);
	m_ctlOutput.ReplaceSel(strItem);

}


void CChatDlg::InitArchive(void)
{
	//初始化输入和输出流
	m_pFile = new CSocketFile(m_pSocket);					//初始化CSocketFile
	m_pArchiveIn = new CArchive(m_pFile,CArchive::load);	//初始化读入流
}

void CChatDlg::SetPeerInfor( CUserInfo &peerInfo )
{
	m_PeerInfo = peerInfo;
}

void CChatDlg::SetUserInfor( CUserInfo &userInfo )
{
	m_UserInfo = userInfo;
}


void CChatDlg::OnDestroy() 
{
	m_ctlOutput.GetWindowText(m_strRec);//聊天记录
	CDialog::OnDestroy();

}

CChatDlg::~CChatDlg()
{
	if(FALSE == m_bOfflineWnd)
	{
		if (NULL != m_pArchiveIn)
		{
			delete m_pArchiveIn;
			m_pArchiveIn = NULL;
		}
		if (NULL != m_pFile)
		{
			delete m_pFile;
			m_pFile = NULL;
		}	
		
		if (NULL != m_pSocket)
		{
			delete m_pSocket;
			m_pSocket = NULL;
		}		
	}
}

CChatSocket *CChatDlg::GetChatSocket( void )
{
	return m_pSocket;
}

/*
 * 显示离线消息
 */
void CChatDlg::DisplayOfflineMessage( CChatPacket *pPacket )
{
	CRect inputWndRect;
	m_ctlInput.GetWindowRect(&inputWndRect);//获取输入消息窗口区域		
	m_ctlInput.MoveWindow(0, 0, 0, 0);		//设置该窗口大小为0
	
	CRect chatDlgRect;
	GetClientRect(&chatDlgRect);			//获取对话框客户区大小
	MoveWindow(0, 0, chatDlgRect.Width(),	//修改对话框的高度
		chatDlgRect.Height() - inputWndRect.Height());
	
	GetClientRect(&chatDlgRect);			//获取对话框客户区大小
	m_ctlOutput.MoveWindow(5, 5,			//修改显示消息窗口高度
		chatDlgRect.Width() -10, chatDlgRect.Height() -10);
	
	m_PeerInfo = pPacket->m_UserInfo;								//发送消息用户名称							
	SetWindowText(m_PeerInfo.m_strName + _T("发送给您的离线消息"));	 //设置标题
	m_ctlOutput.SetWindowText(pPacket->m_strMsg );					//设置消息
}
void CChatDlg::OnBnClickedButton3()
{	CString cs;

	m_ctlInput.GetWindowText(cs);
	//pEdit->GetSel(0,-1);
	if (cs.IsEmpty())
	{
		AfxMessageBox("ERROR",0,0);
	}
	AfxMessageBox(cs,0,0);
	// TODO: 在此添加控件通知处理程序代码
}

⌨️ 快捷键说明

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