|
|
一.常见问题3 X% B, S8 S4 J8 W
a.可以编译,不能执行的
+ P8 W( t. ~+ o' d1 B4 Y, _. @AfxInitRichEdit();+ }# @7 U [% w7 t
/ T1 @& W) g9 L+ J4 p- [+ wb.升级默认的Riched版本(默认的有一些bug),如7 X' C3 b0 B- n+ i- l+ E- A
可在InitInstance中添加+ q8 K% Q/ j1 v5 F2 E
LoadLibrary("RICHED20.DLL") ' d$ }% C' { N& |. |# C
最后注意 FreeLibrary
: A" L2 N+ W" ^1 \$ t D' A& G! n; ^! l( b% P. D; q% b
如果是CRichEditView基类的可用
9 H2 D) ]1 r% g# O( ]BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
1 \0 G5 {$ n; t2 y" X. J% x& k" N{/ U; M/ m l/ c' A: t# {
//装入rich edit version 2.0
6 T9 D. B! O' T X% l& aif (LoadLibraryA("RICHED20.DLL") == NULL)
" v4 Y4 e# O. i' _0 m- b{* B1 j$ Z8 U- j3 C& u
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
! e, _$ C9 ?4 [! B/ fPostMessage(WM_QUIT,0,0);1 i7 L' ^2 S% L F" g7 e* p
return FALSE;
H% U$ l! `# e3 t7 Z/ D' p}% Z* t, l' I; c
$ d* J6 L& ]2 u5 }: \! h- pm_strClass = RICHEDIT_CLASSA;//for 2.0 class
7 O' s( I7 w: k. t# e% F+ N8 e. y2 v/ q2 p) G! ^% e& R% y9 F, j% `7 B5 {) \
return CRichEditView::PreCreateWindow(cs);
* Y' e% s; j8 l3 i s}
2 m: z! p0 n4 @$ R) R7 S' s; \ b3 C5 T. [
c.最后追加行/ i& K$ o& v- e3 p
richeditctrl.SetSel(-1, -1);
s/ H% t! J! o; Wricheditctrl.ReplaceSel( (LPCTSTR)str );; O* [! P3 |7 h1 l8 h" X
% N2 \6 U( u7 y* F/ H/ a
d.字数限制8 } H! c8 X* S" d
CRichEditCtrl::LimitText(long nChars)
: y: q/ w& A+ a9 U
, z3 x0 f. z8 L% F% _. Te.换行切换
& z5 k' ^6 W# B: w* i9 hCRichEditView的OnInitialUpdate()函数中加入下面两句:: b) V; Y; p U4 p
m_nWordWrap = WrapNone;
9 ^) I) g, m3 T( P4 N2 ?WrapChanged(); * Z$ N% w4 {, o8 X+ H* G
WrapChanged实际上也是调用" g y% p2 Z2 ?1 n2 g
ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone6 k8 G" P5 r; x
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
( j. ?9 a- i5 ]* B6 s还有不常用的 m_nWordWrap == WrapToTargetDevice
1 g/ g+ {' H3 u$ |; ?, [& cctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
4 `3 \1 ?8 E- i# m, I如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return; I! k! C; V. F
% Y- `% q. C6 s$ xf.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴. \/ l5 H( H$ o
pmyRichEditCtrl->PasteSpecial(CF_TEXT);$ R# j' O4 |& j0 f z& U
% v: Y: C8 k1 W( ?+ eg.随着输入随着自动滚动条滚动到最后一行
$ p1 a! @, a* t4 P" `4 L. {$ Jint nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();+ h, E& u/ v8 Q: W
if (nFirstVisible > 0)! z# x* Q+ Z1 _) w/ [
{
. E- w% ~* |6 n" \ pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
: K# f& ?) E% V( J, m' i} ?; P; d4 l' F! m$ b
或
; C: {- G0 o0 _3 H2 Cm_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);, q6 e6 t: G9 G E
" O- l) {- R( `& K Y, M
- ~+ P5 t" y% ~8 {
h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
9 n0 L' j1 {, u3 w+ dSendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);7 P) f: A8 X& B* G$ z" R
TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
0 Q+ a% Z) Z9 ~; D4 ]: {SendMessage(EM_SETUNDOLIMIT,100,0);! c9 d. U3 F+ o/ i5 p
9 v, z1 C% m- U& X5 W
i.响应OnChange/ P8 c: }/ _0 v" p2 f! H3 @3 s3 a" r
EM_SETEVENTMASK 设置 ENM_CHANGE / |2 H5 T5 k- Y3 \$ P( @. V
long lMask = GetEventMask();
0 @6 m* Y6 T% q" hlMask |= ENM_CHANGE;
& I# b+ I3 C- O7 g$ GlMask &= ~ENM_PROTECTED;
- Z0 W1 z7 p" C, L. cSetEventMask(lMask);1 Z) Y3 H4 n: D! g7 M
, _7 a4 h! }! Uj.设置只读
% }7 U Q! y! T, h! H2 X @9 ICRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );# z3 O( ?' W, K; ]
通过设置PROTECTED实现选中的文本只读,参见
1 B* ]; A, V+ ]# Ihttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
; T( j% H$ u0 j( i* p1 h Z& b- @* y& I- K- B
二.函数应用
/ m' Z% U: z* {$ d1 @a.设置字体(主要是通过SetSelectionCharFormat)5 z3 a" ]3 b9 w q( F
CHARFORMAT cf;
5 v* w, m, M6 Y' Yrich.GetSelectionCharFormat(cf);
: N# T$ m4 Y* {% [9 w- x& ^' G) [cf.dwMask|=CFM_BOLD;
( t" z, N, [) \7 Vcf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;6 E" f: _- f$ ]8 d; L7 r
cf.dwMask|=CFM_ITALIC;
& t! `; L8 [6 H5 {2 B7 ~( X7 scf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
' G+ l9 ?) a5 ]/ q; {- D Wcf.dwMask|=CFM_UNDERLINE;
3 U9 ?4 W( g9 `' E$ G+ t& wcf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;0 Y; W; R/ c( L; V B7 \
cf.dwMask|=CFM_COLOR;
. @0 d0 @4 T% O) }( G- y; I3 wcf.crTextColor = RGB(255,0,0);//设置颜色
) Z2 B* j6 [6 Hcf.dwMask|=CFM_SIZE;
" G2 Q7 }. l: [& f% R zcf.yHeight =200;//设置高度5 i1 V6 I; ]4 ^, ]; p# F
cf.dwMask|=CFM_FACE;$ K2 V0 ]& i3 m
strcpy(cf.szFaceName ,_T("隶书"));//设置字体& o3 r- V Q& q) ?: c
rich.SetSelectionCharFormat(cf);; V9 [5 y1 T) C. x- F
: Q" m; k3 f+ R; L- u" }* S r. A
b.设置字体的行间距
* x: a! ?, c" g1 T6 q3 V% N要用richedit2.0以上2 f5 @, n9 s, ~8 m. v
试试
. {. C6 T. W' c- g+ Q- }6 cPARAFORMAT2 pf;
9 Q, D/ O, ?* @6 {3 e+ z, zpf.cbSize = sizeof(PARAFORMAT2);! E$ l1 ?5 z( ]/ }
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
0 W3 f8 \. A3 o$ gpf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING + N! p( x3 I$ g3 K7 a+ W
pf.dxOffset = 10;) ~' j" E5 j! o" S
VERIFY(SetParaFormat(pf)); 8 l8 C$ l6 V! ?& c% c
常用的dwMask有3 r$ B4 u4 S% `( A7 u( D8 q# T
PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
* J7 D5 \' S3 I7 V2 使用阿拉伯数字 (1, 2, 3, ...). " m% I2 v/ v: K. |/ ^
3 使用小写字母 (a, b, c, ...). ' N- K1 p% d1 t: ^
4 使用大写字母 (A, B, C, ...).
3 N7 V8 x) n& F z5 |0 k7 {5 使用小写罗马数字 (i, ii, iii, ...).
# R: Y. o4 E. X6 g: ~6 使用大写罗马数字 (I, II, III, ...).
: n, g/ ]7 V) l$ P% Q6 Q1 D; B7 Z- f7 自定义,字符见成员 wNumberingStart.
5 {; X1 `8 F$ VPFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
5 s+ ^6 s, O# X& PPFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进$ F8 T ^: e$ H0 r2 A7 v, m
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
# c; Y9 b8 Y5 z. RPFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
4 s5 n! }( K7 t3 n# G+ G* p: I8 ^+ _6 o1 | R6 W
c.设置CRichEditCtrl(2.0)背景透明
* y' ]: S: U6 f; l7 H# C2 nlong style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
$ P: y. @% w( K3 M2 w" G$ `style &= WS_EX_TRANSPARENT;
' |3 |: B! v6 c7 r2 W4 R& ~::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);) f" C- L+ k8 ?- @5 m
或 CreateEx,然后把WS_EX_TRANSPARENT样式加上4 { p8 i$ z4 e8 |7 a
; I! I5 N$ A1 S- b4 g6 f& le.得到内容有三种
9 r' t4 G/ l& r' t9 [1)GetWindowText
- [' M+ S4 {; Z& @0 G- q0 h2)使用EM_GETTEXTEX# F9 c/ q% A s4 c2 x
GETTEXTEX gt; a# k* r$ W3 l J8 f6 U
gt.cb = 200;
( @% f. |4 s, B; D7 |gt.flags = GT_DEFAULT;
7 q/ j* k9 p* V0 Y$ |9 u' ]gt.codepage = CP_ACP ;
: M! b! E. p5 m, d) Fgt.lpDefaultChar = NULL; 4 d! M) H/ Q6 u1 }
gt.lpUsedDefChar = NULL;
# Q! ^- y& P: p d9 YSendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
& `8 N/ y6 W9 n1 v' t9 T! U3)StreamOut(主要用于RTF等格式输出)% E# I0 m4 {0 i! E2 g
static DWORD CALLBACK + z; U! T* L5 `- O- A. k% m, G
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
: x0 e9 H8 k7 m3 p{2 n3 v9 @# N- S, K3 g
CFile* pFile = (CFile*) dwCookie;
' R0 K# t$ j5 F* d% h! f8 b' h
/ F) T& W9 y E& { pFile->Write(pbBuff, cb);
' o2 D% p8 ]1 h4 p( I3 l *pcb = cb;
, p- C h; Z; B" e5 ?8 L. J1 \2 l" Q+ I1 I) m, l R }. b! I" g
return 0;4 z! o) r0 P$ v/ \/ ?4 c' h
}. p5 z) }8 ~2 G2 f7 `: D) p
0 [& C1 L+ _8 K5 X, T n. l3 J) n6 r |( U5 A, i. ?9 p, t1 g
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
" P9 B$ p W4 s6 q EDITSTREAM es;
& X, Z0 f; T9 f( w# f; C. @ es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用4 k7 E; G, t: k3 J2 H; ?
es.pfnCallback = MyStreamOutCallback; ! _* ]: [, O7 w" G
pmyRichEditCtrl->StreamOut(SF_RTF, es);
( \& x2 `! O- L7 s读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
: s; l4 M" [" b. c( ~
+ c Q* Z! [1 M( b2 [f.查找字符串1 p! U7 e' k1 Z3 |/ z
FINDTEXTEX ft;2 Z6 v4 e0 q8 x% Z+ x( C1 b
ft.chrg.cpMin = 0;5 A6 ^ d& W+ v1 t7 s! R
ft.chrg.cpMax = -1;
6 z7 X. S" L+ s8 k) eft.lpstrText = "|";
8 S% d& `4 [% Z: ]( R) l0 |long lPos = FindText(0, &ft);
; T6 W1 t I& n% o
! n# X1 l! O3 C& v1 A! h如果要继续查找,修改cpMin,如
. j2 s' x: u5 C% A+ Qint nCount = 0;
3 b1 T" c2 ~) _! I' G% }. bdo
" Z. Q! }9 h6 i5 J9 h6 s1 j{
, @6 F) l' u! E8 L) P long lPos = GetRichEditCtrl().FindText(0, &ft);
- z* M; `; E& f* k+ @ if( -1 == lPos) break;8 T+ Y$ P9 ?, H9 d
ft.chrg.cpMin = lPos + strlen(ft.lpstrText);
' J# ?1 {0 u ^; B ++nCount;
) _7 l' p& O5 X, q}while(TRUE);0 ~) o n& X9 H3 B$ x
4 l" V4 O, |3 s% d" B1 bg.以Html格式保存
( b6 g: r K& y- A6 \0 K/ `/ s$ b目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
6 M+ B1 h& g- ~& H, Ghttp://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
6 B) H* D' Q8 J/ [! i% b1 v' Q) q
9 F# T4 J: R4 u+ ph.重载OnProtected函数得到对应的消息,如粘贴等
) J* e3 A: h2 d2 Y3 V$ dvoid CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
! G+ _7 G: f0 D4 \) e7 H/ Z{
& _) Y* `, `7 ?% `/ M! g ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;9 i% t( \6 o) a+ l R$ O9 H
; D& F$ Y8 L" e4 F0 i switch (pEP->msg) {
; h9 @: i, X( d5 N% t* W* S case WM_KEYDOWN://按键,判断pEP->wParam1 a' K( }* K9 n2 v, J) x# a2 k9 M
case WM_PASTE://粘贴; ~' [& m' g; j
case WM_CUT://剪切
+ X$ k- h Z: q" }. X case EM_SETCHARFORMAT:3 x. S2 q+ O* g9 z( b9 w4 X
default:
1 @& E% }4 l" g# k9 W d8 F break;
( ]/ M s0 Q" b0 c9 U; o };
a: D8 O8 A' ^* \/ z5 A% v
' U) V& {8 H. `8 i! r *pResult = FALSE;
& \1 ^6 h, R* v7 u3 }& h}
# R d9 G8 \) x3 }" r! ^" k6 {. i0 v: u2 O6 Q
三.聊天常用 0 b; u: i9 T+ {. E. I3 u
a.LINK 链接功能' S9 p. a" G/ r2 m
1. LoadLibrary(_T("Riched20.dll"));
2 K; e/ Q8 s& {+ x2. 创建RichEdit2.0控件$ o( J( ^; J1 n& }" |; ?" ]! E
CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP! ]% V+ S& ^3 e+ i5 p: u/ ?
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,: D- {* y/ X# v
rect.left, rect.top, cx, cy,) P9 {. |# H z( m* [+ B* A2 y0 P
pParentWnd->m_hWnd, (HMENU)nID, NULL);% B' N/ q8 r! X# T" G* Q& ^& S$ `
3. 设定选中的文字为链接显示2 ]2 A9 Z! ~5 m4 Y" i: e
CHARFORMAT2 cf2;
( F# B9 w/ ^7 u: ZZeroMemory(&cf2, sizeof(CHARFORMAT2));//
4 R( [! c: T( m( xcf2.cbSize = sizeof(CHARFORMAT2);5 `4 M6 n4 t s* G' H
cf2.dwMask = CFM_LINK;
# v( a5 E" j9 I' G1 Z" c3 Scf2.dwEffects |= CFE_LINK;2 d- v5 z6 ]# R
m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
' M3 V' N$ [' j# t5 r: J4.支持链接的点击响应7 m' H/ ^8 J& S+ h; `/ s% i6 f
m_cRichEdit.SetEventMask(ENM_LINK);* I/ w# p" k) R4 A& h- }
5.响应链接的点击EN_LINK
3 T7 M) _9 c4 Q* P$ o. |! ~+ T/ P& x; |" D" e, ?! m, S
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
! M1 u% o- f" s8 AON_NOTIFY_REFLECT(EN_LINK,OnURL)' W, w/ A7 E0 R. z, a# v
END_MESSAGE_MAP()
) T* _% H9 U% F% D' x) l$ ]% E......
0 S4 D( J8 J, E) l% z+ q Y( T) _- T" q2 s+ X1 T
void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
9 I0 M; f, Z* {$ M; I{4 U8 H9 E2 s, `; E3 @; X, C
TCHAR LinkChar[512]; [. s8 o8 ^* W* A4 x8 k7 G
ENLINK *pLink = (ENLINK *)pNmhdr;' n4 M+ B7 h, a% S( X
if (pLink->msg == WM_LBUTTONUP)
( W! M# m; A* H/ P{
/ K0 x- h# z# M7 I9 sSetSel(penLink->chrg);//这是链接的文字范围
: f; Q6 b: m: X. V+ i* olong Res = GetSelText((char *)LinkChar);//这是链接文字
7 V I& l# X3 P6 ~3 x //后面是你的处理过程4 Y1 Q& V0 J9 I" \6 T5 d( m3 a
....... i8 A. h$ J( x# c! E
}
% a, G$ F5 N2 a: k8 J$ B# y# Q% D}
! \+ N8 o1 w1 a2 F, v, W5 l- v U7 w& l- W7 {% V
b.插入位图) Y& J, }7 P8 y7 e+ C
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/, y- V' W! n7 g# U' g5 I
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
7 Q$ L" A6 f+ R$ M9 j6 t& ] @
+ q. c D% ^% M7 \5 z自定义在RichEdit中插入对象的图标2 c- F, u) }, w% G+ D
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html
" n' E) d" r$ M% m- F方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control7 v; L4 i: H9 q+ a9 h
只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
' p2 u* @( ?: b Y% ?/ C- O6 k4 Z9 K/ H! e# p
使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。, m6 H' y q2 a& m4 k
另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。 4 f, J- D2 v# U0 ?/ ~" n: }% _
! M1 l/ g3 x( m8 H
c.显示GIF动画
+ M) N* z% |% o+ \( D1 s) e常用的是通过qq的imageole.dll(也有用Gif89.dll的)
3 A) G" f- D0 h6 N; X k" Dhttp://www.xiaozhou.net/cooldog/blogview.asp?logID=828 |7 ?7 k3 c, ]. ]% s
http://www.codeproject.com/richedit/AnimatedEmoticon.asp) K+ Z! ~0 _: A+ x9 f4 G+ y
+ A: N8 o5 n6 D: M, D( N) t% @在richedit控件中插入动态GIF (Native C++版)
2 F) }# ]6 |& w/ p u4 A' i w& y, ihttp://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx
+ }/ [, I1 D& s" g
$ x. B% F1 ?# a: O" i1 Fd.IRichEditOleCallback的使用
6 |; z3 e6 k6 u1 Y6 r, I V% xhttp://61.186.252.131/Expert/topic/905/905844.xml?temp=.83790227 m" U# A$ F0 Y( {
, ]9 X) i$ ?2 Q: v' M# s$ u: _! O
类似 MSN 信息发送框的制作(上)& p2 s# U2 k- H u& s0 L, o! S U
http://www.vckbase.com/document/viewdoc/?id=1087
1 v( d5 K Y& |: [0 s5 n% m内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串
( ]0 V& X2 k2 v" s' [. P
* d: ]/ [5 M6 O# C. S- u. F( x自定义 CRichEditCtrl 控件 {2 E( c% [0 h3 X
http://www.vckbase.com/document/viewdoc/?id=3283 k$ Z9 l! S% @; V$ f( l- @3 k( L
内容包含:鼠标右键消息,消息映射,字体变换9 c2 n' S A6 e( G% G" N2 ^8 W
/ @+ T- W# i* k y. ?7 Q( ]7 K: e% v) PPS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母0 Q+ \# X6 k3 g/ Y! C* W: C/ w
是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778 * l* S5 x' f9 `- [0 i" V$ k
----------------------- ^) P" W0 ? P7 ]
比我想象中还要花时间,所以最后潦草了点,见谅 |
|