|
|
一.常见问题5 q8 E3 i$ N" L: @- x/ c
a.可以编译,不能执行的
! n1 d( h6 {4 `- j, m+ Q2 oAfxInitRichEdit();
/ g5 o! ^" | V5 J c" l, a& p7 P$ k+ ^0 Y- W; J% ?
b.升级默认的Riched版本(默认的有一些bug),如# j9 j/ Z7 `: Z/ d8 y* d
可在InitInstance中添加
2 x8 T6 |$ u" S* U, L5 dLoadLibrary("RICHED20.DLL") ) p* Z2 x; t- h9 j
最后注意 FreeLibrary+ d$ k) S9 B+ B% C
1 [, d. d8 d6 M) G- q
如果是CRichEditView基类的可用
9 K1 @ F7 U6 h! W& fBOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
; d) C6 D# s% _8 b. J{* c0 s" X4 y- b7 b r O. R
//装入rich edit version 2.0
( p' Y P% q$ D0 fif (LoadLibraryA("RICHED20.DLL") == NULL)
- a3 k' h# B1 W0 T. j# T{- L, M( N9 {/ u; c5 V+ K
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);1 c3 C. D5 G3 k
PostMessage(WM_QUIT,0,0);2 R& P- _+ m4 p) Z5 G s' G
return FALSE;
3 ?8 t$ F2 U" `}, y: k1 w/ g* S. \( r8 j
8 T2 t/ u" G# X% K& a( Pm_strClass = RICHEDIT_CLASSA;//for 2.0 class1 t4 h, M: \7 d: Q
0 A' e# [3 h, C: Y% k
return CRichEditView::PreCreateWindow(cs);
1 |* z8 O5 b2 a}
5 [$ m8 G& p5 ?# ~; U4 d" C$ u- d: n" E j( B2 g
c.最后追加行. T0 G! u0 J% A% B4 P
richeditctrl.SetSel(-1, -1);
8 H1 f7 U/ y& [( Rricheditctrl.ReplaceSel( (LPCTSTR)str );% k; g/ t Y2 }" n
5 ~: e- q/ v) [6 g7 M6 L3 L
d.字数限制6 {& N7 r$ z% x8 Y
CRichEditCtrl::LimitText(long nChars)
4 o2 I( J/ T; S2 g' S$ e5 M, y7 w5 S9 U, ^& F2 A# H2 s3 }4 r" @
e.换行切换
$ i- S8 ?8 Z/ z8 E W1 q5 W# b$ [CRichEditView的OnInitialUpdate()函数中加入下面两句:
+ Q$ y+ w7 k$ W* gm_nWordWrap = WrapNone;
* Q( b, W5 E# V0 Z& X! D8 x7 W% I0 QWrapChanged(); 8 K/ p+ L: L) Q
WrapChanged实际上也是调用
+ N& u( b* H! P Zctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone( n) y: M7 @) q/ U) d: k
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
+ @" b$ L3 x0 g6 v- I. I还有不常用的 m_nWordWrap == WrapToTargetDevice3 G# E9 H- c. E0 X
ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());1 k6 m* q' h: p0 I) J2 Q7 V3 x- g
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return% `- _+ s( U) H
+ j" x R) M; U+ tf.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
5 G) h1 m) z* GpmyRichEditCtrl->PasteSpecial(CF_TEXT);& ~( ~ {# c) l& }
2 q/ ]4 e; x$ f
g.随着输入随着自动滚动条滚动到最后一行
" w; D: l+ y! \5 ]7 i7 xint nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();! s! d. c1 d3 P% \
if (nFirstVisible > 0)% ?2 c- A( _5 b; R. ]- i' ?
{
* Y/ @6 p) G5 i1 ] pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);' m& G. O% r7 o- X
}- R% {! n, O5 F" @. x: u# X3 ~ B
或
N' d- {' \) w& m" C7 F) B6 x' ]m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);
1 Q6 G: h5 M& A' F7 m' t& [# N5 d
w7 A2 a; \" Z) h& @
! A) Q% ?7 \8 H% z- x) ^: b( xh.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
2 d. B0 c& I2 BSendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
6 r7 t# w: d) PTM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
8 X7 ?6 M% Q* @/ N! OSendMessage(EM_SETUNDOLIMIT,100,0);; z8 x$ t5 n9 U( a
$ g9 Z" L) M1 o; p- q8 Li.响应OnChange
) v; R1 c9 I( V) W" ^EM_SETEVENTMASK 设置 ENM_CHANGE
3 e% S {' F9 nlong lMask = GetEventMask();, H1 _. ^' F) j* B) n8 v# f
lMask |= ENM_CHANGE;( Q, {8 B6 t8 r
lMask &= ~ENM_PROTECTED;( m* Y: D/ i5 v) q6 F8 m- F
SetEventMask(lMask);
& B9 `1 B6 M9 _1 O' ?" d* n! e4 N; h8 c: i
j.设置只读
; |9 X5 d' m+ s/ Q) y& KCRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );! T, f v: S1 F8 {, C3 B3 k
通过设置PROTECTED实现选中的文本只读,参见
0 z2 {4 ^4 O. M$ B+ o6 K$ jhttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
& g% d* ~) {5 t+ T/ o5 |" Y' F! n Y p8 i2 b0 i
二.函数应用
$ `6 H1 b$ x9 m1 q3 T `a.设置字体(主要是通过SetSelectionCharFormat)
% P$ r0 G; F6 X V& m! N, J0 i: i! ^CHARFORMAT cf;
2 w: S' K/ g# l1 Q+ Q0 trich.GetSelectionCharFormat(cf);
" N4 j2 A: g3 c/ ~: r2 Z0 H1 [cf.dwMask|=CFM_BOLD;* q' _) Q0 ~# U" H$ c4 G5 O! o& P
cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;0 E/ b* V! w# Y
cf.dwMask|=CFM_ITALIC;1 }& U9 k/ U4 ?5 s# q$ j0 {+ h
cf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;' M$ b& B$ X* r+ X2 d2 w: j
cf.dwMask|=CFM_UNDERLINE;
4 |/ `" i/ v1 @: f2 lcf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;2 p9 r) o0 `0 W+ a2 W0 M
cf.dwMask|=CFM_COLOR;
& P Y' l" X0 g6 _" Pcf.crTextColor = RGB(255,0,0);//设置颜色
2 L+ I. c2 \2 e2 K8 R0 `/ Dcf.dwMask|=CFM_SIZE;
3 | N- [5 l! k3 b4 b* a/ d: wcf.yHeight =200;//设置高度
8 U7 N' k( s. b& B8 ^* `cf.dwMask|=CFM_FACE;5 `- e& i* g, o) i) x
strcpy(cf.szFaceName ,_T("隶书"));//设置字体
/ T1 Y! r+ B8 Qrich.SetSelectionCharFormat(cf);8 z7 P3 J/ Y2 U F" ~+ n
3 t! e+ r( d! v$ D# N3 e' Tb.设置字体的行间距& }1 W G0 [; a& {( s" M
要用richedit2.0以上8 u! J. K6 w0 y1 U9 @
试试
- X+ t5 W7 z3 ^' ?* ~& yPARAFORMAT2 pf;! j4 K$ F8 j! w7 u! K
pf.cbSize = sizeof(PARAFORMAT2);- c7 U, B. ?3 w9 X1 w* K6 i
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;9 p1 U# [( ~9 |4 b d' _# m
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
$ o6 L5 f7 y9 k/ Fpf.dxOffset = 10;3 k! D" _$ L3 }
VERIFY(SetParaFormat(pf)); 2 Q( Z9 R0 N3 j7 D% i- a8 v
常用的dwMask有
* u2 b7 m9 Z, i/ K! [PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET( D: \2 @: n/ G$ H
2 使用阿拉伯数字 (1, 2, 3, ...). . p1 v) h, T" y/ P6 f/ D) j% g; X3 k
3 使用小写字母 (a, b, c, ...).
/ ]+ [) M* z& T0 p! e% w, c& |4 使用大写字母 (A, B, C, ...).
3 M7 w5 Y' N- a$ Q" w5 使用小写罗马数字 (i, ii, iii, ...).
9 {5 A( g' J; V6 使用大写罗马数字 (I, II, III, ...). , K: n5 H7 I! k" N1 P% u
7 自定义,字符见成员 wNumberingStart.
5 H* d" u$ K5 d9 O$ {PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips1 j6 u, t8 p0 T% G! D) z' y& h
PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进; j$ {' S. w9 x: {2 Z: T* w
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
/ ~: f0 H1 S% XPFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
* w0 M* s! C! W0 E% P7 L" _5 l
7 Q" f! R: g% j' gc.设置CRichEditCtrl(2.0)背景透明 * o6 g3 k) d/ d8 ?, l r5 m9 K& r
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);3 r. Y' @2 h' {9 P' S
style &= WS_EX_TRANSPARENT;* v) J( Z9 R# Z
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
+ l. c" n/ o+ H, z% S' N0 n5 _0 a1 I或 CreateEx,然后把WS_EX_TRANSPARENT样式加上$ {" P4 x* I; s' X
& \5 G2 @9 {2 ]! G5 d2 E1 W4 ?1 Qe.得到内容有三种& [3 I3 ]& C! l9 w7 A' q: g @
1)GetWindowText* [" q( U: K/ W
2)使用EM_GETTEXTEX1 \1 r) u: \2 N c3 q
GETTEXTEX gt;5 j! d6 O0 I. `, J3 M* Z
gt.cb = 200;
, p$ l- c! e/ Z5 p! n# t( e" ygt.flags = GT_DEFAULT;& z6 Z1 _1 C6 l! G+ b
gt.codepage = CP_ACP ;
' P, _3 V- _) [0 M. A4 a( Fgt.lpDefaultChar = NULL;
- k+ N. {) L( R; A& W+ m: Bgt.lpUsedDefChar = NULL;
- D: n7 N; ?4 z6 P% _. O8 r' ~SendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);% q1 c1 K- h/ |( y# E5 j }
3)StreamOut(主要用于RTF等格式输出)
/ I( i0 J, n/ m3 }0 j; }6 Fstatic DWORD CALLBACK
\; ~* S" g% w7 \/ dMyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)" w u+ v: k. x
{+ g' K9 H( h& r/ a7 F
CFile* pFile = (CFile*) dwCookie;
3 D$ O" p* C8 o$ G* a; v# u- D, g! _4 Y) u8 D# d! Q Q
pFile->Write(pbBuff, cb);
& M( R/ Y6 d1 a: W4 n *pcb = cb;
% t2 b. L8 U' ]) ~" Q( H: w7 u( | m! N8 l
return 0;; r& R1 I; D- \" m# ^5 V4 n
}
' K( p: O7 z9 [$ E; k
- }- h* v* P: f' C8 v8 I/ Q0 c: i& V
9 v$ {* `. E) Z7 B4 O( B$ k4 j CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);3 j! @4 U% u3 |! g
EDITSTREAM es;, Z/ |/ ^0 Y( n3 @
es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用, b+ b: ~5 s( {$ o
es.pfnCallback = MyStreamOutCallback; 1 K2 i( V, I, d: K/ D
pmyRichEditCtrl->StreamOut(SF_RTF, es);
; c' `# p/ Z- |2 N Y t读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
8 D0 R. u. f$ S$ t' u5 ?0 g
* s0 ^$ K% z, ]/ h. {5 F8 H, `7 A/ Pf.查找字符串$ A8 m! J. o9 @ D' P6 V
FINDTEXTEX ft;
9 g$ Y2 C$ j, C# b. V; rft.chrg.cpMin = 0;3 C; v+ q2 _: P+ G! A- d
ft.chrg.cpMax = -1;! t( r- Z- Y; S5 n+ o# w1 W+ W3 }: N; Z) O
ft.lpstrText = "|";- f, v. H8 ^2 s6 g! c
long lPos = FindText(0, &ft);
3 h/ b' g" E; ~' g/ @5 j1 x3 B
2 ^3 d0 k1 K; [7 K6 U如果要继续查找,修改cpMin,如
# v: {' a$ {/ b' Bint nCount = 0;
. s0 x# X/ A3 e$ Z+ Mdo
, ~1 b2 {% V6 x{
4 F& B: A" t |0 Y long lPos = GetRichEditCtrl().FindText(0, &ft);
1 s% P; @/ Y( v6 v) V4 l if( -1 == lPos) break;
( N, Z2 \( C6 m9 y+ A5 ?1 l ft.chrg.cpMin = lPos + strlen(ft.lpstrText);' h+ h p1 I, X( o- y! V
++nCount;
4 G& ? f0 c- \}while(TRUE);
; `, w9 c5 v5 M
7 N7 A6 F' _- g* K$ D8 \g.以Html格式保存
( b, X, _6 S1 W目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
$ N$ F/ h. T9 L# E; zhttp://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
y1 L" x0 M3 q4 O( x3 b4 A% l ]: {' h5 K9 h0 P4 r
h.重载OnProtected函数得到对应的消息,如粘贴等
- k4 Y8 G* `: h1 @* Y$ kvoid CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)0 h2 y: y8 R: T/ W0 i9 s
{( M* J/ Y: h3 X% L
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
_; B% B3 f. ^; n( g3 Q8 f$ u' [
5 c4 |# D- j+ D' a' D7 c" _; F switch (pEP->msg) {( ~! q7 v# t) R) F2 B& p
case WM_KEYDOWN://按键,判断pEP->wParam
# z% b0 ~( \2 ?1 C case WM_PASTE://粘贴8 \. o! p% J1 Z
case WM_CUT://剪切8 M8 ]% K! D! g6 B7 [
case EM_SETCHARFORMAT:+ J! H. h/ {2 A* x
default:& j- J; h2 N0 ^0 r$ p0 S
break;, T' d7 n1 }+ {* |. [( u
};) E3 H1 ~ U& q
& u: ^5 ~7 n, @3 c% s8 d' B& f
*pResult = FALSE;
9 E% s. o. x* ~: \0 T8 V7 f}
Q' N9 g' c% ~6 l0 ~5 v6 x- d, K# A V/ l. I8 @
三.聊天常用
G! k; C. k: _+ T2 M" ]6 c# Ea.LINK 链接功能* I- t6 I( |/ X6 c! @" I* E0 I
1. LoadLibrary(_T("Riched20.dll"));3 L0 }5 p. p) w7 l+ F$ P! Q
2. 创建RichEdit2.0控件
' t" r1 x" d1 X: t4 J \' [& D CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
0 J3 @# w( R" {3 @# ||ES_READONLY|ES_WANTRETURN|ES_MULTILINE,, I3 i; v/ {" ~1 G5 C
rect.left, rect.top, cx, cy,
$ s/ l2 F4 j5 M& r pParentWnd->m_hWnd, (HMENU)nID, NULL);
. P v% z9 s6 w% i' {3. 设定选中的文字为链接显示 m5 o8 u" Z. v. Q; ~
CHARFORMAT2 cf2;
" r" v8 V% J: [ZeroMemory(&cf2, sizeof(CHARFORMAT2));//
! z# ?, t# p" e7 l$ @cf2.cbSize = sizeof(CHARFORMAT2);
9 r$ a8 S' M1 L8 mcf2.dwMask = CFM_LINK;; c) m) d Q9 g7 F
cf2.dwEffects |= CFE_LINK;
. {3 Z4 I3 Z6 b5 ym_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
5 g2 ?# A0 g, y) c# l4.支持链接的点击响应 r7 T: u! T. ~
m_cRichEdit.SetEventMask(ENM_LINK);( p( R* I1 q' F. R& |% x
5.响应链接的点击EN_LINK! |7 b4 x4 _6 `9 ]- U
' `3 @6 w) e9 l; ^- Q
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
% {* f4 H* Z! K5 r0 R8 dON_NOTIFY_REFLECT(EN_LINK,OnURL)
. O2 ^' r/ K2 R M, \END_MESSAGE_MAP()
8 b; P f0 y' q9 G0 D) D......& E+ B0 K+ I; o
' {, x& Y8 L# Q3 T) e* Cvoid CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)' J4 N$ y; u* G- L! }/ F D6 b+ K
{( \. z Z0 O% c# S- s
TCHAR LinkChar[512];
; J, w4 V5 a- Q8 f0 |ENLINK *pLink = (ENLINK *)pNmhdr; R" ?$ y+ u/ _+ H+ J W) A2 H4 ^( J
if (pLink->msg == WM_LBUTTONUP)& I- Z( w/ T, L A! g+ v3 j) E" g
{$ n" B( F; F/ b0 n6 N1 x% T
SetSel(penLink->chrg);//这是链接的文字范围
' P" d$ _* s, ]" Tlong Res = GetSelText((char *)LinkChar);//这是链接文字4 t7 I' A1 @+ o2 a. n, s
//后面是你的处理过程
I3 U! ]7 f2 o) Q) z ......
; X) J! F- h* y6 P! k* R& S$ r }- h& ~+ d' A6 G" _1 ?7 O
}5 [' c& R- a2 A i) z
( r. ]% e& u3 @( i; z: Kb.插入位图
8 q6 U) ~3 B2 @5 s* G+ T: z" rhttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
1 c' ~6 J8 k1 Z5 w! }/ O% shttp://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
2 v0 Z0 L8 O! i9 B0 \ r: I9 F2 g9 h
自定义在RichEdit中插入对象的图标
4 [3 X, x4 P3 l8 [6 L" p# `- dhttp://www.blogcn.com/user3/jiangsheng/blog/1319738.html
9 A3 w/ L1 ` [; r: v方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
* g. ~5 G+ o( ?1 s; a W只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片0 ?0 [1 r3 n- I! K
3 A2 S' D. `4 L8 D
使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。6 t) f& j' z! I: ]
另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。 # E" E$ F8 W; _6 P
' A* o7 g+ M+ t. b: x8 _c.显示GIF动画
8 R: k5 _3 z$ b- \; L. C常用的是通过qq的imageole.dll(也有用Gif89.dll的)* Q! x! Z ^; ~' t2 V; \# w* g& c
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
' B* u# m$ Q7 S' w; w( N2 U, Vhttp://www.codeproject.com/richedit/AnimatedEmoticon.asp
1 O" V7 ?/ C8 a2 k8 B' S3 q. s" q' P0 ~7 z9 Y1 `
在richedit控件中插入动态GIF (Native C++版)5 F \# n& S2 p, J3 h
http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx' l2 H7 J( `; i3 A% z n: L
- g* K4 `6 V0 t0 `; `+ V. j! Hd.IRichEditOleCallback的使用8 E( U. R+ V" P+ v5 t2 Q: C
http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022" F* o; q! h0 d! r. ~
8 H0 H2 {0 H/ a/ a
类似 MSN 信息发送框的制作(上)
+ Q+ b# W: F' j% Q2 yhttp://www.vckbase.com/document/viewdoc/?id=10879 o4 d1 p$ O4 O1 [0 J* p, T
内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串7 Q/ r+ C1 K: _+ w7 ^ C
) q. m( G: w& }* i4 D3 M自定义 CRichEditCtrl 控件
2 W ]1 I1 h3 s: S, R- chttp://www.vckbase.com/document/viewdoc/?id=328
/ x. `4 F& j* C0 K) |$ ~3 K' w内容包含:鼠标右键消息,消息映射,字体变换& O E$ x/ e- ?$ ]- F' ^4 a
# J' }! b- J, C9 |; _5 {
PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母3 U( {7 W8 o" o7 Y7 c5 S% T
是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778 ! j- v, o7 ?% w) ]
----------------------4 s! I4 P" x6 x7 A$ t/ Q
比我想象中还要花时间,所以最后潦草了点,见谅 |
|