?? chatclientdoc.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 + -