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

📄 chatclientdoc.cpp

📁 基于C/S模式
💻 CPP
字号:
// ChatClientDoc.cpp : implementation of the CChatClientDoc class
//

#include "stdafx.h"
#include "ChatClient.h"

#include "ClientSocket.h"//添加的语句
#include "ChatClientDoc.h"
#include "ChatClientView.h" //添加的语句

#include "SetupDlg.h"//添加的语句
#include "Msg.h"//添加的语句

#ifdef _WIN32
#ifndef _UNICODE

#include <strstrea.h> //注意2

#endif
#endif

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

/////////////////////////////////////////////////////////////////////////////
// CChatClientDoc

IMPLEMENT_DYNCREATE(CChatClientDoc, CDocument)

BEGIN_MESSAGE_MAP(CChatClientDoc, CDocument)
	//{{AFX_MSG_MAP(CChatClientDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChatClientDoc construction/destruction

CChatClientDoc::CChatClientDoc()
{
	// TODO: add one-time construction code here
	m_bAutoChat = FALSE;
	m_pSocket = NULL;
	m_pFile = NULL;
	m_pArchiveIn = NULL;
	m_pArchiveOut = NULL;
}

CChatClientDoc::~CChatClientDoc()
{
}

BOOL CChatClientDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;
	
	CSetupDlg Dialog;
	Dialog.m_strName=m_strName;
	Dialog.m_strAdress=_T("");
	Dialog.m_nPort=5000;

	while(TRUE)
	{
		if (IDOK != Dialog.DoModal())
			return FALSE;

		if (ConnectSocket(Dialog.m_strName, 
			Dialog.m_strAdress, Dialog.m_nPort))
			return TRUE;

		if (AfxMessageBox("是否连接其他地址?",MB_YESNO) == IDNO)
			return FALSE;
	}
}


void CChatClientDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
		{
			CView* pView = GetNextView(pos);
			CChatClientView* pChatClientView = 
				DYNAMIC_DOWNCAST(CChatClientView, pView);

			if (pChatClientView != NULL)
				pChatClientView->SerializeRaw(ar);
		}  //可以保存聊天的记录
	}
}

/////////////////////////////////////////////////////////////////////////////
// CChatClientDoc diagnostics

#ifdef _DEBUG
void CChatClientDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CChatClientDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CChatClientDoc commands

void CChatClientDoc::DeleteContents() 
{
		m_bAutoChat = FALSE;

	//发送给服务器表示终止的信息
	if ((m_pSocket != NULL) && (m_pFile != NULL) 
		&& (m_pArchiveOut != NULL))
	{
		CMsg msg;
		CString strTemp;

		if (strTemp.LoadString(IDS_DISCONNECT))
		{
			msg.m_bClose = TRUE;
			msg.m_strText = m_strName + strTemp;
			msg.Serialize(*m_pArchiveOut);
			m_pArchiveOut->Flush();
		}
	}
	//释放空间
	delete m_pArchiveOut;
	m_pArchiveOut = NULL;
	delete m_pArchiveIn;
	m_pArchiveIn = NULL;
	delete m_pFile;
	m_pFile = NULL;
	
	if (m_pSocket != NULL)
	{
		BYTE Buffer[50];
		m_pSocket->ShutDown();
		m_pSocket->Close();
		while(m_pSocket->Receive(Buffer,50) > 0);
	}
	delete m_pSocket;
	m_pSocket = NULL;

	//给显示视类窗口清空
	for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
	{
		CView* pView = GetNextView(pos);

		if (pView->IsKindOf(RUNTIME_CLASS(CChatClientView)))
		{
			CChatClientView* pChatClientView = (CChatClientView*)pView;
			pChatClientView->GetEditCtrl().SetWindowText(_T(""));
		}
	}

	CDocument::DeleteContents();
}

//自己定义的函数的实现
BOOL CChatClientDoc::ConnectSocket(LPCTSTR lpszHandle, LPCTSTR lpszAddress, UINT nPort)
{
	m_strName=lpszHandle;   
	
 	m_pSocket = new CClientSocket(this); //注意4:构造函数的参数

	if (!m_pSocket->Create())
	{
  		delete m_pSocket;
		m_pSocket = NULL;
		AfxMessageBox(IDS_CREATEFAILED);
		return FALSE;
	}

	//可以重试
	while (!m_pSocket->Connect(lpszAddress, nPort))
	{
		if (AfxMessageBox(IDS_RETRYCONNECT,MB_YESNO) == IDNO)
		{
			delete m_pSocket;
			m_pSocket = NULL;
			return FALSE;
		}
	}

	
	m_pFile = new CSocketFile(m_pSocket);
	m_pArchiveIn = new CArchive(m_pFile,CArchive::load);
	m_pArchiveOut = new CArchive(m_pFile,CArchive::store);
		//已经生成了基本的四个指针

	CString strTemp;
	if (strTemp.LoadString(IDS_CONNECT))
		SendMsg(strTemp); //发送已经登录的消息给服务器

	return TRUE;
}

void CChatClientDoc::ProcessPendingRead()
{
	do
	{
		ReceiveMsg();
		if (m_pSocket == NULL)
			return;
	}
	while(!m_pArchiveIn->IsBufferEmpty());
}

void CChatClientDoc::SendMsg(CString& strText)
{
	if (m_pArchiveOut != NULL)
	{
		CMsg msg;

		msg.m_strText = m_strName + _T(": ") + strText;

		TRY
		{
			msg.Serialize(*m_pArchiveOut);
			m_pArchiveOut->Flush();
		}
		CATCH(CFileException, e)
		{
			m_bAutoChat = FALSE;
			m_pArchiveOut->Abort();
			delete m_pArchiveOut;
			m_pArchiveOut = NULL;

			CString strTemp;
			if (strTemp.LoadString(IDS_SERVERRESET))
				DisplayMsg(strTemp);
		}
		END_CATCH
	}
}

void CChatClientDoc::ReceiveMsg()
{
	CMsg msg;

	TRY
	{
		msg.Serialize(*m_pArchiveIn);

		while(!msg.m_msgList.IsEmpty())
		{
			CString temp = msg.m_msgList.RemoveHead();
			DisplayMsg(temp);
		}

	}
	CATCH(CFileException, e)
	{
		m_bAutoChat = FALSE;
		msg.m_bClose = TRUE;
		m_pArchiveOut->Abort();

		CString strTemp;
		if (strTemp.LoadString(IDS_SERVERRESET))
			DisplayMsg(strTemp);
		if (strTemp.LoadString(IDS_CONNECTIONCLOSED))
			DisplayMsg(strTemp);
	}
	END_CATCH

	if (msg.m_bClose)  //注意5:是在这里完成的关闭四个基本指针
	{
		delete m_pArchiveIn;
		m_pArchiveIn = NULL;
		delete m_pArchiveOut;
		m_pArchiveOut = NULL;
		delete m_pFile;
		m_pFile = NULL;
		delete m_pSocket;
		m_pSocket = NULL;
	}
}

void CChatClientDoc::DisplayMsg(LPCTSTR lpszText)
{
	for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
	{
		CView* pView = GetNextView(pos);
		CChatClientView* pChatClientView = DYNAMIC_DOWNCAST
			(CChatClientView, pView);

		if (pChatClientView != NULL)
			pChatClientView->Message(lpszText);
	}
}

⌨️ 快捷键说明

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