chatclientdoc.cpp
来自「一个简易的聊天室程序」· C++ 代码 · 共 437 行
CPP
437 行
#include "stdafx.h"
#include "ChatClient.h"
#include "ChatClientDoc.h"
#include "LogonDlg.h"
#include "LeftView.h"
#include "ChatViewRE.h"
#include "PrivateMsgDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CString m_strHandle;
/////////////////////////////////////////////////////////////////////////////
// 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()
{
bIsConnected = FALSE;
m_pSocket = NULL;
m_pFile = NULL;
m_pArchiveOut = NULL;
m_pArchiveIn = NULL;
m_stdCF.cbSize = sizeof(CHARFORMAT);
m_stdCF.dwMask = CFM_BOLD|CFM_SIZE|CFM_COLOR;
m_stdCF.dwEffects = CFE_AUTOCOLOR | FW_NORMAL;
m_stdCF.yHeight = 200;
m_stdCF.yOffset = 0;
m_stdCF.crTextColor = RGB(0,0,0);
m_stdCF.bCharSet = 0;
m_stdCF.bPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
strcpy(m_stdCF.szFaceName , "Arial");
}
CChatClientDoc::~CChatClientDoc()
{
}
BOOL CChatClientDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CChatClientDoc serialization
void CChatClientDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
{
CView* pView = GetNextView(pos);
CChatViewRE* pChatView = DYNAMIC_DOWNCAST(CChatViewRE, 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 , m_stdCF);
msg.m_dwMask = m_stdCF.dwMask;
msg.m_dwEffects = m_stdCF.dwEffects;
msg.m_yHeight = m_stdCF.yHeight;
msg.m_yOffset = m_stdCF.yOffset;
msg.m_crTextColor = m_stdCF.crTextColor;
msg.m_bCharSet = m_stdCF.bCharSet;
msg.m_bPitchAndFamily = m_stdCF.bPitchAndFamily;
msg.m_szFaceName = m_stdCF.szFaceName;
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(CChatViewRE)))
{
CChatViewRE* pChatView = (CChatViewRE*)pView;
pChatView->GetRichEditCtrl().SetWindowText(_T(""));
}
if (pView->IsKindOf(RUNTIME_CLASS(CLeftView)))
{
CLeftView* pLeftView = (CLeftView*)pView;
pLeftView->ClearChattersList();
}
}
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, m_stdCF);
CString strTemp;
if (strTemp.LoadString(IDS_CONNECT))
SendMsg(strTemp, NORMAL_MESSAGE, true, m_stdCF);
return TRUE;
}
void CChatClientDoc::ProcessPendingRead()
{
do
{
ReceiveMsg();
if (m_pSocket == NULL)
return;
}
while(!m_pArchiveIn->IsBufferEmpty());
}
void CChatClientDoc::ReceiveMsg()
{
CMsg msg;
CString temp;
TRY
{
msg.Serialize(*m_pArchiveIn);
if(msg.code == SENDING_CHATTERS_LIST)
{
UpdateChattersList(&msg);
}
if(msg.code == DUPLICATE_NICKNAME)
{
AfxMessageBox(msg.m_strText);
msg.m_bClose = TRUE;
OnDisconnect();
}
if(msg.code == PRIVATE_MESSAGE)
{
CWnd* wnd;
for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
{
CView* pView = GetNextView(pos);
if (pView->IsKindOf(RUNTIME_CLASS(CLeftView)))
wnd = (CWnd*)pView;
}
CPrivateMsgDlg* dlg = new CPrivateMsgDlg(wnd , TRUE , msg.m_strText);
dlg->Create();
dlg->ShowWindow(SW_SHOW);
}
if(msg.code == KICK_USER)
{
temp.LoadString(IDS_KICKED);
msg.m_bClose = TRUE;
}
while(!msg.m_msgList.IsEmpty())
{
temp = msg.m_msgList.RemoveHead();
CHARFORMAT cf;
cf.cbSize = sizeof(CHARFORMAT);
cf.dwMask = msg.m_dwMask;
cf.dwEffects = msg.m_dwEffects;
cf.yHeight = msg.m_yHeight;
cf.yOffset = msg.m_yOffset;
cf.crTextColor = msg.m_crTextColor;
cf.bCharSet = msg.m_bCharSet;
cf.bPitchAndFamily = msg.m_bPitchAndFamily;
strcpy(cf.szFaceName , msg.m_szFaceName);
DisplayMsg(temp, cf);
}
}
CATCH(CFileException, e)
{
msg.m_bClose = TRUE;
m_pArchiveOut->Abort();
CString strTemp;
if (strTemp.LoadString(IDS_SERVERRESET))
DisplayMsg(strTemp, m_stdCF);
if (strTemp.LoadString(IDS_CONNECTIONCLOSED))
DisplayMsg(strTemp, m_stdCF);
}
END_CATCH
if (msg.m_bClose)
{
AfxMessageBox(temp);
OnDisconnect();
}
}
void CChatClientDoc::DisplayMsg(LPCTSTR lpszText, CHARFORMAT cf)
{
for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
{
CView* pView = GetNextView(pos);
CChatViewRE* pChatView = DYNAMIC_DOWNCAST(CChatViewRE, pView);
if (pChatView != NULL)
pChatView->message(lpszText, cf);
}
}
void CChatClientDoc::SendMsg(CString& strText, UINT mCode, BOOL bSendHandle , CHARFORMAT cf)
{
CMsg msg;
msg.m_dwMask = cf.dwMask;
msg.m_dwEffects = cf.dwEffects;
msg.m_yHeight = cf.yHeight;
msg.m_yOffset = cf.yOffset;
msg.m_crTextColor = cf.crTextColor;
msg.m_bCharSet = cf.bCharSet;
msg.m_bPitchAndFamily = cf.bPitchAndFamily;
msg.m_szFaceName = cf.szFaceName;
msg.code = mCode;
msg.m_strText = (bSendHandle ? m_strHandle + _T(": ") + strText : strText);
DespatchMsg(msg);
}
void CChatClientDoc::DespatchMsg(CMsg& msg)
{
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, m_stdCF);
}
END_CATCH
}
}
void CChatClientDoc::UpdateChattersList(CMsg* pMsg)
{
CLeftView* pLeftView;
POSITION pos;
for(pos=GetFirstViewPosition();pos!=NULL;)
{
CView* pView = GetNextView(pos);
pLeftView = DYNAMIC_DOWNCAST(CLeftView, pView);
if (pLeftView != NULL)
pLeftView->ClearChattersList();
}
while(!pMsg->m_chattersList.IsEmpty())
{
CString sNameSock = pMsg->m_chattersList.RemoveHead();
CString sName = sNameSock.Left(sNameSock.Find(":" , 0));
CString cSocket = sNameSock.Mid(sNameSock.Find(":", 0)+2);
if(pLeftView != NULL)
pLeftView->AddToChattersList(sName, cSocket);
}
}
void CChatClientDoc::OnConnect()
{
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)
{
pCmdUI->Enable(!bIsConnected);
}
void CChatClientDoc::OnUpdateDisconnect(CCmdUI* pCmdUI)
{
pCmdUI->Enable(bIsConnected);
}
void CChatClientDoc::OnDisconnect()
{
DeleteContents();
bIsConnected = FALSE;
}
void CChatClientDoc::ClearMessages()
{
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?