home *** CD-ROM | disk | FTP | other *** search
- // srvrdoc.cpp : implementation of the CServerDoc class
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
- #include "chatsrvr.h"
-
- #include "srvrdoc.h"
- #include "srvrvw.h"
-
- #include "msg.h"
- #include "dialogs.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerDoc
-
- IMPLEMENT_DYNCREATE(CServerDoc, CDocument)
-
- BEGIN_MESSAGE_MAP(CServerDoc, CDocument)
- //{{AFX_MSG_MAP(CServerDoc)
- //}}AFX_MSG_MAP
- ON_UPDATE_COMMAND_UI(ID_MESSAGES, OnUpdateMessages)
- ON_UPDATE_COMMAND_UI(ID_CONNECTIONS, OnUpdateConnections)
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerDoc construction/destruction
-
- CServerDoc::CServerDoc()
- {
- m_pSocket = NULL;
- }
-
- CServerDoc::~CServerDoc()
- {
- delete m_pSocket;
- }
-
- BOOL CServerDoc::OnNewDocument()
- {
- if (!CDocument::OnNewDocument())
- return FALSE;
-
- CDiscussionDlg Dialog;
-
- if (Dialog.DoModal() == IDOK)
- {
- m_pSocket = new CListeningSocket(this);
- if (m_pSocket->Create(Dialog.m_nPort+700))
- {
- if (m_pSocket->Listen())
- return TRUE;
- }
- }
- return FALSE;
- }
-
- void CServerDoc::DeleteContents()
- {
- delete m_pSocket;
- m_pSocket = NULL;
-
- CString temp;
- if (temp.LoadString(IDS_SERVERSHUTDOWN))
- m_msgList.AddTail(temp);
-
- while(!m_connectionList.IsEmpty())
- {
- CClientSocket* pSocket = (CClientSocket*)m_connectionList.RemoveHead();
- CMsg* pMsg = AssembleMsg(pSocket);
- pMsg->m_bClose = TRUE;
-
- SendMsg(pSocket, pMsg);
-
- if (!pSocket->IsAborted())
- {
- pSocket->ShutDown();
-
- BYTE Buffer[50];
-
- while (pSocket->Receive(Buffer,50) > 0);
-
- delete pSocket;
- }
- }
-
- m_msgList.RemoveAll();
-
- if (!m_viewList.IsEmpty())
- ((CEditView*)m_viewList.GetHead())->SetWindowText(_T(""));
-
- CDocument::DeleteContents();
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerDoc serialization
-
- void CServerDoc::Serialize(CArchive& ar)
- {
- if (ar.IsStoring())
- {
- // CEditView contains an edit control which handles all serialization
- ((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerDoc diagnostics
-
- #ifdef _DEBUG
- void CServerDoc::AssertValid() const
- {
- CDocument::AssertValid();
- }
-
- void CServerDoc::Dump(CDumpContext& dc) const
- {
- CDocument::Dump(dc);
- }
- #endif //_DEBUG
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerDoc Operations
-
- void CServerDoc::UpdateClients()
- {
- for(POSITION pos = m_connectionList.GetHeadPosition(); pos != NULL;)
- {
- CClientSocket* pSocket = (CClientSocket*)m_connectionList.GetNext(pos);
- CMsg* pMsg = AssembleMsg(pSocket);
-
- if (pMsg != NULL)
- SendMsg(pSocket, pMsg);
- }
- }
-
- void CServerDoc::ProcessPendingAccept()
- {
- CClientSocket* pSocket = new CClientSocket(this);
-
- if (m_pSocket->Accept(*pSocket))
- {
- pSocket->Init();
- m_connectionList.AddTail(pSocket);
- }
- else
- delete pSocket;
- }
-
- void CServerDoc::ProcessPendingRead(CClientSocket* pSocket)
- {
- do
- {
- CMsg* pMsg = ReadMsg(pSocket);
-
- if (pMsg->m_bClose)
- {
- CloseSocket(pSocket);
- break;
- }
- }
- while (!pSocket->m_pArchiveIn->IsBufferEmpty());
-
- UpdateClients();
- }
-
- CMsg* CServerDoc::AssembleMsg(CClientSocket* pSocket)
- {
- static CMsg msg;
-
- msg.Init();
-
- if (pSocket->m_nMsgCount >= m_msgList.GetCount())
- return NULL;
-
- for (POSITION pos1 = m_msgList.FindIndex(pSocket->m_nMsgCount); pos1 != NULL;)
- {
- CString temp = m_msgList.GetNext(pos1);
- msg.m_msgList.AddTail(temp);
- }
- pSocket->m_nMsgCount = m_msgList.GetCount();
- return &msg;
- }
-
- CMsg* CServerDoc::ReadMsg(CClientSocket* pSocket)
- {
- static CMsg msg;
-
- TRY
- {
- pSocket->ReceiveMsg(&msg);
-
- Message(msg.m_strText);
-
- m_msgList.AddTail(msg.m_strText);
- }
- CATCH(CFileException, e)
- {
- CString strTemp;
- if (strTemp.LoadString(IDS_READERROR))
- Message(strTemp);
-
- msg.m_bClose = TRUE;
- pSocket->Abort();
- }
- END_CATCH
-
- return &msg;
- }
-
- void CServerDoc::SendMsg(CClientSocket* pSocket, CMsg* pMsg)
- {
- TRY
- {
- pSocket->SendMsg(pMsg);
- }
- CATCH(CFileException, e)
- {
- pSocket->Abort();
-
- CString strTemp;
- if (strTemp.LoadString(IDS_SENDERROR))
- Message(strTemp);
- }
- END_CATCH
- }
-
- void CServerDoc::CloseSocket(CClientSocket* pSocket)
- {
- pSocket->Close();
-
- POSITION pos,temp;
- for(pos = m_connectionList.GetHeadPosition(); pos != NULL;)
- {
- temp = pos;
- CClientSocket* pSock = (CClientSocket*)m_connectionList.GetNext(pos);
- if (pSock == pSocket)
- {
- m_connectionList.RemoveAt(temp);
- break;
- }
- }
-
- delete pSocket;
- }
-
- void CServerDoc::Message(LPCTSTR lpszMessage)
- {
- ((CServerView*)m_viewList.GetHead())->Message(lpszMessage);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerDoc Handlers
-
- void CServerDoc::OnUpdateMessages(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(TRUE);
-
- CString strFmt;
- if (strFmt.LoadString(IDS_MESSAGESFMT))
- {
- CString strTemp;
- wsprintf(strTemp.GetBuffer(50),strFmt,m_msgList.GetCount());
- strTemp.ReleaseBuffer();
- pCmdUI->SetText(strTemp);
- }
- }
-
- void CServerDoc::OnUpdateConnections(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(TRUE);
-
- CString strFmt;
- if (strFmt.LoadString(IDS_CONNECTIONSFMT))
- {
- CString strTemp;
- wsprintf(strTemp.GetBuffer(50),strFmt,m_connectionList.GetCount());
- strTemp.ReleaseBuffer();
- pCmdUI->SetText(strTemp);
- }
- }
-