www.pudn.com > mischat.rar > mischatDoc.cpp
// mischatDoc.cpp : implementation of the CmischatDoc class
//
#include "stdafx.h"
#include "mischat.h"
#include "mischatDoc.h"
#include "mischatView.h"
#include "Draw.h"
#include "DrawTypeId.h"
#include ".\mischatdoc.h"
#include "NDKMessage.h"
#include "ChatMessage.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CmischatDoc
#define WM_REFRESHCAPTIONBAR WM_USER + 0x7FFF
#define WM_APPENDOUTPUTBARINFO WM_USER + 0x7FFE
#define WM_REFRESHIPBAR WM_USER + 0x7FFD
#define WM_PANEGROGRESSBAR WM_USER + 0x7FFC
#define FILEBLOCKSIZE 2048
extern CMainFrame* pMainWnd;
IMPLEMENT_DYNCREATE(CmischatDoc, CDocument)
BEGIN_MESSAGE_MAP(CmischatDoc, CDocument)
ON_COMMAND(IDM_SERVERSTART, OnServerStart)
ON_COMMAND(IDM_SERVERSTOP, OnServerStop)
ON_COMMAND(IDM_CLIENTSTART, OnClientStart)
ON_COMMAND(IDM_CLIENTSTOP, OnClientStop)
ON_UPDATE_COMMAND_UI(IDM_CLIENTSTOP, OnUpdateClientStop)
ON_UPDATE_COMMAND_UI(IDM_CLIENTSTART, OnUpdateClientStart)
ON_UPDATE_COMMAND_UI(IDM_SERVERSTOP, OnUpdateServerStop)
ON_UPDATE_COMMAND_UI(IDM_SERVERSTART, OnUpdateServerStart)
END_MESSAGE_MAP()
// CmischatDoc construction/destruction
CmischatDoc* pDoc;
CmischatDoc::CmischatDoc()
{
// TODO: add one-time construction code here
flag=NOTHING;
pDoc=this;
pView=NULL;
outputInfo.SetSize (500,50);
outInfoIndex=0;
CanTransmitFile=FALSE;
TCHAR szPath[MAX_PATH];
memset(szPath,'\0',sizeof(szPath));
::GetModuleFileName(NULL,szPath,sizeof(szPath)/sizeof(TCHAR));
strModulePath=szPath;
int index=strModulePath.ReverseFind(_T('\\'));
ASSERT(index!=-1);
strModulePath=strModulePath.Left(index+1);
if(!ReadIniFile(strModulePath+"chat.env"))
{
widthPen=3;
corPen=RGB(255,0,0),corBrush=RGB(0,0,255),corText=RGB(0,0,0);
m_strIP="127.0.0.1";
strName=_T("无名氏");
m_ServerPort=m_ClientPort=6000;
m_ConnectMax=10;
ChatPrivilege=_T("禁止");
CFont::FromHandle ((HFONT) GetStockObject (DEFAULT_GUI_FONT))->GetLogFont (&lf);
}
}
CmischatDoc::~CmischatDoc()
{
while(!drawList.IsEmpty ()) delete drawList.RemoveHead();
ip_socket_map.RemoveAll ();
AllIPList.RemoveAll ();
DenyIPList.RemoveAll ();
server.UnInit ();
client.UnInit ();
}
BOOL CmischatDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
if(strModulePath.IsEmpty ()) return FALSE;
TCHAR env[MAX_PATH];
memset(env,'\0',sizeof(env));
if(::GetEnvironmentVariable(_T("TEMP"),env,sizeof(env)/sizeof(TCHAR))==0) return FALSE;
strTempFileS.Format ("%s\\updates.chat",env);
strTempFileC.Format ("%s\\updatec.chat",env);
TRACE("strTempFileS=%s\n",strTempFileS);
POSITION pos = GetFirstViewPosition();
if(pos != NULL)
{
pView = static_cast(GetNextView(pos));
}
return pView!=NULL;
}
bool CmischatDoc::ReadIniFile(CString& str)
{
HANDLE hSearch;
WIN32_FIND_DATA fd;
hSearch = FindFirstFile(str, &fd);
if (hSearch != INVALID_HANDLE_VALUE)
{
CFile myFile;
CFileException e;
try{
myFile.Open(str, CFile::modeRead|CFile::typeBinary, &e);
CArchive ar(&myFile, CArchive::load);
Serialize(ar);
ar.Close();
myFile.Close();
}
catch(CFileException * e){
e->ReportError();
e->Delete();
}
return true;
}else return false;
}
void CmischatDoc::SaveIniFile(CString& str)
{
CFile myFile;
CFileException e;
try{
myFile.Open(str, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary, &e);
CArchive ar(&myFile, CArchive::store);
Serialize(ar);
ar.Close();
myFile.Close();
}
catch(CFileException * e){
e->ReportError();
e->Delete();
}
}
void CmischatDoc::OpenWhiteBroad()
{
CString strFilter=_T("白板文件(*.chat)|*.chat||");
CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST,strFilter);
if(dlg.DoModal() ==IDOK)
{
CFile myFile;
CFileException e;
try{
myFile.Open(dlg.GetPathName (), CFile::modeRead|CFile::typeBinary, &e);
CArchive ar(&myFile, CArchive::load);
csDrawInfo.Lock ();
while(!drawList.IsEmpty ()) delete drawList.RemoveHead();
drawList.Serialize(ar);
csDrawInfo.Unlock ();
ar.Close();
myFile.Close();
pView->Invalidate ();
}
catch(CFileException * e){
e->ReportError();
e->Delete();
}
}
}
void CmischatDoc::SaveWhiteBroad()
{
HRESULT hResult;
TCHAR strFilter[]=_T("白板文件(*.chat)|*.chat||");
CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,strFilter);
hResult = (int)dlg.DoModal();
if (hResult != IDOK) {
return;
}
// Add the appropriate extension if the user didn't type one
CString strFileName;
strFileName = dlg.m_ofn.lpstrFile;
// add the file extension if the user didn't supply one
if (dlg.m_ofn.nFileExtension == 0)
{
strFileName = strFileName + ".chat";
}
CFile myFile;
CFileException e;
try{
myFile.Open(strFileName,CFile::modeWrite|CFile::modeCreate|CFile::typeBinary, &e);
CArchive ar(&myFile, CArchive::store);
csDrawInfo.Lock ();
drawList.Serialize(ar);
csDrawInfo.Unlock ();
ar.Close();
myFile.Close();
}
catch(CFileException * e){
e->ReportError();
e->Delete();
}
}
// CmischatDoc serialization
void CmischatDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
ar<>widthPen>>corPen>>corBrush>>corText>>m_strIP>>strName>>m_ServerPort>>m_ClientPort>>m_ConnectMax>>ChatPrivilege;
ar.Read (&lf,sizeof(LOGFONT));
}
DenyIPList.Serialize (ar);
}
// CmischatDoc diagnostics
#ifdef _DEBUG
void CmischatDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CmischatDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
// CmischatDoc commands
void CmischatDoc::AppendAndDispOutputBarInfo(CString strInfo)
{
pDoc->csOutputInfo.Lock ();
pDoc->outputInfo.SetAtGrow (pDoc->outInfoIndex,strInfo);
pDoc->outInfoIndex++;
LPTSTR p=strInfo.LockBuffer ();
pMainWnd->SendMessage (WM_APPENDOUTPUTBARINFO,0,(LPARAM)p);
strInfo.UnlockBuffer();
pDoc->csOutputInfo.Unlock();
}
void CmischatDoc::AddToTailAndDraw(CDraw* pdw)
{
pDoc->csDrawInfo.Lock ();
pDoc->drawList.AddTail (pdw);
pView->Draw(pdw);
pDoc->csDrawInfo.Unlock();
}
void CmischatDoc::SProcessRecvData(unsigned long sIP,SOCKET sClient,char * pData,unsigned long DataLength,BOOL hint)
{
CString str;
if(pData!=NULL)
{
if(hint)//WriteLogString发来的数据:连接、断开、SOCKET函数调用错误
{
str=pData;
pDoc->AppendAndDispOutputBarInfo(str);
if(sIP!=0 && str.Find (_T("断开"))!=-1){//断开
pDoc->csAllIPList .Lock ();
pDoc->RemoveFromIPList(pDoc->AllIPList,sIP);
pDoc->SendUserList();
pMainWnd->SendMessage (WM_REFRESHIPBAR);
pDoc->csAllIPList .Unlock ();
}
return;
}
CNDKMessage mg;
pDoc->PCharToCNDKMessage(mg,pData,DataLength);
switch(mg.GetId ())
{
case ChatUserJoin:
pDoc->csAllIPList .Lock ();
pDoc->ProcessUserJoin(mg,sIP,sClient);
pDoc->csAllIPList .Unlock ();
break;
case ChatText:
if(pDoc->ChatPrivilege==_T("文本") || pDoc->ChatPrivilege==_T("全部"))
{
mg.GetAt (0,str);
pDoc->AppendAndDispOutputBarInfo(str);
}
break;
case ChatClear:
if(pDoc->ChatPrivilege==_T("白板") || pDoc->ChatPrivilege==_T("全部"))
{
pDoc->csDrawInfo.Lock ();
while(!pDoc->drawList.IsEmpty ()) delete pDoc->drawList.RemoveHead();
pDoc->pView->Invalidate ();
pDoc->csDrawInfo.Unlock();
}
break;
case ChatSendFileQuery:
pDoc->ProcessSendFileQuery(sIP,mg);
break;
case ChatSendFileOk:
pDoc->BeginTransmitFile();
pDoc->AppendAndDispOutputBarInfo(_T("开始发送文件"));
break;
case ChatSendFileNo:
pDoc->TransmitFile.Close ();
pDoc->CanTransmitFile=TRUE;
pDoc->AppendAndDispOutputBarInfo(_T("对方拒绝接收"));
break;
case ChatNextFileBlock:
pDoc->BeginTransmitFile();
break;
case ChatSendFileData:
pDoc->BeginReceiveFile(mg);
break;
case ChatSendFileEnd:
pDoc->ReceiveFile.Close ();
if(pDoc->TotalReceiveLength==pDoc->FileHaveReceiveLength)
{
::MessageBox(pMainWnd->GetSafeHwnd(),_T("已成功接收"),_T("信息"),MB_OK);
mg.Clear ();
mg.SetId (ChatReceiveFileOk);
if(!pDoc->SendMsg (sClient,mg)) pDoc->PrecessSendFileError(ChatReceiveFileOk);
}
else ::MessageBox(pMainWnd->GetSafeHwnd(),_T("文件传送失败"),_T("信息"),MB_OK);
pDoc->CanTransmitFile=TRUE;
break;
case ChatReceiveFileOk:
::MessageBox(pMainWnd->GetSafeHwnd(),_T("已成功发送"),_T("信息"),MB_OK);
break;
case ChatNextUpdateBlock:
mg.Clear ();
if(pDoc->finishLen==pDoc->totalDrawLen)
{
mg.SetId (ChatUpdateEnd);
pDoc->SendMsgToAll(mg);
pDoc->AllDrawFile.Close ();
break;
}
else mg.SetId (ChatUpdateData);
{
BYTE buf[FILEBLOCKSIZE];
ULONG len=pDoc->AllDrawFile.Read (buf,FILEBLOCKSIZE);
mg.SetAt (0,len);
mg.SetAt (1,buf,len);
pDoc->finishLen+=len;
pDoc->SendMsgToAll(mg);
}
break;
case ChatCCurve: case ChatCLine: case ChatCText: case ChatCRectangle: case ChatCEllipse:
if(pDoc->ChatPrivilege==_T("白板") || pDoc->ChatPrivilege==_T("全部"))
{
CDraw* pdw=pDoc->CNDKMessageToCDraw(mg);
if(pdw!=NULL) pDoc->AddToTailAndDraw(pdw);
}
break;
}
}
}
void CmischatDoc::CProcessRecvData(char * pData,unsigned long DataLength,BOOL hint)
{
CString str;
if(pData==NULL)
{
pDoc->OnClientStop();
return;
}
else
{
if(hint){//WriteLogString发来的数据:连接、断开、SOCKET函数调用错误
str=pData;
pDoc->AppendAndDispOutputBarInfo(str);
return;
}
CNDKMessage mg;
pDoc->PCharToCNDKMessage(mg,pData,DataLength);
switch(mg.GetId ())
{
case ChatUserOnline:
pDoc->csAllIPList .Lock ();
pDoc->ReceiveUserList(mg);
pMainWnd->SendMessage (WM_REFRESHIPBAR);
pDoc->csAllIPList .Unlock ();
break;
case ChatText:
mg.GetAt (0,str);
pDoc->AppendAndDispOutputBarInfo(str);
break;
case ChatClear:
pDoc->csDrawInfo.Lock ();
while(!pDoc->drawList.IsEmpty ()) delete pDoc->drawList.RemoveHead();
pDoc->pView->Invalidate ();
pDoc->csDrawInfo.Unlock();
break;
case ChatSendFileQuery:
pDoc->ProcessSendFileQuery(mg);
break;
case ChatSendFileOk:
pDoc->BeginTransmitFile();
pDoc->AppendAndDispOutputBarInfo(_T("开始发送文件"));
break;
case ChatSendFileNo:
pDoc->TransmitFile.Close ();
pDoc->CanTransmitFile=TRUE;
pDoc->AppendAndDispOutputBarInfo(_T("对方拒绝接收"));
break;
case ChatNextFileBlock:
pDoc->BeginTransmitFile();
break;
case ChatSendFileData:
pDoc->BeginReceiveFile(mg);
break;
case ChatSendFileEnd:
pDoc->ReceiveFile.Close ();
if(pDoc->TotalReceiveLength==pDoc->FileHaveReceiveLength)
{
::MessageBox(pMainWnd->GetSafeHwnd(),_T("已成功接收"),_T("信息"),MB_OK);
mg.Clear ();
mg.SetId (ChatReceiveFileOk);
if(!pDoc->SendMsg (mg)) pDoc->PrecessSendFileError(ChatReceiveFileOk);
}
else ::MessageBox(pMainWnd->GetSafeHwnd(),_T("文件传送失败"),_T("信息"),MB_OK);
pDoc->CanTransmitFile=TRUE;
break;
case ChatReceiveFileOk:
::MessageBox(pMainWnd->GetSafeHwnd(),_T("已成功发送"),_T("信息"),MB_OK);
break;
case ChatUpdate:
if(pDoc->AllDrawFile.m_hFile != CFile::hFileNull) pDoc->AllDrawFile.Close ();
pDoc->AllDrawFile.Open(pDoc->strTempFileC, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary);
mg.GetAt (0,pDoc->totalDrawLen );
pDoc->finishLen =0;
mg.Clear ();
mg.SetId (ChatNextUpdateBlock);
pDoc->SendMsg(mg);
break;
case ChatUpdateData:
{
BYTE buf[FILEBLOCKSIZE];
ULONG len;
mg.GetAt (0,len);
mg.GetAt (1,buf,len);
pDoc->finishLen+=len;
pDoc->AllDrawFile.Write (buf,len);
mg.Clear ();
mg.SetId (ChatNextUpdateBlock);
pDoc->SendMsg(mg);
}
break;
case ChatUpdateEnd:
pDoc->AllDrawFile.Close ();
if(pDoc->finishLen==pDoc->totalDrawLen)
{
CFileException e;
try{
pDoc->AllDrawFile.Open(pDoc->strTempFileC, CFile::modeRead|CFile::typeBinary,&e);
CArchive ar(&pDoc->AllDrawFile,CArchive::load );
pDoc->csDrawInfo.Lock ();
while(!pDoc->drawList.IsEmpty ()) delete pDoc->drawList.RemoveHead();
pDoc->drawList.Serialize (ar);
ar.Close ();
pDoc->csDrawInfo.Unlock();
pDoc->AllDrawFile.Close ();
}
catch(CFileException * e){
e->ReportError();
e->Delete();
}
}
pDoc->pView->Invalidate ();
break;
case ChatCCurve: case ChatCLine: case ChatCText: case ChatCRectangle: case ChatCEllipse:
CDraw* pdw=pDoc->CNDKMessageToCDraw(mg);
if(pdw!=NULL) pDoc->AddToTailAndDraw(pdw);
break;
}
}
}
int CmischatDoc::ConditionFunc(
IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
OUT LPWSABUF lpCalleeData,
OUT GROUP FAR *g,
IN DWORD_PTR dwCallbackData
)
{
sockaddr addr;
char buf[50];
DWORD len=50;
memcpy(&addr,lpCallerId->buf,lpCallerId->len );
if(::WSAAddressToString (&addr,sizeof(sockaddr),NULL,buf,&len)==0)
{
CString str=buf;
int index=str.Find (':');
bool found=false;
POSITION ps=pDoc->DenyIPList.GetHeadPosition ();
while(ps)
{
found=pDoc->DenyIPList.GetNext (ps).Find (str.Left(index))!=-1;
if(found) break;
}
if(!found && pDoc->AllIPList.GetCount ()m_ConnectMax)
return CF_ACCEPT;
}
::Sleep (5000);
return CF_REJECT;
}
void CmischatDoc::OnServerStart()
{
// TODO: 在此添加命令处理程序代码
CString str;
if(server.Init (SProcessRecvData,ConditionFunc,m_ServerPort))
{
str.Format (_T("服务器启动成功 本地IP:%s 监听端口:%d"),server.GetLocalIpAdd (),m_ServerPort);
CanTransmitFile=TRUE;
}
else str=_T("服务器启动失败");
AppendAndDispOutputBarInfo(str);
LPTSTR p=str.LockBuffer ();
pMainWnd->SendMessage (WM_REFRESHCAPTIONBAR,0,(LPARAM)p);
str.UnlockBuffer ();
}
void CmischatDoc::OnServerStop()
{
// TODO: 在此添加命令处理程序代码
CString str;
str=_T("服务器已关闭");
server.UnInit ();
if(TransmitFile.m_hFile != CFile::hFileNull) TransmitFile.Close ();
if(ReceiveFile.m_hFile != CFile::hFileNull) ReceiveFile.Close ();
if(AllDrawFile.m_hFile != CFile::hFileNull) AllDrawFile.Close ();
CanTransmitFile=FALSE;
AppendAndDispOutputBarInfo(str);
LPTSTR p=str.LockBuffer ();
pMainWnd->SendMessage (WM_REFRESHCAPTIONBAR,0,(LPARAM)p);
str.UnlockBuffer ();
}
void CmischatDoc::OnClientStart()
{
// TODO: 在此添加命令处理程序代码
CString str;
if(client.Init (CProcessRecvData,m_strIP,m_ClientPort))
{
str.Format (_T("连接服务器成功 本地IP:%s 服务器IP:%s 连接端口:%d"),client.GetLocalIP(),m_strIP,m_ClientPort);
CNDKMessage mg;
mg.SetId (ChatUserJoin);
mg.Add (strName);
SendMsg(mg);
CanTransmitFile=TRUE;
}
else str=_T("连接服务器失败");
AppendAndDispOutputBarInfo(str);
LPTSTR p=str.LockBuffer ();
pMainWnd->SendMessage (WM_REFRESHCAPTIONBAR,0,(LPARAM)p);
str.UnlockBuffer ();
}
void CmischatDoc::OnClientStop()
{
// TODO: 在此添加命令处理程序代码
CString str;
str=_T("已断开与服务器的连接");
client.UnInit ();
if(TransmitFile.m_hFile != CFile::hFileNull) TransmitFile.Close ();
if(ReceiveFile.m_hFile != CFile::hFileNull) ReceiveFile.Close ();
if(AllDrawFile.m_hFile != CFile::hFileNull) AllDrawFile.Close ();
CanTransmitFile=FALSE;
AppendAndDispOutputBarInfo(str);
AllIPList.RemoveAll ();
pMainWnd->SendMessage(WM_REFRESHIPBAR);
LPTSTR p=str.LockBuffer ();
pMainWnd->SendMessage (WM_REFRESHCAPTIONBAR,0,(LPARAM)p);
str.UnlockBuffer ();
}
void CmischatDoc::OnUpdateClientStop(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
pCmdUI->Enable(client.isStart());
}
void CmischatDoc::OnUpdateClientStart(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
pCmdUI->SetCheck (client.isStart());
pCmdUI->Enable(!client.isStart() && !server.isStart());
}
void CmischatDoc::OnUpdateServerStop(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
pCmdUI->Enable(server.isStart());
}
void CmischatDoc::OnUpdateServerStart(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
pCmdUI->SetCheck (server.isStart());
pCmdUI->Enable(!client.isStart() && !server.isStart());
}
char* CmischatDoc::CNDKMessageToPChar(CNDKMessage& mg,ULONG& len)
{
char* pchar=NULL;
//if(mg.GetNbElements ()==0) return pchar;
CMemFile mf;
CArchive ar(&mf,CArchive::store);
mg.Serialize (ar);
ar.Close ();
len=(ULONG)mf.GetLength ();
pchar=(char*)mf.Detach ();
return pchar;
}
void CmischatDoc::PCharToCNDKMessage(CNDKMessage& mg,char* pchar,ULONG len)
{
if(pchar==NULL || len==0) return;
CMemFile mf;
mf.Attach ((BYTE*)pchar,len);
CArchive ar(&mf,CArchive::load);
mg.Serialize (ar);
ar.Close ();
mf.Detach ();
}
void CmischatDoc::CDrawToCNDKMessage(CNDKMessage& mg,CDraw* pdw)
{
if(!pdw->IsKindOf (RUNTIME_CLASS(CDraw))) return;
if(pdw->IsKindOf (RUNTIME_CLASS(CCurve))) mg.SetId (ChatCCurve);
if(pdw->IsKindOf (RUNTIME_CLASS(CLine))) mg.SetId (ChatCLine);
if(pdw->IsKindOf (RUNTIME_CLASS(CText))) mg.SetId (ChatCText);
if(pdw->IsKindOf (RUNTIME_CLASS(CRectangle))) mg.SetId (ChatCRectangle);
if(pdw->IsKindOf (RUNTIME_CLASS(CEllipse))) mg.SetId (ChatCEllipse);
CMemFile mf;
CArchive ar(&mf,CArchive::store);
pdw->Serialize (ar);
ar.Close ();
ULONG len=(ULONG)mf.GetLength ();
BYTE* p=mf.Detach ();
mg.Add (len);
mg.Add (p,(UINT)len);
delete p;
}
CDraw* CmischatDoc::CNDKMessageToCDraw(CNDKMessage& mg)
{
CDraw * pdw=NULL;
ULONG len;
if(mg.GetNbElements ()==0) return pdw;
switch(mg.GetId ())
{
case ChatCCurve:
pdw=new CCurve();
break;
case ChatCLine:
pdw=new CLine();
break;
case ChatCText:
pdw=new CText();
break;
case ChatCRectangle:
pdw=new CRectangle();
break;
case ChatCEllipse:
pdw=new CEllipse();
break;
}
if(pdw!=NULL)
{
mg.GetAt (0,len);
BYTE* p=new BYTE[len];
mg.GetAt (1,p,(UINT)len);
CMemFile mf;
mf.Attach (p,(UINT)len);
CArchive ar(&mf,CArchive::load);
pdw->Serialize (ar);
ar.Close ();
mf.Detach ();
delete[] p;
}
return pdw;
}
bool CmischatDoc::SendMsg(LPCTSTR TargetIp,CNDKMessage& mg)
{
unsigned long tIP=inet_addr(TargetIp);
SOCKET sClient;
if(ip_socket_map.Lookup (tIP,sClient)==0) return false;
char* pch;
ULONG len;
pch=CNDKMessageToPChar(mg,len);
bool result=false;
if(pch!=NULL){
result=server.SendMsg(sClient,pch,len);
delete pch;
}
return result;
}
bool CmischatDoc::SendMsg(SOCKET sClient,CNDKMessage& mg)
{
char* pch;
ULONG len;
pch=CNDKMessageToPChar(mg,len);
bool result=false;
if(pch!=NULL){
result=server.SendMsg(sClient,pch,len);
delete pch;
}
return result;
}
bool CmischatDoc::SendMsgToAll(CNDKMessage& mg)
{
char* pch;
ULONG len;
pch=CNDKMessageToPChar(mg,len);
bool result=false;
if(pch!=NULL){
result=server.SendMsgToAll (pch,len);
delete pch;
}
return result;
}
bool CmischatDoc::SendMsgToOther(LPCTSTR ExceptIp,CNDKMessage& mg)
{
unsigned long tIP=inet_addr(ExceptIp);
SOCKET sClient;
if(ip_socket_map.Lookup (tIP,sClient)==0) return false;
char* pch;
ULONG len;
pch=CNDKMessageToPChar(mg,len);
bool result=false;
if(pch!=NULL){
result=server.SendMsgToOther (sClient,pch,len);
delete pch;
}
return result;
}
bool CmischatDoc::SendMsgToOther(SOCKET ExceptSocket,CNDKMessage& mg)
{
char* pch;
ULONG len;
pch=CNDKMessageToPChar(mg,len);
bool result=false;
if(pch!=NULL){
result=server.SendMsgToOther (ExceptSocket,pch,len);
delete pch;
}
return result;
}
bool CmischatDoc::SendMsg(CNDKMessage& mg)
{
char* pch;
ULONG len;
pch=CNDKMessageToPChar(mg,len);
bool result=false;
if(pch!=NULL){
result=client.SendMsg(pch,len);
delete pch;
}
return result;
}
bool CmischatDoc::SendMsgToAll(CDraw* pdw)
{
CNDKMessage mg;
if(pdw!=NULL)
{
CDrawToCNDKMessage(mg,pdw);
}
else
{
mg.SetId (ChatClear);
CString str="SERVERCLEAR";
mg.Add (str);
}
return SendMsgToAll(mg);
}
bool CmischatDoc::SendMsg(CDraw* pdw)
{
CNDKMessage mg;
if(pdw!=NULL)
{
CDrawToCNDKMessage(mg,pdw);
}
else
{
mg.SetId (ChatClear);
CString str="CLIENTCLEAR";
mg.Add (str);
}
return SendMsg(mg);
}
void CmischatDoc::AddToIPList(CStringList& list,unsigned long sIP,CString& strName)
{
CString str;
str.Format ("%d.%d.%d.%d",LOBYTE(LOWORD(sIP)),HIBYTE(LOWORD(sIP)),LOBYTE(HIWORD(sIP)),HIBYTE(HIWORD(sIP)));
list.AddTail (str+"#"+strName);
}
void CmischatDoc::AddToIPList(CStringList& list,CString& sIP,CString& strName)
{
list.AddTail (sIP+"#"+strName);
}
void CmischatDoc::RemoveFromIPList(CStringList& list,unsigned long sIP)
{
POSITION ps,psTemp;
ps=list.GetHeadPosition ();
CString str;
str.Format ("%d.%d.%d.%d",LOBYTE(LOWORD(sIP)),HIBYTE(LOWORD(sIP)),LOBYTE(HIWORD(sIP)),HIBYTE(HIWORD(sIP)));
while(ps!=NULL)
{
psTemp=ps;
if(list.GetNext (ps).Find (str)!=-1){
list.RemoveAt (psTemp);
break;
}
}
}
void CmischatDoc::RemoveFromIPList(CStringList& list,CString& sIP)
{
POSITION ps,psTemp;
ps=list.GetHeadPosition ();
while(ps!=NULL)
{
psTemp=ps;
if(list.GetNext (ps).Find (sIP)!=-1){
list.RemoveAt (psTemp);
break;
}
}
}
bool CmischatDoc::SendUserList()
{
CNDKMessage mg;
mg.SetId (ChatUserOnline);
POSITION ps;
ps=AllIPList.GetHeadPosition ();
while(ps)
{
mg.Add (AllIPList.GetNext (ps));
}
return SendMsgToAll(mg);
}
//客户机端用
void CmischatDoc::ReceiveUserList(CNDKMessage& mg)
{
CString str;
AllIPList.RemoveAll ();
for(int i=0;iAddToIPList(pDoc->AllIPList,sIP,str);
ip_socket_map.SetAt (sIP,socket);
pDoc->SendUserList();
pMainWnd->SendMessage (WM_REFRESHIPBAR);
}
void CmischatDoc::OnCloseDocument()
{
// TODO: 在此添加专用代码和/或调用基类
SaveIniFile(strModulePath+"chat.env");
if(TransmitFile.m_hFile != CFile::hFileNull) TransmitFile.Close ();
if(ReceiveFile.m_hFile != CFile::hFileNull) ReceiveFile.Close ();
if(AllDrawFile.m_hFile != CFile::hFileNull) AllDrawFile.Close ();
CDocument::OnCloseDocument();
}
void CmischatDoc::PreTransmitFile(CString strIP,CString strFile)
{
try{
if(TransmitFile.Open(strFile, CFile::modeRead|CFile::typeBinary))
{
CNDKMessage mg;
strFileName=strFile;
strIPFile=strIP;
TotalFileLength=(ULONG)TransmitFile.GetLength ();
FileHaveTransmitLength=0;
mg.SetId (ChatSendFileQuery);
mg.Add (TransmitFile.GetFileName ());
mg.Add (TotalFileLength);
if(SendMsg(strIP,mg)) CanTransmitFile=FALSE;
else PrecessSendFileError(ChatSendFileQuery);
}
}
catch (CFileException* pEx)
{
// if an error occurs, just make a message box
pEx->ReportError();
pEx->Delete();
}
}
void CmischatDoc::PreTransmitFile(CString strFile)
{
try{
if(TransmitFile.Open(strFile, CFile::modeRead|CFile::typeBinary))
{
CNDKMessage mg;
strFileName=strFile;
strIPFile="";
TotalFileLength=(ULONG)TransmitFile.GetLength ();
FileHaveTransmitLength=0;
mg.SetId (ChatSendFileQuery);
mg.Add (TransmitFile.GetFileName ());
mg.Add (TotalFileLength);
if(SendMsg(mg)) CanTransmitFile=FALSE;
else PrecessSendFileError(ChatSendFileQuery);
}
}
catch (CFileException* pEx)
{
// if an error occurs, just make a message box
pEx->ReportError();
pEx->Delete();
}
}
void CmischatDoc::BeginTransmitFile()
{
bool rel=false;
CNDKMessage mg;
if(FileHaveTransmitLength==TotalFileLength)
{
TransmitFile.Close ();
CanTransmitFile=TRUE;
mg.SetId (ChatSendFileEnd);
TRACE("ChatSendFileEnd\n");
goto label;
}
ULONG len;
mg.SetId (ChatSendFileData);
BYTE buf[FILEBLOCKSIZE];
len=TransmitFile.Read (buf,FILEBLOCKSIZE);
FileHaveTransmitLength+=len;
mg.Add (len);
mg.Add (buf,len);
TRACE("ChatSendFileData\n");
label:
if(server.isStart()) rel=SendMsg(strIPFile,mg);
if(client.isStart()) rel=SendMsg(mg);
if(!rel) PrecessSendFileError(mg.GetId ());
TRACE("TotalFileLength=%d FileHaveTransmitLength=%d\n",TotalFileLength,FileHaveTransmitLength);
pMainWnd->SendMessage (WM_PANEGROGRESSBAR,0,(LPARAM)(FileHaveTransmitLength*100/TotalFileLength));
}
void CmischatDoc::BeginReceiveFile(CNDKMessage& mg)
{
bool rel=false;
BYTE buf[FILEBLOCKSIZE];
ULONG len;
mg.GetAt (0,len);
mg.GetAt (1,buf,len);
ReceiveFile.Write (buf,len);
FileHaveReceiveLength+=len;
mg.Clear ();
mg.SetId (ChatNextFileBlock);
if(server.isStart()) {rel=SendMsg(strIPFile,mg);TRACE("BeginReceiveFile->ChatNextFileBlock\n");}
if(client.isStart()) {rel=SendMsg(mg);TRACE("BeginReceiveFile->ChatNextFileBlock\n");}
if(!rel) PrecessSendFileError(ChatNextFileBlock);
TRACE("TotalReceiveLength=%d FileHaveReceiveLength=%d\n",TotalReceiveLength,FileHaveReceiveLength);
pMainWnd->SendMessage (WM_PANEGROGRESSBAR,0,(LPARAM)(FileHaveReceiveLength*100/TotalReceiveLength));
}
void CmischatDoc::PrecessSendFileError(long error_id)
{
switch(error_id)
{
case ChatSendFileOk:
TRACE("Error Send ChatSendFileOk\n");
ReceiveFile.Close ();
break;
case ChatSendFileNo:
TRACE("Error Send ChatSendFileNo\n");
break;
case ChatNextFileBlock:
ReceiveFile.Close ();
TRACE("Error Send ChatNextFileBlock\n");
break;
case ChatSendFileData:
TransmitFile.Close ();
TRACE("Error Send ChatSendFileData\n");
break;
case ChatSendFileQuery:
TransmitFile.Close ();
TRACE("Error Send ChatSendFileQuery\n");
break;
case ChatSendFileEnd:
TransmitFile.Close ();
TRACE("Error Send ChatSendFileEnd\n");
break;
case ChatReceiveFileOk:
TRACE("Error Send ChatReceiveFileOk\n");
break;
default:
TRACE("Error Send %d\n" ,error_id);
}
CanTransmitFile=TRUE;
::MessageBox(pMainWnd->GetSafeHwnd(),_T("文件传输过程中发生错误,请稍后重试"),_T("信息"),MB_OK);
}
void CmischatDoc::ProcessSendFileQuery(CNDKMessage& mg)
{
CString strFile,str;
ULONG ul;
mg.GetAt (0,strFile);
mg.GetAt (1,ul);
mg.Clear ();
str.Format (_T("服务器给你发送文件:%s 长度为:%d 要接收吗?"),strFile,ul);
if(CanTransmitFile && MessageBox(pMainWnd->GetSafeHwnd(),str,_T("信息"),MB_ICONINFORMATION|MB_YESNO)==IDYES)
{
CFileDialog dlg(FALSE,NULL,strFile,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER);
if(dlg.DoModal ()==IDOK)
{
TotalReceiveLength=ul;
FileHaveReceiveLength=0;
try{
if(ReceiveFile.Open(dlg.GetPathName(), CFile::modeCreate| CFile::modeWrite|CFile::typeBinary))
{
mg.SetId (ChatSendFileOk);
if(SendMsg(mg)) {CanTransmitFile=FALSE;TRACE("ProcessSendFileQuery->ChatSendFileOk\n");}
else PrecessSendFileError(ChatSendFileOk);
}
}
catch (CFileException* pEx)
{
// if an error occurs, just make a message box
pEx->ReportError();
pEx->Delete();
}
}
}
else
{
mg.SetId (ChatSendFileNo);
if(SendMsg(mg)) TRACE("ProcessSendFileQuery->ChatSendFileNo\n");
else PrecessSendFileError(ChatSendFileNo);
}
}
void CmischatDoc::ProcessSendFileQuery(unsigned long sIP,CNDKMessage& mg)
{
CString strFile,strIP,str;
ULONG ul;
strIP.Format ("%d.%d.%d.%d",LOBYTE(LOWORD(sIP)),HIBYTE(LOWORD(sIP)),LOBYTE(HIWORD(sIP)),HIBYTE(HIWORD(sIP)));
mg.GetAt (0,strFile);
mg.GetAt (1,ul);
mg.Clear ();
str.Format (_T("%s给你发送文件:%s 长度为:%d 要接收吗?"),strIP,strFile,ul);
if(CanTransmitFile && MessageBox(pMainWnd->GetSafeHwnd(),str,_T("信息"),MB_ICONINFORMATION|MB_YESNO)==IDYES)
{
CFileDialog dlg(FALSE,NULL,strFile,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER);
if(dlg.DoModal ()==IDOK)
{
TotalReceiveLength=ul;
FileHaveReceiveLength=0;
try{
if(ReceiveFile.Open(dlg.GetPathName(), CFile::modeCreate| CFile::modeWrite|CFile::typeBinary))
{
mg.SetId (ChatSendFileOk);
if(SendMsg(strIP,mg)) {CanTransmitFile=FALSE;TRACE("ProcessSendFileQuery->ChatSendFileOk\n");}
else PrecessSendFileError(ChatSendFileOk);
}
}
catch (CFileException* pEx)
{
// if an error occurs, just make a message box
pEx->ReportError();
pEx->Delete();
}
}
}
else
{
mg.SetId (ChatSendFileNo);
if(SendMsg(strIP,mg)) TRACE("ProcessSendFileQuery->ChatSendFileNo\n");
else PrecessSendFileError(ChatSendFileNo);
}
}
void CmischatDoc::UpdateAllDrawData()
{
CFileException e;
if(AllDrawFile.m_hFile != CFile::hFileNull) AllDrawFile.Close ();
try{
AllDrawFile.Open(strTempFileS, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary, &e);
CArchive ar(&AllDrawFile, CArchive::store);
drawList.Serialize (ar);
ar.Close();
AllDrawFile.Close ();
AllDrawFile.Open(strTempFileS, CFile::modeRead|CFile::typeBinary);
}
catch(CFileException * e){
e->ReportError();
e->Delete();
}
totalDrawLen=(ULONG)AllDrawFile.GetLength ();
finishLen=0;
CNDKMessage mg;
mg.SetId (ChatUpdate);
mg.Add (totalDrawLen);
SendMsgToAll(mg);
}