Richedit-
上传用户:ywjx168
上传日期:2022-02-02
资源大小:7k
文件大小:15k
源码类别:

RichEdit

开发平台:

Visual C++

  1.  
  2.  
  3. Richedit使用大全
  4.  
  5. a.可以编译,不能执行的
  6. AfxInitRichEdit();
  7. b.升级默认的Riched版本(默认的有一些bug),如
  8. 可在InitInstance中添加
  9. LoadLibrary("RICHED20.DLL") 
  10. 最后注意 FreeLibrary 如果是CRichEditView基类的可用
  11. BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
  12. {
  13. //装入rich edit version 2.0
  14. if (LoadLibraryA("RICHED20.DLL") == NULL)
  15. {
  16. AfxMessageBox(_T("Fail to load "riched20.dll"."),MB_OK | MB_ICONERROR);
  17. PostMessage(WM_QUIT,0,0);
  18. return FALSE;
  19. } m_strClass = RICHEDIT_CLASSA;//for 2.0 class return CRichEditView::PreCreateWindow(cs);
  20. c.最后追加行
  21. richeditctrl.SetSel(-1, -1);
  22. richeditctrl.ReplaceSel( (LPCTSTR)str ); 
  23. d.字数限制
  24. CRichEditCtrl::LimitText(long nChars) 
  25. e.换行切换
  26. CRichEditView的OnInitialUpdate()函数中加入下面两句:
  27. m_nWordWrap = WrapNone;
  28. WrapChanged(); 
  29. WrapChanged实际上也是调用
  30. ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
  31. ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
  32. 还有不常用的 m_nWordWrap == WrapToTargetDevice
  33. ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
  34. 如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
  35. pmyRichEditCtrl->;PasteSpecial(CF_TEXT); 
  36. g.随着输入随着自动滚动条滚动到最后一行
  37. int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
  38. if (nFirstVisible > 0)
  39. {
  40. pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
  41. }
  42. m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0); 
  43. h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
  44. SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
  45. TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数 
  46. SendMessage(EM_SETUNDOLIMIT,100,0); i.响应OnChange
  47. EM_SETEVENTMASK 设置 ENM_CHANGE 
  48. long lMask = GetEventMask();
  49. lMask |= ENM_CHANGE;
  50. lMask &= ~ENM_PROTECTED;
  51. SetEventMask(lMask); j.设置只读
  52. CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );
  53. 通过设置PROTECTED实现选中的文本只读,参见
  54. [color=#0000ff]http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/[/color] [size=4][color=sienna][/color][/color]
  55. [size=4][color=sienna][/color][/color][size=4][color=sienna]二.函数应用[/color][/color]
  56. a.设置字体(主要是通过SetSelectionCharFormat)
  57. CHARFORMAT cf;
  58. ZeroMemory(&cf, sizeof(CHARFORMAT));
  59. cf.cbSize = sizeof(CHARFORMAT);
  60. cf.dwMask|=CFM_BOLD;
  61. cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
  62. cf.dwMask|=CFM_ITALIC;
  63. cf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
  64. cf.dwMask|=CFM_UNDERLINE;
  65. cf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;
  66. cf.dwMask|=CFM_COLOR;
  67. cf.crTextColor = RGB(255,0,0);//设置颜色
  68. cf.dwMask|=CFM_SIZE;
  69. cf.yHeight =200;//设置高度
  70. cf.dwMask|=CFM_FACE;
  71. strcpy(cf.szFaceName ,_T("隶书"));//设置字体
  72. rich.SetSelectionCharFormat(cf); 
  73. b.设置字体的行间距
  74. 要用richedit2.0以上
  75. 试试
  76. PARAFORMAT2 pf;
  77. pf.cbSize = sizeof(PARAFORMAT2);
  78. pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
  79. pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING 
  80. pf.dxOffset = 10;
  81. VERIFY(SetParaFormat(pf)); 
  82. 常用的dwMask有
  83. PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
  84. 2 使用阿拉伯数字 (1, 2, 3, ...).  
  85. 3 使用小写字母 (a, b, c, ...).  
  86. 4 使用大写字母 (A, B, C, ...).  
  87. 5 使用小写罗马数字 (i, ii, iii, ...).  
  88. 6 使用大写罗马数字 (I, II, III, ...).  
  89. 7 自定义,字符见成员 wNumberingStart.  
  90. PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
  91. PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进
  92. PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
  93. PFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距 
  94. c.设置CRichEditCtrl(2.0)背景透明 
  95. long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
  96. style &= WS_EX_TRANSPARENT;
  97. ::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
  98. 或 CreateEx,然后把WS_EX_TRANSPARENT样式加上 e.得到内容有三种
  99. 1)GetWindowText
  100. 2)使用EM_GETTEXTEX
  101. GETTEXTEX gt;
  102. gt.cb = 200;
  103. gt.flags = GT_DEFAULT;
  104. gt.codepage = CP_ACP ;
  105. gt.lpDefaultChar = NULL; 
  106. gt.lpUsedDefChar = NULL;
  107. SendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
  108. 3)StreamOut(主要用于RTF等格式输出)
  109. static DWORD CALLBACK 
  110. MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  111. {
  112. CFile* pFile = (CFile*) dwCookie; pFile->Write(pbBuff, cb);
  113. *pcb = cb; return 0;
  114. CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
  115. EDITSTREAM es;
  116. es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用
  117. es.pfnCallback = MyStreamOutCallback; 
  118. pmyRichEditCtrl->StreamOut(SF_RTF, es);
  119. 读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn f.查找字符串
  120. FINDTEXTEX ft;
  121. ft.chrg.cpMin = 0;
  122. ft.chrg.cpMax = -1;
  123. ft.lpstrText = "|";
  124. long lPos = FindText(0, &ft); 如果要继续查找,修改cpMin,如
  125. int nCount = 0;
  126. do
  127. {
  128. long lPos = GetRichEditCtrl().FindText(0, &ft);
  129. if( -1 == lPos) break;
  130. ft.chrg.cpMin = lPos + strlen(ft.lpstrText);
  131. ++nCount;
  132. }while(TRUE); g.以Html格式保存
  133. 目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
  134. [color=#0000ff]http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/[/color] 
  135. h.重载OnProtected函数得到对应的消息,如粘贴等
  136. void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
  137. {
  138. ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;   switch (pEP->msg) {
  139. case WM_KEYDOWN://按键,判断pEP->wParam
  140. case WM_PASTE://粘贴
  141. case WM_CUT://剪切
  142. case EM_SETCHARFORMAT:
  143. default:
  144.    break;
  145. };
  146. *pResult = FALSE;
  147. }
  148.    [size=4][color=sienna]三.聊天常用[/color][/color]  
  149. a.LINK 链接功能
  150. 1.   LoadLibrary(_T("Riched20.dll"));
  151. 2. 创建RichEdit2.0控件
  152. CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
  153. |ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
  154.       rect.left, rect.top, cx, cy,
  155.    pParentWnd->m_hWnd, (HMENU)nID, NULL);
  156. 3. 设定选中的文字为链接显示
  157. CHARFORMAT2 cf2;
  158. ZeroMemory(&cf2, sizeof(CHARFORMAT2));//
  159. cf2.cbSize = sizeof(CHARFORMAT2);
  160. cf2.dwMask = CFM_LINK;
  161. cf2.dwEffects |= CFE_LINK;
  162. m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
  163. 4.支持链接的点击响应
  164. m_cRichEdit.SetEventMask(ENM_LINK);
  165. 5.响应链接的点击EN_LINK BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
  166. ON_NOTIFY_REFLECT(EN_LINK,OnURL)
  167. END_MESSAGE_MAP()
  168. ...... void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
  169. {
  170. TCHAR LinkChar[512];
  171. ENLINK *pLink = (ENLINK *)pNmhdr;
  172. if (pLink->msg == WM_LBUTTONUP)
  173. {
  174. SetSel(penLink->chrg);//这是链接的文字范围
  175. long Res = GetSelText((char *)LinkChar);//这是链接文字
  176.                //后面是你的处理过程
  177.                ......
  178.       }
  179. } b.插入位图
  180. [color=#0000ff]http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/[/color]
  181. [color=#0000ff]http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/[/color] 
  182. 自定义在RichEdit中插入对象的图标
  183. [color=#0000ff]http://www.blogcn.com/user3/jiangsheng/blog/1319738.html[/color]
  184. 方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
  185. 只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片 使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
  186. 另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”([color=#0000ff]http://www.codeguru.com/richedit/richeditrc.html[/color])。 
  187. c.显示GIF动画
  188. 常用的是通过qq的imageole.dll(也有用Gif89.dll的)
  189. [color=#0000ff]http://www.xiaozhou.net/cooldog/blogview.asp?logID=82[/color]
  190. [color=#0000ff]http://www.codeproject.com/richedit/AnimatedEmoticon.asp[/color] 
  191. 在richedit控件中插入动态GIF (Native C++版)
  192. [color=#0000ff]http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx[/color] 
  193. d.IRichEditOleCallback的使用
  194. [color=#0000ff]http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022[/color] 
  195. 类似 MSN 信息发送框的制作(上)
  196. [color=#0000ff]http://www.vckbase.com/document/viewdoc/?id=1087[/color]
  197. 内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串 自定义 CRichEditCtrl 控件
  198. [color=#0000ff]http://www.vckbase.com/document/viewdoc/?id=328[/color]
  199. 内容包含:鼠标右键消息,消息映射,字体变换 PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
  200. 是一个专门的设计 Dual-font, Smart font apply, 参见 [color=#0000ff]http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778[/color]
  201.  
  202. 重写后的CRichEdit类可实现
  203. 1.右键菜单
  204. 2.能插入图片
  205. 3..RTF格式输入输出不够方便
  206. 二、原理简介
  207. 1、主要功能用CRichEditCtrl实现,像设置字体,设置字体颜色,字号等等CRichEditCtrl都提供了很完善的支持,我就不一一赘述了。
  208. CRichEditCtrl 主要的不足在于以下几个方面: 
  209. (1).没有右键菜单 
  210. (2).不能插入图片(这是实现转义字符显示的关键) 
  211. (3).RTF格式输入输出不够方便(涉及到回调函数的递归调用) 
  212.   我扩展了CRichEditCtrl类CRichEditCtrlEx实现了上述功能.参考了很多网上的文章,对所有公开源码的开发人员表示崇高的敬意!!
  213. 2、实现右键菜单:
  214. ///生成右键菜单
  215. void CRichEditCtrlEx::OnRButtonUp(UINT nFlags, CPoint point) 
  216. {
  217. // TODO: Add your message handler code here and/or call default
  218. //设置为焦点
  219. SetFocus();
  220. //创建一个弹出式菜单
  221. CMenu popmenu;
  222. popmenu.CreatePopupMenu();
  223. //添加菜单项目
  224. popmenu.AppendMenu(0, ID_RICH_UNDO, "&Undo");
  225. popmenu.AppendMenu(0, MF_SEPARATOR);
  226. popmenu.AppendMenu(0, ID_RICH_CUT, "&Cut");
  227. popmenu.AppendMenu(0, ID_RICH_COPY, "C&opy");
  228. popmenu.AppendMenu(0, ID_RICH_PASTE, "&Paste");
  229. popmenu.AppendMenu(0, ID_RICH_CLEAR, "C&lear");
  230. popmenu.AppendMenu(0, MF_SEPARATOR);
  231. popmenu.AppendMenu(0, ID_RICH_SELECTALL, "Select &All");
  232. popmenu.AppendMenu(0, MF_SEPARATOR);
  233. popmenu.AppendMenu(0, ID_RICH_SETFONT, "Select &Font");
  234. //初始化菜单项
  235. UINT nUndo=(CanUndo() ? 0 : MF_GRAYED );
  236. popmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND|nUndo);
  237. UINT nSel=((GetSelectionType()!=SEL_EMPTY) ? 0 : MF_GRAYED) ;
  238. popmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND|nSel);
  239. popmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND|nSel);
  240. popmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND|nSel);
  241. UINT nPaste=(CanPaste() ? 0 : MF_GRAYED) ;
  242. popmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND|nPaste);
  243. //显示菜单
  244. CPoint pt;
  245. GetCursorPos(&pt);
  246. popmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
  247. popmenu.DestroyMenu();
  248. CRichEditCtrl::OnRButtonDown(nFlags, point);
  249. CRichEditCtrl::OnRButtonUp(nFlags, point);
  250. }3、关于如何把图片插入到RichEdit中,国外由很多文章介绍,都是(我看到的都是)通过插入OLE对象来实现.主要用两个函数,还涉及到了和多接口的调用。
  251. (1)从文件创建OLE对象OleCreateFromFile();
  252. void CRichEditCtrlEx::InsertBitmap(CString szFileName)
  253. {
  254. USES_CONVERSION;
  255. SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &m_lpLockBytes);
  256. if (sc != S_OK)
  257. AfxThrowOleException(sc);
  258. ASSERT(m_lpLockBytes != NULL);
  259. sc = ::StgCreateDocfileOnILockBytes(m_lpLockBytes,
  260. STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);
  261. if (sc != S_OK)
  262. {
  263. VERIFY(m_lpLockBytes->Release() == 0);
  264. m_lpLockBytes = NULL;
  265. AfxThrowOleException(sc);
  266. }
  267. // attempt to create the object
  268. sc = ::OleCreateFromFile(CLSID_NULL, T2COLE(szFileName),
  269.         IID_IUnknown, OLERENDER_DRAW, NULL, NULL, 
  270.         m_lpStorage, (void **)&m_lpObject);
  271. if ( sc != S_OK )
  272. {
  273. TCHAR * lpMsgBuf;
  274. ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 
  275. FORMAT_MESSAGE_FROM_SYSTEM, NULL, 
  276. ::GetLastError(),
  277. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  278. (LPTSTR) &lpMsgBuf, 0, NULL );
  279. CString msg( lpMsgBuf );
  280. msg += _T("nnnThe following file, created inn"
  281. "Simulation->Plot, may be missing duen"
  282. "to not doing a File->Save Workspace:nn" );
  283. msg += szFileName;
  284. AfxMessageBox( msg, MB_OK );
  285. ::LocalFree( lpMsgBuf );
  286. return;
  287. }
  288. // m_lpObject is currently an IUnknown, convert to IOleObject
  289. if (m_lpObject != NULL)
  290. {
  291. LPUNKNOWN lpUnk = m_lpObject;
  292. m_lpObject = QUERYINTERFACE(lpUnk, IOleObject);
  293. lpUnk->Release();
  294. if (m_lpObject == NULL)
  295. AfxThrowOleException(E_OUTOFMEMORY);
  296. }
  297. // cache the IViewObject interface
  298. m_lpViewObject = QUERYINTERFACE(m_lpObject, IViewObject2);
  299. if (m_lpViewObject == NULL)
  300. return;
  301. // setup for advises; we assume that OLE cleans them up properly
  302. LPADVISESINK lpAdviseSink =
  303. (LPADVISESINK)GetInterface(&IID_IAdviseSink);
  304. // set up view advise
  305. VERIFY(m_lpViewObject->SetAdvise(DVASPECT_CONTENT, 0, lpAdviseSink)
  306. == S_OK);
  307. // the server shows these in its user-interface
  308. //  (as document title and in File Exit menu)
  309. m_lpObject->SetHostNames(T2COLE(AfxGetAppName()),
  310. T2COLE(_T("Test")));
  311. // all items are "contained" -- this makes our reference to this object
  312. //  weak -- which is needed for links to embedding silent update.
  313. OleSetContainedObject(m_lpObject, TRUE);
  314. CHARRANGE cr;
  315. this->GetSel( cr );
  316. cr.cpMin = cr.cpMax -1;
  317. this->SetSel( cr );
  318. REOBJECT reo;
  319. memset( &reo, 0, sizeof( reo ) );
  320. reo.cbStruct = sizeof( reo );
  321. CLSID classID;
  322. if ( m_lpObject->GetUserClassID( &classID ) != S_OK)
  323. classID = CLSID_NULL;
  324. reo.clsid = classID;
  325. reo.cp = REO_CP_SELECTION;
  326. reo.poleobj = m_lpObject;
  327. reo.pstg = m_lpStorage;
  328. LPOLECLIENTSITE lpClientSite;
  329. this->GetIRichEditOle()->GetClientSite( &lpClientSite );
  330. reo.polesite = lpClientSite;
  331. SIZEL sizel;
  332. sizel.cx = sizel.cy = 0; // let richedit determine initial size
  333. reo.sizel = sizel;
  334. reo.dvaspect = DVASPECT_CONTENT;
  335. reo.dwFlags = REO_RESIZABLE;
  336. reo.dwUser = 0;
  337. HRESULT hr = this->GetIRichEditOle()->InsertObject( &reo );
  338. }
  339. (2)根据位图句柄创建OleCreateStaticFromData();用这个函数可以把资源中的图片插入到文本框中
  340. void CRichEditCtrlEx::InsertBitmap(HBITMAP hBitmap)
  341. {
  342. STGMEDIUM stgm;
  343. stgm.tymed = TYMED_GDI;    // Storage medium = HBITMAP handle
  344. stgm.hBitmap = hBitmap;
  345. stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium
  346. FORMATETC fm;
  347. fm.cfFormat = CF_BITMAP;    // Clipboard format = CF_BITMAP
  348. fm.ptd = NULL;       // Target Device = Screen
  349. fm.dwAspect = DVASPECT_CONTENT;   // Level of detail = Full content
  350. fm.lindex = -1;       // Index = Not applicaple
  351. fm.tymed = TYMED_GDI;  
  352. ////创建输入数据源
  353. IStorage *pStorage; 
  354. ///分配内存
  355. LPLOCKBYTES lpLockBytes = NULL;
  356. SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
  357. if (sc != S_OK)
  358. AfxThrowOleException(sc);
  359. ASSERT(lpLockBytes != NULL);
  360. sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
  361. STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);
  362. if (sc != S_OK)
  363. {
  364. VERIFY(lpLockBytes->Release() == 0);
  365. lpLockBytes = NULL;
  366. AfxThrowOleException(sc);
  367. }
  368. ASSERT(pStorage != NULL);
  369. COleDataSource *pDataSource = new COleDataSource;
  370. pDataSource->CacheData(CF_BITMAP, &stgm);
  371. LPDATAOBJECT lpDataObject = 
  372. (LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);
  373. ///获取RichEdit的OLEClientSite
  374. LPOLECLIENTSITE lpClientSite;
  375. this->GetIRichEditOle()->GetClientSite( &lpClientSite );
  376. ///创建OLE对象
  377. IOleObject *pOleObject;
  378. sc = OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
  379. &fm,lpClientSite,pStorage,(void **)&pOleObject);
  380. if(sc!=S_OK)
  381. AfxThrowOleException(sc);
  382. ///插入OLE对象
  383. REOBJECT reobject;
  384. ZeroMemory(&reobject, sizeof(REOBJECT));
  385. reobject.cbStruct = sizeof(REOBJECT);
  386. CLSID clsid;
  387. sc = pOleObject->GetUserClassID(&clsid);
  388. if (sc != S_OK)
  389. AfxThrowOleException(sc);
  390. reobject.clsid = clsid;
  391. reobject.cp = REO_CP_SELECTION;
  392. reobject.dvaspect = DVASPECT_CONTENT;
  393. reobject.poleobj = pOleObject;
  394. reobject.polesite = lpClientSite;
  395. reobject.pstg = pStorage; 
  396. HRESULT hr = this->GetIRichEditOle()->InsertObject( &reobject );
  397. }
  398. 4、读取/写入RTF格式字符串
  399.   CRichEditCtrl 提供了两个函数StreamIn()和StreamOut()来实现这个功能,输出的内容包含文本信息和字体信息。我把这两个函数重新包装了一下 ,用GetRTF()把格式文本返回到一个CString变量中SetRTF(CString )实现逆过程。具体代码参看本文附带的工程文件。
  400.