richedit 常见使用问题



 
 
  1. richedit 常见使用问题
  2. 一.常见问题
  3. a.可以编译,不能执行的
  4. 在需要在相应的对话框中加上InitInstance( void)函数中添加
  5. AfxInitRichEdit();
  6. b.升级默认的Riched版本(默认的有一些bug),如
  7. 可在InitInstance中添加
  8. LoadLibrary( "RICHED20.DLL")
  9. 最后注意 FreeLibrary
  10. 如果是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. }
  20. m_strClass = RICHEDIT_CLASSA; //for 2.0 class
  21. return CRichEditView::PreCreateWindow(cs);
  22. }
  23. c.最后追加行
  24. richeditctrl.SetSel( -1, -1);
  25. richeditctrl.ReplaceSel( (LPCTSTR)str );
  26. d.字数限制
  27. CRichEditCtrl::LimitText( long nChars)
  28. e.换行切换
  29. CRichEditView的OnInitialUpdate()函数中加入下面两句:
  30. m_nWordWrap = WrapNone;
  31. WrapChanged();
  32. WrapChanged实际上也是调用
  33. ctrl.SetTargetDevice( NULL, 1); //m_nWordWrap == WrapNone
  34. ctrl.SetTargetDevice( NULL, 0); //m_nWordWrap == WrapToWindow
  35. 还有不常用的 m_nWordWrap == WrapToTargetDevice
  36. ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
  37. 如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return
  38. f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
  39. pmyRichEditCtrl->PasteSpecial(CF_TEXT);
  40. g.随着输入随着自动滚动条滚动到最后一行
  41. int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
  42. if (nFirstVisible > 0)
  43. {
  44. pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
  45. }
  46. m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
  47. h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
  48. SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO, 0);
  49. TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
  50. SendMessage(EM_SETUNDOLIMIT, 100, 0);
  51. i.响应OnChange
  52. EM_SETEVENTMASK 设置 ENM_CHANGE
  53. long lMask = GetEventMask();
  54. lMask |= ENM_CHANGE;
  55. lMask &= ~ENM_PROTECTED;
  56. SetEventMask(lMask);
  57. j.设置只读
  58. CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );
  59. 通过设置PROTECTED实现选中的文本只读,参见
  60. http: //www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
  61. 二.函数应用
  62. a.设置字体(主要是通过SetSelectionCharFormat)
  63. CHARFORMAT cf;
  64. rich.GetSelectionCharFormat(cf);
  65. cf.dwMask|=CFM_BOLD;
  66. cf.dwEffects|=CFE_BOLD; //设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
  67. cf.dwMask|=CFM_ITALIC;
  68. cf.dwEffects|=CFE_ITALIC; //设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
  69. cf.dwMask|=CFM_UNDERLINE;
  70. cf.dwEffects|=CFE_UNDERLINE; //设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;
  71. cf.dwMask|=CFM_COLOR;
  72. cf.crTextColor = RGB( 255, 0, 0); //设置颜色
  73. cf.dwMask|=CFM_SIZE;
  74. cf.yHeight = 200; //设置高度
  75. cf.dwMask|=CFM_FACE;
  76. strcpy(cf.szFaceName ,_T( "隶书")); //设置字体
  77. rich.SetSelectionCharFormat(cf);
  78. b.设置字体的行间距
  79. 要用richedit2 .0以上
  80. 试试
  81. PARAFORMAT2 pf;
  82. pf.cbSize = sizeof(PARAFORMAT2);
  83. pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
  84. pf.wNumbering = PFN_BULLET; //注意PFM_NUMBERING
  85. pf.dxOffset = 10;
  86. VERIFY(SetParaFormat(pf));
  87. 常用的dwMask有
  88. PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
  89. 2 使用阿拉伯数字 ( 1, 2, 3, ...).
  90. 3 使用小写字母 (a, b, c, ...).
  91. 4 使用大写字母 (A, B, C, ...).
  92. 5 使用小写罗马数字 (i, ii, iii, ...).
  93. 6 使用大写罗马数字 (I, II, III, ...).
  94. 7 自定义,字符见成员 wNumberingStart.
  95. PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
  96. PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进
  97. PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
  98. PFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
  99. c.设置CRichEditCtrl( 2.0)背景透明
  100. long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
  101. style &= WS_EX_TRANSPARENT;
  102. ::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
  103. 或 CreateEx,然后把WS_EX_TRANSPARENT样式加上
  104. e.得到内容有三种
  105. 1)GetWindowText
  106. 2)使用EM_GETTEXTEX
  107. GETTEXTEX gt;
  108. gt.cb = 200;
  109. gt.flags = GT_DEFAULT;
  110. gt.codepage = CP_ACP ;
  111. gt.lpDefaultChar = NULL;
  112. gt.lpUsedDefChar = NULL;
  113. SendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
  114. 3)StreamOut(主要用于RTF等格式输出)
  115. static DWORD CALLBACK
  116. MyStreamOutCallback (DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  117. {
  118. CFile* pFile = (CFile*) dwCookie;
  119. pFile->Write(pbBuff, cb);
  120. *pcb = cb;
  121. return 0;
  122. }
  123. CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
  124. EDITSTREAM es;
  125. es.dwCookie = (DWORD) &cFile; //设置用例参数,以便回调函数调用
  126. es.pfnCallback = MyStreamOutCallback;
  127. pmyRichEditCtrl->StreamOut(SF_RTF, es);
  128. 读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
  129. f.查找字符串
  130. FINDTEXTEX ft;
  131. ft.chrg.cpMin = 0;
  132. ft.chrg.cpMax = -1;
  133. ft.lpstrText = "|";
  134. long lPos = FindText( 0, &ft);
  135. 如果要继续查找,修改cpMin,如
  136. int nCount = 0;
  137. do
  138. {
  139. long lPos = GetRichEditCtrl().FindText( 0, &ft);
  140. if( -1 == lPos) break;
  141. ft.chrg.cpMin = lPos + strlen(ft.lpstrText);
  142. ++nCount;
  143. } while(TRUE);
  144. g.以Html格式保存
  145. 目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
  146. http: //www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
  147. h.重载OnProtected函数得到对应的消息,如粘贴等
  148. void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
  149. {
  150. ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
  151. switch (pEP->msg) {
  152. case WM_KEYDOWN: //按键,判断pEP->wParam
  153. case WM_PASTE: //粘贴
  154. case WM_CUT: //剪切
  155. case EM_SETCHARFORMAT:
  156. default:
  157. break;
  158. };
  159. *pResult = FALSE;
  160. }
  161. 三.聊天常用
  162. a.LINK 链接功能
  163. 1. LoadLibrary(_T( "Riched20.dll"));
  164. 2. 创建RichEdit2 .0控件
  165. CreateEx( 0, _T( "RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
  166. |ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
  167. rect.left, rect.top, cx, cy,
  168. pParentWnd->m_hWnd, (HMENU)nID, NULL);
  169. 3. 设定选中的文字为链接显示
  170. CHARFORMAT2 cf2;
  171. ZeroMemory(&cf2, sizeof(CHARFORMAT2)); //
  172. cf2.cbSize = sizeof(CHARFORMAT2);
  173. cf2.dwMask = CFM_LINK;
  174. cf2.dwEffects |= CFE_LINK;
  175. m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
  176. 4.支持链接的点击响应
  177. m_cRichEdit.SetEventMask(ENM_LINK);
  178. 5.响应链接的点击 EN_LINK
  179. BEGIN_MESSAGE_MAP (CMyRichEdit, CRichEditCtrl)
  180. ON_NOTIFY_REFLECT (EN_LINK,OnURL)
  181. END_MESSAGE_MAP ()
  182. ......
  183. void CMyRichEdit:: OnURLClick (NMHDR *pNmhdr, LRESULT *pResult)
  184. {
  185. TCHAR LinkChar[ 512];
  186. ENLINK *pLink = (ENLINK *)pNmhdr;
  187. if (pLink->msg == WM_LBUTTONUP)
  188. {
  189. SetSel(penLink->chrg); //这是链接的文字范围
  190. long Res = GetSelText(( char *)LinkChar); //这是链接文字
  191. //后面是你的处理过程
  192. ......
  193. }
  194. }
  195. b.插入位图
  196. http: //www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
  197. http: //www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
  198. 自定义在RichEdit中插入对象的图标
  199. http: //www.blogcn.com/user3/jiangsheng/blog/1319738.html
  200. 方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
  201. 只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
  202. 使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
  203. 另外可以参考“ Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
  204. c.显示GIF动画
  205. 常用的是通过qq的imageole.dll(也有用Gif89.dll的)
  206. http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
  207. http://www.codeproject.com/richedit/AnimatedEmoticon.asp
  208. 在richedit控件中插入动态GIF (Native C++版)
  209. http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx
  210. d.IRichEditOleCallback的使用
  211. http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022
  212. 类似 MSN 信息发送框的制作(上)
  213. http://www.vckbase.com/document/viewdoc/?id=1087
  214. 内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串
  215. 自定义 CRichEditCtrl 控件
  216. http://www.vckbase.com/document/viewdoc/?id=328
  217. 内容包含:鼠标右键消息,消息映射,字体变换
  218. PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
  219. 是一个专门的设计 Dual-font, Smart font apply, 参见http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778
  220. 不能显示图片等其他OLE对象
  221. MFC提供的CRichEditCtrl没有提供直接显示图片等OLE对象的属性或方法设置,但是提供了一个接口SetOLECallback( IRichEditOleCallback* pCallback );
  222. 要让CRichEditCtrl显示图片,就得在IRichEditOleCallback上下功夫。
  223. IRichEditOleCallback是windows中的接口,它的定义如下:
  224. ContextSensitiveHelp:
  225. 通过该方法通知应用程序它将以上下文关联方式调度帮助。
  226. DeleteObject:
  227. 通过该方法发出通知:一个对象即将从RichEdit控件中删除
  228. GetClipboardData:
  229. 通过该方法允许RichEdit的客户端(调用程序)提供自己的粘贴对象
  230. GetContextMenu:
  231. 通过该方法向应用程序提出通过鼠标右键事件来获取上下文菜单的请求
  232. GetDragDropEffect:
  233. 通过该方法允许RichEdit的客户端(调用程序)设置拖动操作的效果
  234. GetInPlaceContext:
  235. 通过该方法提供了应用程序级和文档级接口,以及必要的支持In-place激活的信息
  236. GetNewStrorage:
  237. 通过该方法存储从粘贴板或超文本流(RTF)中读取的新对象
  238. QueryAcceptData:
  239. 通过该方法决定在粘贴操作或拖放操作中引入的数据是否可以被接受。
  240. QueryInsertObject:
  241. 通过该方法向应用程序询问某个对象是否可以被插入
  242. ShowContainerUI:
  243. 通过该方法告知应用程序是否显示自己的操作界面
  244. 大致了解了IRichEditOleCallback接口后,就应该清楚,要显示图片等ole对象,至少应该实现GetNewStorage方法,因为该方法是存储ole对象的接口方法。
  245. 以下是接口声明的代码:
  246. interface IExRichEditOleCallback; // forward declaration (see below in this header file)
  247. IExRichEditOleCallback* m_pIRichEditOleCallback;
  248. BOOL m_bCallbackSet;
  249. interface IExRichEditOleCallback : public IRichEditOleCallback
  250. {
  251. public:
  252. IExRichEditOleCallback();
  253. virtual ~IExRichEditOleCallback();
  254. int m_iNumStorages;
  255. IStorage* pStorage;
  256. DWORD m_dwRef;
  257. virtual HRESULT STDMETHODCALLTYPE GetNewStorage(LPSTORAGE* lplpstg);
  258. virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);
  259. virtual ULONG STDMETHODCALLTYPE AddRef();
  260. virtual ULONG STDMETHODCALLTYPE Release();
  261. virtual HRESULT STDMETHODCALLTYPE GetInPlaceContext(LPOLEINPLACEFRAME FAR *lplpFrame,
  262. LPOLEINPLACEUIWINDOW FAR *lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo);
  263. virtual HRESULT STDMETHODCALLTYPE ShowContainerUI(BOOL fShow);
  264. virtual HRESULT STDMETHODCALLTYPE QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp);
  265. virtual HRESULT STDMETHODCALLTYPE DeleteObject(LPOLEOBJECT lpoleobj);
  266. virtual HRESULT STDMETHODCALLTYPE QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT FAR *lpcfFormat,
  267. DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
  268. virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
  269. virtual HRESULT STDMETHODCALLTYPE GetClipboardData(CHARRANGE FAR *lpchrg, DWORD reco, LPDATAOBJECT FAR *lplpdataobj);
  270. virtual HRESULT STDMETHODCALLTYPE GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect);
  271. virtual HRESULT STDMETHODCALLTYPE GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE FAR *lpchrg,
  272. HMENU FAR *lphmenu);
  273. };


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值