|
一.常见问题2 L' S) A9 a+ Q( _4 t( T$ @/ b+ d
a.可以编译,不能执行的
5 L1 M3 q6 T8 E' |/ J# \9 w' f# J/ \AfxInitRichEdit();
9 ?$ N) r$ {8 F
* l. g; X2 i/ m7 I# J5 p+ eb.升级默认的Riched版本(默认的有一些bug),如
) t8 M( D d: {% j- T( O可在InitInstance中添加6 f3 d' j* F/ ~) }2 z5 x2 a
LoadLibrary("RICHED20.DLL")
$ _2 u* Q' |$ I0 j$ h" \( G, o3 ^最后注意 FreeLibrary% w- `0 x% t5 r f
# I7 y9 F/ v- o- O, y/ N2 n3 U+ s
如果是CRichEditView基类的可用
- a& J0 m% I3 k5 RBOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)6 K {( G, ]& z
{
6 V8 M9 A- u9 l% W//装入rich edit version 2.0/ {% @. y! Y- x" Z
if (LoadLibraryA("RICHED20.DLL") == NULL)
: j. z" v" \& m# s) t: x, U{& a6 T( p1 Y( i+ e2 J
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
: n d: I, G5 ^# P# jPostMessage(WM_QUIT,0,0);
$ n- h3 T- c+ R7 oreturn FALSE;
. c/ c! ?. q9 z' F' x6 a6 L/ ~6 r}
, q' V1 z% p5 }2 ^' A
9 y9 H8 K- h+ B4 Dm_strClass = RICHEDIT_CLASSA;//for 2.0 class; h8 C% s) p5 U, N h) S
# j: E) y! W2 m+ @1 o2 e
return CRichEditView::PreCreateWindow(cs);, R8 d6 m- O& g
}
7 W' W# _5 s, Q" `
3 M" L2 |4 v% R" V7 N; z: Uc.最后追加行
% F, ^+ s3 q3 J! W9 K& @richeditctrl.SetSel(-1, -1);# M2 g4 ^# O# ]. i! q( m. i0 z! C8 S/ S
richeditctrl.ReplaceSel( (LPCTSTR)str );
6 I9 g" Z( e- j( Q) ^ P$ G' m! x: J% G' o: R4 b4 L
d.字数限制
7 ?- ^% N$ g" SCRichEditCtrl::LimitText(long nChars)+ G2 J+ l9 u5 N6 C6 G
9 q, E& w; y1 v; H* H. |
e.换行切换
! k8 Z% B/ ~' J+ M0 W7 ZCRichEditView的OnInitialUpdate()函数中加入下面两句:% p5 H. c; l: y2 G& I5 d
m_nWordWrap = WrapNone;& ?! I e ]: H, J8 h+ V0 S
WrapChanged();
0 t6 O1 y) }: m% lWrapChanged实际上也是调用; q, U9 I0 Q o: Y; X7 V
ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
2 m& F! _! N1 ^( f+ k Yctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow. t6 c4 C: C% o2 {3 y+ u
还有不常用的 m_nWordWrap == WrapToTargetDevice
: X& G. v$ N4 L5 Yctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
( P6 X) ~; b6 s8 A: W' d! G如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return8 s5 v/ c/ ~+ o- w V' O
4 Y9 [8 p+ q2 r4 r a3 w% B- w
f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
' A" G# t& T( [6 k6 b& t2 cpmyRichEditCtrl->PasteSpecial(CF_TEXT);
$ w% I) C$ q3 d. I& i9 T3 A) Q, n% }
g.随着输入随着自动滚动条滚动到最后一行+ j" \( C5 Z( P: ?+ H% O
int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();3 A6 C. C3 T! P- \$ O9 t# @
if (nFirstVisible > 0)
1 B+ P; ]# ]; d* h$ z* w. E! U{$ _1 h- _- @$ M2 V8 s$ j' Y# ?
pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);% Z/ k1 \- P2 I" w* }( X5 J
}9 Z3 E( a$ I( {3 K
或
% g/ M! m5 V$ a: T8 b% V& ~m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);+ U) a6 Y8 D# s# A5 N3 a8 p) g% I
6 c! B' O7 D! L, y. g* A) t
/ u% N1 [0 j3 X$ n9 H
h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)% O2 a) r) s7 F6 O
SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);; Y5 w; `5 s( v
TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
( a( B, Q! L+ e3 BSendMessage(EM_SETUNDOLIMIT,100,0);
. i( H$ W1 \1 Q) _+ j6 A! U
# W' z, P2 R+ }4 fi.响应OnChange
; v2 I( ~: G6 REM_SETEVENTMASK 设置 ENM_CHANGE 2 L. a U# w. S# y4 b0 Q- h
long lMask = GetEventMask();
- u, j7 L8 B# c& E% A$ d0 N' JlMask |= ENM_CHANGE;& w% t b/ H$ a7 Q
lMask &= ~ENM_PROTECTED;2 T8 `6 f8 _* h1 B! P: t
SetEventMask(lMask);
- I: r$ r" c) R& z1 q; o2 o- G; U! Y8 F P+ a2 C! ?
j.设置只读
, _( _% u/ N. n: _CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );3 q2 _# g F9 j* h. u( j. O
通过设置PROTECTED实现选中的文本只读,参见
' s7 y( G* Y5 l2 h8 m2 Ohttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
* l+ @1 g+ w% b8 `3 G
! \0 W$ E a( u# s7 u二.函数应用
& H) \6 E& [. |a.设置字体(主要是通过SetSelectionCharFormat)* M& ^9 W6 u- S4 {
CHARFORMAT cf;
" e4 J! k- m3 \. ~; @rich.GetSelectionCharFormat(cf);( v4 U7 U6 S" B, R3 Y d% N
cf.dwMask|=CFM_BOLD;- T+ ?$ g3 [/ O; ?
cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;+ q- a6 d8 ?0 @& g
cf.dwMask|=CFM_ITALIC;
' G! P4 Q. d% \8 U" x2 t5 l% ~( Zcf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;; f! J1 V/ [6 H5 p$ F4 q
cf.dwMask|=CFM_UNDERLINE;
4 X/ c8 b; X* P" m1 s0 lcf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE; J: J3 R: R8 o+ H" [, N1 V. W
cf.dwMask|=CFM_COLOR;$ G/ q' g! Z% F
cf.crTextColor = RGB(255,0,0);//设置颜色0 B- @1 d9 A2 t" {* d
cf.dwMask|=CFM_SIZE;$ T3 _$ W5 h) e
cf.yHeight =200;//设置高度) O; d: E. p4 M# O |( `5 g7 i
cf.dwMask|=CFM_FACE;
6 e6 S J% X4 vstrcpy(cf.szFaceName ,_T("隶书"));//设置字体
' ]' d: _2 E' c- o' }+ Qrich.SetSelectionCharFormat(cf);9 L3 L/ L) I' N ^4 \" M
, P1 D0 y% _) n
b.设置字体的行间距
% F" D0 k+ G1 {. O4 N3 x: k要用richedit2.0以上4 f% y4 k7 T$ `- C' i( \: ~
试试
$ X; Z9 b% b& h/ f9 KPARAFORMAT2 pf;& g" t! W2 g8 [6 Z! K1 S
pf.cbSize = sizeof(PARAFORMAT2);7 c7 a: b: m5 S, ]* O9 H
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;! o, F+ W+ T* L* ^. ]0 F) z" W9 X9 f
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
3 i( A6 E8 @) n0 ]0 D* ]1 v0 ?pf.dxOffset = 10;
" N+ Q% b& D$ q8 z/ sVERIFY(SetParaFormat(pf)); E( a- n( q2 n" X M
常用的dwMask有$ Z% k x2 M, R" M. u: n
PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
( Z- L) j+ B- N# w$ X3 f8 |' F2 使用阿拉伯数字 (1, 2, 3, ...). . X" Q% a5 X" G0 z( q. M
3 使用小写字母 (a, b, c, ...). ; h0 w, O9 N4 W% E1 u
4 使用大写字母 (A, B, C, ...). 6 L/ W1 B; L! @1 f6 I
5 使用小写罗马数字 (i, ii, iii, ...).
/ e5 X( N, L, d3 J Q7 y$ o6 使用大写罗马数字 (I, II, III, ...).
, i9 H( s: S$ F: k7 自定义,字符见成员 wNumberingStart. * |: W# c) L" ]' r' e7 G
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips, M2 u+ W3 t; [& B, r
PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进. b0 t: [3 p% T- b
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
' e1 M+ g9 `( `% ~PFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
& D" Z5 w( q6 o' t$ C+ B; s9 t4 S0 J" _( n+ W' \
c.设置CRichEditCtrl(2.0)背景透明
: @+ _& U% {, p; ^long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
* H' x2 n6 x& N& e. v4 @style &= WS_EX_TRANSPARENT;
% ^; ]2 e" c# D1 h8 I% m+ }::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
* f# p3 h2 K, Q% O& A0 Y或 CreateEx,然后把WS_EX_TRANSPARENT样式加上' x% d% ^6 v; J
; z$ {* L2 G- m3 n; `( }2 S
e.得到内容有三种
, ? s+ \; v3 w- i$ `; S" W9 o1)GetWindowText
* Z+ y9 [/ n, d$ u. I2)使用EM_GETTEXTEX
8 S" e: w4 J$ z8 [* v8 W+ ]+ \GETTEXTEX gt;
+ V8 C2 q- x: a! ^6 H! Lgt.cb = 200;
6 E, H0 ]# N9 n: {# s9 |9 [& Kgt.flags = GT_DEFAULT;1 D8 l4 L4 D* o) a. a- A9 p, w
gt.codepage = CP_ACP ;
! ^/ w5 Z5 I1 ?% G0 egt.lpDefaultChar = NULL;
) c+ R" w6 A) ]6 S% bgt.lpUsedDefChar = NULL;
3 s/ p3 `3 R7 VSendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);2 a4 f7 h" F4 M8 M. T
3)StreamOut(主要用于RTF等格式输出)- P1 t8 {9 F- @0 Q* G& c* K
static DWORD CALLBACK # D( A6 `6 F: J, K( l" L/ k- ]
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
, v N/ }% b6 B0 L5 T) H{
7 d7 [% x; J) G CFile* pFile = (CFile*) dwCookie;/ v p# A& h/ |( E k' i$ _
1 R$ M+ C4 J/ e, C6 f pFile->Write(pbBuff, cb);& K. Z- @9 i$ \7 _0 q% Y. f3 _' t! y
*pcb = cb; V: M2 i5 Q: T+ Z
0 G' k" T4 w! Z6 U* @9 u return 0;
5 W. |/ t; [8 S, O7 u0 _}: K F" y. i) E- w, w# _5 B
8 t1 {# B) b! }7 u5 O
1 D+ ^' j: ~& b, V( f
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
$ |4 p" v I" x& x- i EDITSTREAM es;, I) n/ J/ N1 [/ R) N, p- m) ^
es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用
+ A$ L( Z4 ?+ U% V4 T- G4 x- c# ] es.pfnCallback = MyStreamOutCallback;
! m7 ^+ U8 B3 e; n pmyRichEditCtrl->StreamOut(SF_RTF, es);* B" ~7 J( |& z2 |9 A7 }1 \
读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
9 R% |$ K8 }5 J* f: H2 ]- t( F( W6 A( H
f.查找字符串
5 S( e8 }5 e }* |5 gFINDTEXTEX ft;
: z' C3 k _6 p- U- u/ Uft.chrg.cpMin = 0;$ y( ? ?3 k, w2 ?/ c9 U
ft.chrg.cpMax = -1;
- K8 V: R( U# ^; [" R3 w- q2 b! ?( Jft.lpstrText = "|";
& K# z! i9 C9 R. s: `long lPos = FindText(0, &ft);) }* I6 Y+ E3 x# M/ [
1 ]0 ^/ f }: _) s$ t0 X' v; h5 C
如果要继续查找,修改cpMin,如 S0 i1 v3 O3 Z5 s
int nCount = 0;
, U, l( B- C: ydo+ k& q* l* ]- Q* X
{% p! R3 Z4 a- @4 R
long lPos = GetRichEditCtrl().FindText(0, &ft);8 e& K# Y* y: {" n7 b5 |$ A
if( -1 == lPos) break;
, v3 j( M$ a% ^6 a/ ^( I ft.chrg.cpMin = lPos + strlen(ft.lpstrText);9 d+ V' J) r. e A8 G# ]' J
++nCount;
+ O; M, c' E# }& T; P% Z9 K6 `}while(TRUE);
3 U, @. W* w! G( _& ^1 d( t$ L! G4 A& b& Q. d1 q3 \* Q
g.以Html格式保存
" ~: |0 n& i5 H8 J+ t8 q目前做法可先转为RTF格式,再通过RTF-to-HTML Converter, ~( D% i% W8 e& k" m
http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
& S1 L+ x+ T* }5 p6 r
~+ ~5 V0 ^: mh.重载OnProtected函数得到对应的消息,如粘贴等* f2 x* O$ a; O: j1 j3 z
void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
; e: T% L. ]+ I; S: ]; Z4 I1 n{
2 X. N9 f( |6 x ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;% V+ M# `3 r8 {8 J5 Z
' c% @: ?3 @+ J( M: A! V; X switch (pEP->msg) {
& P; q# N" N8 [0 R: V% u6 L case WM_KEYDOWN://按键,判断pEP->wParam
* U D B- T8 B3 W9 I case WM_PASTE://粘贴
+ y& o5 t; N$ a2 v' D9 D case WM_CUT://剪切
( p+ O" @2 M( j) T case EM_SETCHARFORMAT:/ D7 D q j# V& m" @# w+ Q# ?
default:+ s& r7 o n* A) C7 H
break;" X0 Z) p2 f. n) t3 r
};9 \7 j5 F$ {' i4 _2 c5 J
& S( s4 E9 y; s A2 j) F$ }# j0 r
*pResult = FALSE;: u, k9 V: ~& u
}* w/ O* Z; {* V/ Y
7 g. b$ l S# e: _ p+ b+ C2 x
三.聊天常用
4 r2 |. Z2 ] }* v4 Pa.LINK 链接功能! O+ k. {7 B3 Y0 h7 m) K
1. LoadLibrary(_T("Riched20.dll"));- L: L2 N4 {3 d! k9 p$ I
2. 创建RichEdit2.0控件! ~6 a) B6 U1 C2 Y m3 o! f
CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP9 o6 A) K9 q. I* O1 Y
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
2 B: _. _$ T ^0 t" j* | rect.left, rect.top, cx, cy,; q4 L2 q- }4 W+ p
pParentWnd->m_hWnd, (HMENU)nID, NULL);
$ S- f' u6 i( W8 X1 G1 p3 @3. 设定选中的文字为链接显示/ W0 b, T: H. R
CHARFORMAT2 cf2;, B0 q$ p6 E3 i. \; Y8 L* v( O
ZeroMemory(&cf2, sizeof(CHARFORMAT2));//# M' w- h( l2 [. @
cf2.cbSize = sizeof(CHARFORMAT2);: W# b/ t' S5 {5 L; R+ S; }" f
cf2.dwMask = CFM_LINK;
& J6 ^) S% ], ^7 X8 @* U4 Ucf2.dwEffects |= CFE_LINK;
% |& ~- ^( F9 s' w# [1 n% rm_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
1 n, `4 I, j3 S7 E. a; K4.支持链接的点击响应
: J! k( `6 B% q, d1 C @2 s! Xm_cRichEdit.SetEventMask(ENM_LINK);% ]' J/ y0 a6 u, Q4 p* J% y
5.响应链接的点击EN_LINK0 q$ x( Y9 k* m/ ]% j
8 P% o& [& i7 e: d) f# iBEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
7 q3 n6 @5 H- L: `& I& k6 PON_NOTIFY_REFLECT(EN_LINK,OnURL)
6 e2 o) N9 L9 }7 H4 tEND_MESSAGE_MAP()
2 T1 K% u9 `& _: E......
% j6 I+ P0 D1 H L4 u
) z7 K0 L: v2 cvoid CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)3 w* y5 w' `. T! J% ^% ?
{% v1 S- B0 C$ V
TCHAR LinkChar[512];
0 [3 M4 @% ^& Y j: Z3 h+ cENLINK *pLink = (ENLINK *)pNmhdr;
( T. [; K0 N$ N" V& W$ b9 Yif (pLink->msg == WM_LBUTTONUP)
) \& F/ H7 _9 |* Z{
& N+ Z% T f gSetSel(penLink->chrg);//这是链接的文字范围
$ r* _8 H( A9 ~3 K. F8 U, Z1 {long Res = GetSelText((char *)LinkChar);//这是链接文字& [3 l! P* K# O. g0 B2 Y# h
//后面是你的处理过程
! R/ W& ~% s& y/ i7 X. H U ......
# E$ ?9 f! T0 q! k/ M5 `+ u1 }& u }
8 h& R: p, w C" w% [}
; j/ H/ \1 s; w1 f2 h8 a: f
, A+ C: b% u( o1 [b.插入位图
# P& J& z7 ]6 ^" A$ t4 Y+ whttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/: u8 I2 L( P: c6 Y/ y
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/! X" t( I4 k; ?& Y; }5 L- g( [
5 e" J, G% b! R3 ~- u( T! z0 o4 S
自定义在RichEdit中插入对象的图标
' A+ M( v) a. Q4 z" p) B4 ^9 e! rhttp://www.blogcn.com/user3/jiangsheng/blog/1319738.html: p8 O) v: z: p4 `' a D
方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
; O1 \7 ?2 M) i. X& J只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
6 s0 M; P# H$ C6 D' r5 F# g1 g/ G+ q: q5 h7 M7 ]
使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
( I1 W4 ~1 {4 _# G1 W另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
& X! o6 ]+ u4 w+ B4 N
; C2 d! B0 r8 A* U4 b$ }c.显示GIF动画( Q. A; e: X, {/ {( I
常用的是通过qq的imageole.dll(也有用Gif89.dll的)8 n% Q6 p4 Z$ T8 Z( z4 p5 m
http://www.xiaozhou.net/cooldog/blogview.asp?logID=828 m$ M5 a! \) @& G
http://www.codeproject.com/richedit/AnimatedEmoticon.asp
8 J1 k* t! q: H3 S0 W3 S4 H. x0 A" z: q+ q
在richedit控件中插入动态GIF (Native C++版)
/ m3 `* z3 r7 y3 @1 W/ h8 D3 Shttp://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx0 F& s L0 `9 A; [5 a3 Z
( O; _2 ~& z( m Q8 c* M% N% k( U
d.IRichEditOleCallback的使用9 i6 D# M+ K8 {: |) f5 J
http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022
6 G+ r8 F5 ?5 D9 \" Z4 Z+ l* R: Q
类似 MSN 信息发送框的制作(上)
& o/ u% U' h: r8 @http://www.vckbase.com/document/viewdoc/?id=1087& `$ r& s7 j0 K- C
内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串* B( Z, [' _2 O( R! a6 Z; B! K
1 I; E. B; V$ u V8 ]- w, S# Z7 l
自定义 CRichEditCtrl 控件: @* G0 ~" ~0 u/ F- q
http://www.vckbase.com/document/viewdoc/?id=328; B7 l: }6 r9 F
内容包含:鼠标右键消息,消息映射,字体变换( g6 m' {# J( N5 \8 z* u
) {) \) J7 y2 f+ T! G' APS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
Y% U. z% h1 {* k" I, `4 a# e是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778
, k# N/ |" [6 m+ \; c. x. J----------------------+ W p; D2 h; N" j
比我想象中还要花时间,所以最后潦草了点,见谅 |
|