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

📄 chatclientdoc.cpp

📁 一个基于vc++的c/s架构的网络教学答疑系统。我的软件工程上机报告。
💻 CPP
字号:
// ChatClientDoc.cpp : implementation of the CChatClientDoc class
//

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

#include "ChatClientDoc.h"
#include "CntrItem.h"
#include "ChatSocket.h"
#include "chatclientview.h"
#include "MainFrm.h"

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

#define SAFEDELETE(x) if(x!=NULL){delete x;x=NULL;}
#define WM_ADDLIST    WM_USER + 1001

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

IMPLEMENT_DYNCREATE(CChatClientDoc, CRichEditDoc)

BEGIN_MESSAGE_MAP(CChatClientDoc, CRichEditDoc)
	//{{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
	// Enable default OLE container implementation
	ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, CRichEditDoc::OnUpdateEditLinksMenu)
	ON_COMMAND(ID_OLE_EDIT_LINKS, CRichEditDoc::OnEditLinks)
	ON_UPDATE_COMMAND_UI_RANGE(ID_OLE_VERB_FIRST, ID_OLE_VERB_LAST, CRichEditDoc::OnUpdateObjectVerbMenu)
END_MESSAGE_MAP()

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

CChatClientDoc::CChatClientDoc()
{
	m_bConnected = FALSE;
	m_pSocket = NULL;
	m_pFile = NULL;
	m_pArchiveIn = NULL;
	m_pArchiveOut = NULL;
	m_bFilter = FALSE;
}

CChatClientDoc::~CChatClientDoc()
{
	msg.type = -2;
	msg.m_bClose = TRUE;
	msg.from = m_strHandle;
	msg.to = "所有人";
	msg.secret = FALSE;
	msg.m_strText ="Hello";
	msg.color = RGB(0,136,255);
	msg.major = (WORD)atoi(m_strMajor);
	msg.type1 = (WORD)atoi(m_strType);
	SendMsg();

	SAFEDELETE(m_pArchiveIn);
	SAFEDELETE(m_pArchiveOut);
	SAFEDELETE(m_pFile);
	SAFEDELETE(m_pSocket);
}

BOOL CChatClientDoc::OnNewDocument()
{
	if (!CRichEditDoc::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}

CRichEditCntrItem* CChatClientDoc::CreateClientItem(REOBJECT* preo) const
{
	// cast away constness of this
	return new CChatClientCntrItem(preo, (CChatClientDoc*) this);
}

/////////////////////////////////////////////////////////////////////////////
// CChatClientDoc serialization

void CChatClientDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}

	// Calling the base class CRichEditDoc enables serialization
	//  of the container document's COleClientItem objects.
	// TODO: set CRichEditDoc::m_bRTF = FALSE if you are serializing as text
	CRichEditDoc::Serialize(ar);
}

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

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

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

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

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

BOOL CChatClientDoc::ConnectSocket(LPCTSTR lpszHandle, LPCTSTR lpszAddress, 
				LPCTSTR m_strImage, LPCTSTR lpszMajor, LPCTSTR lpszType, UINT nPort)
{
	if(m_bConnected)
		return FALSE;
	m_strHandle = lpszHandle; //姓名
	m_strMajor = lpszMajor; //专业名
	m_strType = lpszType;  //论坛类型

	SAFEDELETE(m_pArchiveIn);
	SAFEDELETE(m_pArchiveOut);
	SAFEDELETE(m_pFile);
	SAFEDELETE(m_pSocket);

	if(m_pSocket == NULL){
		m_pSocket = new CChatSocket(this);
		ASSERT(m_pSocket != NULL);
	}

	if (!m_pSocket->Create())
	{
		delete m_pSocket;
		m_pSocket = NULL;
		TRACE("Create Socket Error!\n");
		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);
	
	msg.type = -1;
	msg.m_bClose = FALSE;
	msg.from = m_strHandle;
	msg.to = "所有人";
	msg.secret = FALSE;
	msg.m_strText ="Hello";
	msg.color = RGB(0,136,255); 
	msg.image = atoi(m_strImage);
	msg.major = atoi(m_strMajor);
	msg.type1 = atoi(m_strType);
	CString strWindowText;
	switch(msg.type1)
	{
	case 1:	strWindowText = m_strHandle + "(" + "硬件论坛" + ")";break;
	case 2:	strWindowText = m_strHandle + "(" + "软件论坛" + ")";break;
	case 3:	strWindowText = m_strHandle + "(" + "应用论坛" + ")";
	}

	SendMsg();
	m_bConnected = TRUE;
	GetView()->GetParent()->SetWindowText(strWindowText);
	return TRUE;
}

void CChatClientDoc::SendMsg()
{
	msg.from = m_strHandle;
	msg.major = (WORD)atoi(m_strMajor);
	msg.type1 = (WORD)atoi(m_strType);
	if (m_pArchiveOut != NULL)
	{
		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::DisplayMsg(LPCTSTR lpszText)
{
	CChatClientView* pView = (CChatClientView*)GetView();

	if(pView != NULL)
		pView->TextOut(lpszText, RGB(128,0,0));
}

void CChatClientDoc::ReceiveMsg()
{
	TRY
	{
		msg.Serialize(*m_pArchiveIn);
		if(msg.type1 != (WORD)atoi(m_strType)) return ;
		DisplayRecMsg(msg.type, msg.from, msg.to, msg.secret, 
				msg.m_strText, msg.color);
		if(msg.type == -7 || msg.type == -2 || msg.type == -9)
			m_bConnected = FALSE;
		if(msg.type == -9)
			DisplayMsg("该用户名已经有人使用,请更名重新登录!\n");
	}
	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 && (msg.from == m_strHandle)){
		SAFEDELETE(m_pArchiveIn);
		SAFEDELETE(m_pArchiveOut);
		SAFEDELETE(m_pFile);
		SAFEDELETE(m_pSocket);
		m_bConnected = FALSE;
	}
	CString strText, strMajor;
	switch(((WORD)atoi(m_strMajor)))
	{
	case 1:	strText = m_strHandle + ", " + "硬件";break;
	case 2:	strText = m_strHandle + ", " + "软件";break;
	case 3:	strText = m_strHandle + ", " + "应用";
	}	
	if((msg.type == -1 && msg.from != m_strHandle) || (msg.type == -8)){
		switch(msg.type1)
		{
			case 1:	strText = msg.from + ", " + "硬件";break;
			case 2:	strText = msg.from + ", " + "软件";break;
			case 3:	strText = msg.from + ", " + "应用";
		}
		GetView()->GetParent()->SendMessage(WM_ADDLIST, (LPARAM)&(strText), msg.image);
	}
	if((msg.type == -7) || (msg.type == -2)){
		GetView()->GetParent()->SendMessage(WM_ADDLIST + 1, (LPARAM)&(msg.from), msg.image);
	}
}

void CChatClientDoc::DisplayRecMsg(int type, CString from, CString to,
		BOOL sec, CString str, COLORREF clr)
{
	CChatClientView* pView = (CChatClientView*)GetView();
	
	if (msg.type1 != (WORD)atoi(m_strType)) return ;
	if(type == -7){
		pView->TextOut(_T("系统:聊天室掌门人以一招'佛山无影脚',将"),RGB(0,0,0));
		if(from == m_strHandle){
			pView->TextOut(_T("你"),RGB(0,0,255));
		}
		else
			pView->TextOut(from,RGB(0,0,255));
		pView->TextOut(_T("踢出门外\r\n"),RGB(0,0,0));
	}   
	if(type == -5){
		return;	
	}
	if(type == -3){
		pView->TextOut(_T("系统:服务器已关闭!"),RGB(0,0,0));
		return;
	}
	if(type == -1 ){
		pView->TextOut(from, RGB(0,0,255));
		pView->TextOut(_TEXT("风尘仆仆地推门而入\r\n"),RGB(255,0,0));
		
	}
	if(type == -2){
		pView->TextOut(from, RGB(0,0,255));
		pView->TextOut(_TEXT("静静地离开了,孤单的背影显得格外潇洒\r\n"),RGB(255,0,0));
	}
	if(type >= 0){
		if(from == m_strHandle || to == m_strHandle || sec == FALSE || to =="所有人")
			talk(type, from, to, str, clr);			
	}
}

void CChatClientDoc::talk(int type, CString form, CString to,
						  CString str, COLORREF clr)
{
	CChatClientView* pView = (CChatClientView*)GetView();
	
	if(form != m_strHandle && to != m_strHandle && m_bFilter)
		return;
	CString temp,to2,first,second;
	
	if(type > 32 || type < 0) 
		return;  
	temp.LoadString(IDS_TALK0 + type);	
	int i=temp.Find(",");
	if(i != -1){
		first = temp.Left(i);
		if(i != temp.GetLength() - 1){
			second = temp.Mid(i + 1);
			second += ":";
		}
		else{
			second=":";
		}
		pView->TextOut((LPCTSTR)form, RGB(0,0,255));
		pView->TextOut((LPCTSTR)first, RGB(0,0,0));
		pView->TextOut((LPCTSTR)to, RGB(0,0,255));
		pView->TextOut((LPCTSTR)second, RGB(0,0,0));
		pView->TextOut((LPCTSTR)str,clr);
		pView->TextOut((LPCTSTR)"\r\n",clr);
	}
	else{
		first=temp;
		second=": ";
		pView->TextOut(form,RGB(0,0,255));
		pView->TextOut(first,RGB(0,0,0));
		pView->TextOut(second,RGB(0,0,0));
		pView->TextOut(str,clr);
		pView->TextOut("\r\n",clr);
	}
}

void CChatClientDoc::Disconnect()
{
	msg.type = -2;
	msg.m_bClose = TRUE;
	msg.from = m_strHandle;
	msg.to = "所有人";
	msg.secret = FALSE;
	msg.m_strText ="Hello";
	msg.color = RGB(0,136,255);
	msg.major = (WORD)atoi(m_strMajor);
	msg.type1 = (WORD)atoi(m_strType);

	SendMsg();
	m_bConnected = FALSE;
	msg.from = "DUMP";
	GetView()->GetParent()->SetWindowText("网上论坛");
	CComboBox* pTo = (CComboBox*)((CMainFrame*)GetView()->GetParent())->m_wndSend.GetDlgItem(IDC_TO);
	pTo->Clear();
	GetView()->GetParent()->SendMessage(WM_ADDLIST + 1, (LPARAM)&(msg.from), msg.image);
}

BOOL CChatClientDoc::CanCloseFrame(CFrameWnd* pFrame) 
{
	// TODO: Add your specialized code here and/or call the base class
	SetModifiedFlag(FALSE);
	return CRichEditDoc::CanCloseFrame(pFrame);
}

⌨️ 快捷键说明

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