发送是按照一个NetChat的程序修改的,采用CArchive/CSocketFile/CSocket的办法,利用Socket能用ArChive读写数据的办法,在建立连接之后建立如下缓冲:
m_ServerSocket->Accept(*m_ClientSocket);
m_ClientSocket->m_status=m_ServerSocket->m_status;
m_socketfile=new CSocketFile(m_ClientSocket);
m_archiveIn=new CArchive(m_socketfile,CArchive::load);
m_arvhiveOut=new CArchive(m_socketfile,CArchive::store);
在这个缓冲里m_archiveIn用与接收数据,m_arvhiveOut用于发送,原程序在发送时如下:
void CNetChatDlg::OnBtnSend()接收时有:
{
...
UpdateData(TRUE); //从发送编辑框中获得数据
*m_arvhiveOut<<m_Output; //CString m_Output:发送编辑框
m_arvhiveOut->Flush();
...
}
void CNetChatDlg::OnRecive()
{
CString strtemp,strrecv,strleft;
UpdateData(TRUE);
*m_archiveIn>>strrecv;
...
}
因为原程序中发送和接收都只是文字不带图片之类,所以CString就能搞定,我改成带图片的之后,就只能传送一个已经保存好的RTF文件,这个文件包含了所有的RichEdit信息。找到的序列化RTF到Archive的代码如下:
void CRichEditCat::StreamOutToArchive(CArchive &ar, BOOL bSelection, int nFormat)
{
EDITSTREAM es;
es.pfnCallback = writeStreamCallBack;
es.dwError = 0;
RichEditCookie cookie(ar);
es.dwCookie = (DWORD)&cookie;
if (bSelection)
{
nFormat |= SFF_SELECTION;
int nR=GetWindowTextLength();
SetSel(nR,nR);
}
StreamOut(nFormat, es);
return ;
}
DWORD CALLBACK CRichEditCat::writeStreamCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
RichEditCookie* pCookie = (RichEditCookie*)dwCookie;
CArchive& ar = pCookie->m_ar;
ar.Flush();
DWORD dw = 0;
*pcb = cb;
TRY
{
ar.GetFile()->Write(pbBuff, cb);
}
CATCH(CFileException, e)
{
*pcb = 0;
pCookie->m_dwError = (DWORD)e->m_cause;
dw = 1;
}
AND_CATCH_ALL(e)
{
*pcb = 0;
pCookie->m_dwError = (DWORD)CFileException::generic;
dw = 1;
// DELETE_EXCEPTION(e);
}
END_CATCH_ALL
return dw;
}
同理有读取Archive到RichEdit的函数StreamInFromArchive。在程序中这两个读写函数取代>><<操作符,这是我程序的思路。
这样的过程看起来很靠谱,但是每次试的时候接收端收到的都是空的,是Archive不成功吗?搞不懂这是为个啥。有没有更简单的做法?或者先把Richedit的内容保存到RTF中,再用Archive传输RTF也行啊!
路过的大牛,恳求给指点下,用Archive的办法可以传送RTF格式的文档吗?不大愿意用必须阻塞的文件传输,也不大愿意再开个线程,该怎么改才能让程序接收到数据呢?求指点!