怎么用CArchive传送RichEdit中的信息呢?模仿QQ的艰难尝试

Zenhobby 2013-04-11 10:20:23
初学socket都会试着写自己的聊天程序,我也写了一个,按照CodeProject的OleRichEdit的办法改造了RichEditCtrl,让它能支持图片,并能够保存到RTF文件。还没有让GIF动起来,暂时试试发送。

发送是按照一个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格式的文档吗?不大愿意用必须阻塞的文件传输,也不大愿意再开个线程,该怎么改才能让程序接收到数据呢?求指点!
...全文
108 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Zenhobby 2013-04-17
  • 打赏
  • 举报
回复
看了赵老师推荐的帖子,一群大牛在讨论一些不明觉厉的东西,但是对问题的解决没有太大帮助。最后自己发现是StreamIn和StreamOut的参数中有一个RFF_SELECTION,用于确定是否带选定属性,所以在StreamOutToArchive的时候不需要有这个属性,全部缓冲进去,再StreamInfromArchive时候要选择这个属性并把光标放到最后面以免覆盖……就是这样了。
Archive类的思路挺好的,做的聊天界面把文件都包含在RTF内,简单方便,但是遗憾的是,OLE的插入并没有一种合用方便的办法,聊天窗口以OLE的方法嵌入的话并不能在接收方直接打开OLE对象,因为对象并不具有正确的链接路径(虽然文件已经传过去了)。不知道是不是因为这个QQ之类都用传递文件的来(或者他们是保密的考虑?菜鸟表示不懂)。
遗憾我是个小白还未能学好COM或者ATL啥的,等等我技术进步了一定要做好这个,这样的话,能够自动传输OLE对象并为对象直接分配地址,也就是下载在接收端指定文件夹中的话,岂不是直接可以传送文件了么,多好……
畅想下,处女贴啊,结贴结贴!
赵4老师 2013-04-11
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html 调试socket程序有时不抓包是调不通的。

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧