www.pudn.com > ChatSystem_src.zip > ChatClientDoc.cpp


// ChatClientDoc.cpp : implementation of the CChatClientDoc class 
// 
 
#include "stdafx.h" 
#include "ChatClient.h" 
 
#include "ChatClientDoc.h" 
 
#include "LogonDlg.h" 
 
#include "LeftView.h" 
#include "MessageView.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define JOINING_CHAT          1 
#define LEAVING_CHAT          2 
#define SENDING_CHATTERS_LIST 3 
#define SENDING_NICKNAME      4 
#define NORMAL_MESSAGE        5 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CChatClientDoc 
 
IMPLEMENT_DYNCREATE(CChatClientDoc, CDocument) 
 
BEGIN_MESSAGE_MAP(CChatClientDoc, CDocument) 
	//{{AFX_MSG_MAP(CChatClientDoc) 
	ON_COMMAND(ID_CONNECT, OnConnect) 
	ON_UPDATE_COMMAND_UI(ID_CONNECT, OnUpdateConnect) 
	ON_UPDATE_COMMAND_UI(ID_DISCONNECT, OnUpdateDisconnect) 
	ON_COMMAND(ID_DISCONNECT, OnDisconnect) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CChatClientDoc construction/destruction 
 
CChatClientDoc::CChatClientDoc() 
{ 
	// TODO: add one-time construction code here 
	bIsConnected = FALSE; 
	m_pSocket = NULL; 
	m_pFile = NULL; 
	m_pArchiveOut = NULL; 
	m_pArchiveIn = NULL; 
} 
 
CChatClientDoc::~CChatClientDoc() 
{ 
} 
 
BOOL CChatClientDoc::OnNewDocument() 
{ 
	if (!CDocument::OnNewDocument()) 
		return FALSE; 
 
	// TODO: add reinitialization code here 
	// (SDI documents will reuse this document) 
 
 
	return TRUE; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CChatClientDoc serialization 
 
void CChatClientDoc::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		for(POSITION pos=GetFirstViewPosition();pos!=NULL;) 
		{ 
			CView* pView = GetNextView(pos); 
			CMessageView* pChatView = DYNAMIC_DOWNCAST(CMessageView, pView); 
 
			if (pChatView != NULL) 
				pChatView->Serialize(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() 
{ 
 
	if ((m_pSocket != NULL) && (m_pFile != NULL) && (m_pArchiveOut != NULL)) 
	{ 
		CMsg msg; 
		CString strTemp; 
 
		if (strTemp.LoadString(IDS_DISCONNECT)) 
		{ 
			SendMsg(m_strHandle, LEAVING_CHAT, false); 
 
			msg.code = NORMAL_MESSAGE; 
			msg.m_bClose = TRUE; 
			msg.m_strText = m_strHandle + 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(); 
 
		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(CMessageView))) 
		{ 
			CMessageView* pChatView = (CMessageView*)pView; 
			pChatView->GetEditCtrl().SetWindowText(_T("")); 
		} 
	} 
 
	CDocument::DeleteContents(); 
} 
 
 
BOOL CChatClientDoc::ConnectSocket(LPCTSTR lpszHandle, LPCTSTR lpszAddress, UINT nPort) 
{ 
	m_strHandle = lpszHandle; 
 
	m_pSocket = new CChatSocket(this); 
 
	if (!m_pSocket->Create()) 
	{ 
		delete m_pSocket; 
		m_pSocket = NULL; 
		AfxMessageBox(IDS_CREATEFAILED); 
		return FALSE; 
	} 
 
	while (!m_pSocket->Connect(lpszAddress, nPort + 1500)) // 700 
	{ 
		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); 
 
	 
	SendMsg(m_strHandle, SENDING_NICKNAME, false); 
	 
	CString strTemp; 
	if (strTemp.LoadString(IDS_CONNECT)) 
		SendMsg(strTemp, NORMAL_MESSAGE, true); 
 
	return TRUE; 
} 
 
void CChatClientDoc::ProcessPendingRead() 
{ 
	do 
	{ 
		ReceiveMsg(); 
		if (m_pSocket == NULL) 
			return; 
	} 
	while(!m_pArchiveIn->IsBufferEmpty()); 
} 
 
void CChatClientDoc::SendMsg(CString& strText, UINT mCode, BOOL bSendHandle) 
{ 
	if (m_pArchiveOut != NULL) 
	{ 
		CMsg msg; 
 
		msg.code = mCode; 
 
		msg.m_strText = (bSendHandle ? m_strHandle + _T(": ") + strText : strText); 
 
		TRY 
		{ 
			msg.Serialize(*m_pArchiveOut); 
			m_pArchiveOut->Flush(); 
		} 
		CATCH(CFileException, e) 
		{ 
			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); 
 
		if(msg.code == SENDING_CHATTERS_LIST) 
		{ 
			UpdateChattersList(&msg); 
		} 
 
		while(!msg.m_msgList.IsEmpty()) 
		{ 
			CString temp = msg.m_msgList.RemoveHead(); 
			DisplayMsg(temp); 
		} 
 
	} 
	CATCH(CFileException, e) 
	{ 
		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) 
	{ 
		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); 
		CMessageView* pChatView = DYNAMIC_DOWNCAST(CMessageView, pView); 
 
		if (pChatView != NULL) 
			pChatView->Message(lpszText); 
	} 
} 
 
void CChatClientDoc::UpdateChattersList(CMsg* pMsg) 
{ 
 
	CLeftView* pChatView; 
 
	for(POSITION pos=GetFirstViewPosition();pos!=NULL;) 
	{ 
		CView* pView = GetNextView(pos); 
		pChatView = DYNAMIC_DOWNCAST(CLeftView, pView); 
 
		if (pChatView != NULL) 
			pChatView->ClearChattersList(); 
	} 
	 
	while(!pMsg->m_chattersList.IsEmpty()) 
	{ 
		if(pChatView != NULL) 
			pChatView->AddToChattersList(pMsg->m_chattersList.RemoveHead()); 
	} 
 
} 
 
 
void CChatClientDoc::OnConnect()  
{ 
	// TODO: Add your command handler code here 
	CLogonDlg dlg; 
	dlg.m_NickName = _T("Barry"); 
	dlg.m_Port = 0; 
	dlg.m_Server = _T("127.0.0.1"); 
 
	while(TRUE) 
	{ 
		if (IDOK != dlg.DoModal()) 
			return; 
 
		if (ConnectSocket(dlg.m_NickName, dlg.m_Server, dlg.m_Port)) 
		{ 
			bIsConnected = TRUE; 
			return; 
		} 
 
		if (AfxMessageBox(IDS_CHANGEADDRESS,MB_YESNO) == IDNO) 
			return ; 
	} 
		 
} 
 
void CChatClientDoc::OnUpdateConnect(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
 
	pCmdUI->Enable(!bIsConnected); 
} 
 
void CChatClientDoc::OnUpdateDisconnect(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(bIsConnected);	 
} 
 
void CChatClientDoc::OnDisconnect()  
{ 
	// TODO: Add your command handler code here 
	DeleteContents(); 
	bIsConnected = FALSE; 
} 
 
void CChatClientDoc::ClearMessages() 
{ 
 
}