|
|
一.常见问题* _: u" g# h; [! ^
a.可以编译,不能执行的
5 K( D7 B5 ? Z/ I) iAfxInitRichEdit();
2 S* W! Q" l+ w' X# L, t: D/ O4 f5 X/ T+ c f# `1 j/ _& O
b.升级默认的Riched版本(默认的有一些bug),如
+ H% ?+ N3 g9 M8 Z/ p可在InitInstance中添加, f5 w/ ]; f- }3 S
LoadLibrary("RICHED20.DLL") 4 s" H p1 d* x3 F* \( S/ Q
最后注意 FreeLibrary
& x- o$ N# d7 { G) P% D4 I: G8 L
如果是CRichEditView基类的可用( d+ D' U# M' o$ q- E) b
BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
/ {& t' _3 Q6 r" W4 Q+ s) K* ~3 v{7 C' ^# t8 X. a1 _, y, Q
//装入rich edit version 2.0+ X1 o d9 K' R3 o/ b5 U' V
if (LoadLibraryA("RICHED20.DLL") == NULL)( {7 ~$ Z/ a' M( A* R& e" h' z1 L
{2 j0 |& z5 z0 z2 m; }: F
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
/ B( W3 u4 O! L; rPostMessage(WM_QUIT,0,0);' h$ ?$ K- m+ l( k. Z" \
return FALSE;* O% ?: }/ A; }! X# ?3 e% L
}
9 L+ J' R, E+ X) S4 s$ ~
( T# `# E$ {3 X3 I2 i# L( Y0 Vm_strClass = RICHEDIT_CLASSA;//for 2.0 class
; E8 b8 _; N, v8 W/ |! k& c
2 L; s9 B5 _. F, X( X2 R7 rreturn CRichEditView::PreCreateWindow(cs);6 K# Y5 U+ K0 @
}
" X1 _2 ?8 Q5 h9 K8 r: x! ^% b+ q3 g0 @5 C8 {
c.最后追加行4 }( N( F) H% W0 ~7 B q
richeditctrl.SetSel(-1, -1);4 J% S) t+ R4 }- h. H7 } l& P
richeditctrl.ReplaceSel( (LPCTSTR)str );. j4 z' R+ `+ l
) H# k' A8 d& t! I" M8 S+ L+ q4 gd.字数限制
! N7 P/ I8 {! ECRichEditCtrl::LimitText(long nChars)
; S' [9 W: d( M ?7 o# w+ E
g, w; x" @" N* {e.换行切换
( @3 K# C9 X- q+ ]2 pCRichEditView的OnInitialUpdate()函数中加入下面两句:
& ~& n$ @8 @4 x0 Z8 ^5 U) _: W- Am_nWordWrap = WrapNone;
) m3 W! J" M k yWrapChanged(); 2 i8 q. w! g8 R3 |5 N% D
WrapChanged实际上也是调用
0 ^, e! f6 v9 t6 Q# T/ `: C) Z) z5 z/ sctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
( b* \3 A, @% _1 zctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
$ |6 I% a! T3 P5 x2 }) [" s还有不常用的 m_nWordWrap == WrapToTargetDevice' K1 Y) h7 o" V$ `- Z
ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());* d3 [* ]8 [% M8 T
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return
% j4 `. o* }4 e6 X r% h, x5 X9 V" z( X- h0 g
f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
+ p' r; @2 J% k- v9 J; vpmyRichEditCtrl->PasteSpecial(CF_TEXT);( H- t1 q$ b* ~
i- J7 W% F# i# I3 U1 _
g.随着输入随着自动滚动条滚动到最后一行
# L- W" f* {* q5 S9 M& Fint nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
* ^& Y& O: H* Qif (nFirstVisible > 0)0 Y! ]2 }! ? a, a% _1 r
{
4 [8 d8 v" U0 R e1 C pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
! X* r2 u7 V0 X% {3 ]. E! K}* T9 X) a4 Q$ W6 l
或. p/ b8 M/ A/ f* g
m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);; U/ y2 y' o% f" U" B# G
) s% u- X+ k) B8 b6 n
% V( \- s: [8 S" y' s8 xh.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
: o8 a0 b! f D7 c A7 E7 ?# {SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
6 o# @( ]# B0 ]6 C" wTM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数 $ U; k; }! a# v5 J
SendMessage(EM_SETUNDOLIMIT,100,0); ?; f, e K/ n& c1 K* g
- v+ o+ D" m; v) D# pi.响应OnChange
& E1 R. [( E( ~4 EEM_SETEVENTMASK 设置 ENM_CHANGE 6 [: U* o' B& G% J
long lMask = GetEventMask();
+ W4 V# [6 o% G9 Z8 Q c6 S! F; ~lMask |= ENM_CHANGE;$ ?3 k: S' X8 b* |9 |3 f6 T) [
lMask &= ~ENM_PROTECTED;1 e3 m4 [( D1 ]% c# [
SetEventMask(lMask);1 d# F- y) `2 D+ O* x/ k
8 o8 C; I) U; Q" K }
j.设置只读
7 ~8 _& y1 E3 C6 vCRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );: c9 M9 ^. J- G$ _, F
通过设置PROTECTED实现选中的文本只读,参见6 t$ W- X! p P7 N% N- e l4 d
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
; P0 }0 i* E# x- X. Q3 y- U& V' Q' x, |
2 Y3 b% W* H6 z" H; G! W. r二.函数应用
( e- K7 A: V" B5 Va.设置字体(主要是通过SetSelectionCharFormat)+ g! h9 J" a) {1 Q" ]/ `
CHARFORMAT cf;7 G: Q% g( W* `0 J8 Y
rich.GetSelectionCharFormat(cf);! x. s9 e& R# y
cf.dwMask|=CFM_BOLD;
- h3 K. m+ A' e" l' Hcf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
# ^& A2 U3 x; ^cf.dwMask|=CFM_ITALIC;4 s0 h0 H a T* H6 E, I
cf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
+ R& a7 l9 [. c; Bcf.dwMask|=CFM_UNDERLINE;7 [2 e( j# N' l9 @! \& z
cf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;- g( I4 q) Q, s, j& E, \
cf.dwMask|=CFM_COLOR;; A9 I" F$ r/ {1 T7 l' n" J
cf.crTextColor = RGB(255,0,0);//设置颜色3 S0 q$ @. s* o. f
cf.dwMask|=CFM_SIZE;; b. a- f! ]4 X+ I6 ~1 O# V
cf.yHeight =200;//设置高度) C- } g+ f8 o+ I- ]+ {1 ~; u
cf.dwMask|=CFM_FACE;
( C, ^7 c0 y# l, E G9 |strcpy(cf.szFaceName ,_T("隶书"));//设置字体# f4 U3 U* G9 m* x" \% K
rich.SetSelectionCharFormat(cf);& m1 s ]5 \5 _3 k
" J2 ?: t3 H& N' z" \b.设置字体的行间距) u6 w+ W, m! Q7 Q( D- P4 ]
要用richedit2.0以上3 C0 }9 P. W/ x& w* N% g+ Z
试试- ^/ \; @- w8 o# T
PARAFORMAT2 pf;
* @2 `+ o7 I3 t) @2 Wpf.cbSize = sizeof(PARAFORMAT2);. C1 M) W; B/ X' D4 e4 V
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
3 Z. |+ [% ?$ ^2 M3 b+ G9 O3 J4 N5 @pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
/ \, ]5 N6 Z2 R: kpf.dxOffset = 10;
4 d) t1 o$ Y! Q6 CVERIFY(SetParaFormat(pf)); 2 b5 Q2 \. |, R1 v2 T. |% V& q
常用的dwMask有
6 m- \! ^4 m! h @PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET5 y' X! R/ G" }3 m) G, _3 x+ Q1 h
2 使用阿拉伯数字 (1, 2, 3, ...).
% q2 U2 I7 {. B" K7 W$ r6 Y) `3 使用小写字母 (a, b, c, ...).
! _+ d& `- X) v. S* V. A7 u4 使用大写字母 (A, B, C, ...). $ `$ Q1 e/ z! c
5 使用小写罗马数字 (i, ii, iii, ...).
0 x' n% G. F# R- x6 使用大写罗马数字 (I, II, III, ...).
' m/ t. C3 J/ j( G3 u4 r H. z7 自定义,字符见成员 wNumberingStart. & |5 J9 R, t( u1 O
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips# B8 P: @9 \) B" S
PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进6 p6 r" t) }4 ^+ Q9 m: h) K
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
( O+ t. z" s0 Z+ z% vPFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距. V* g8 }, }; d' t
- l* x5 S( U6 r& ], ac.设置CRichEditCtrl(2.0)背景透明
1 R" G1 A) v8 c( x: Blong style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
! I( _1 F: c6 l* C! Zstyle &= WS_EX_TRANSPARENT;
& H4 ~2 F Z9 ~& Z% k::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
* y; k- x3 @) m7 i5 D$ o" }或 CreateEx,然后把WS_EX_TRANSPARENT样式加上( G" J9 n4 f8 F; z) X1 Q
( ?1 F2 L7 |+ R5 {1 Z; n* E( ?+ m# D" i
e.得到内容有三种
% k8 }. C! h- n) m! ` ]1)GetWindowText3 P, ^* L! ~* M: F0 P! C
2)使用EM_GETTEXTEX
8 U$ M+ U! P: L' p0 w( fGETTEXTEX gt;. Y7 v# `3 o6 k9 E$ D# ~# b( y
gt.cb = 200;
( L$ i7 `( w0 O, O) Dgt.flags = GT_DEFAULT;0 F5 {' Q& l' U7 g/ q# | V
gt.codepage = CP_ACP ;
* ?3 u% H# w! v) p7 G* i i4 Dgt.lpDefaultChar = NULL;
7 O1 H% r, T0 agt.lpUsedDefChar = NULL;
2 n& P( @4 [) ^+ D1 MSendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);0 Z) x$ ]$ i8 c. V+ r" |4 G4 x5 Q8 ^
3)StreamOut(主要用于RTF等格式输出)
; v9 W4 ?5 Q) b6 T; kstatic DWORD CALLBACK
4 c9 F* p6 C# r( ?7 s# k& T+ o0 ^; qMyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)* e6 O$ x4 p7 r x9 p( n
{
6 z$ t/ k! N# y. e0 e( R% a CFile* pFile = (CFile*) dwCookie;5 Z3 e, G3 k, k; k/ P+ i8 V2 i
u) X+ @$ W5 l9 p/ R- C9 s pFile->Write(pbBuff, cb);6 o* }) g) w) m0 Z( S* t
*pcb = cb;
- R( u3 f. r% e9 X% V: ^
7 w/ u4 H/ R. C return 0;( s$ p$ c% A2 o. N) m# d0 \, q
}
0 S, O% x* u) Y! O) @
, K; r1 _) F2 g0 n# L) k5 t9 x9 I
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);' i/ w5 _6 Y# ~- Z3 G
EDITSTREAM es;) O- |) B( u0 c* G: A+ g* K
es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用
6 n+ q1 W8 C9 O es.pfnCallback = MyStreamOutCallback;
( W- Y7 [' ?7 x; m* i* {5 T1 {6 x pmyRichEditCtrl->StreamOut(SF_RTF, es);1 {( ]3 t6 S/ u4 s5 v$ W
读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn+ l; o# ?. G+ C* s% Y
' Z- i7 N6 ?4 t- l! l' v0 X& vf.查找字符串1 D q/ Y0 S9 o7 Q$ d# U- M+ A- N: H
FINDTEXTEX ft;
" L' [) ^1 g7 `1 h0 u. Oft.chrg.cpMin = 0;
1 Y% s) h9 h Vft.chrg.cpMax = -1;2 C' S: |& v9 Q! o0 H. i: m
ft.lpstrText = "|";/ Z$ D! B' j# V9 u7 t: J
long lPos = FindText(0, &ft);1 a5 u8 ?4 h7 G6 N" r
5 L6 K! b0 Q; |, J
如果要继续查找,修改cpMin,如% I( `6 o% Q4 y: c- K
int nCount = 0;
h+ G( V( p" K1 b3 c6 Fdo D* U$ Y3 m. Q H7 S4 Q" z
{# @# Y8 K# k' R5 O# p
long lPos = GetRichEditCtrl().FindText(0, &ft);
- Y) b& i, U/ |. m) O if( -1 == lPos) break;
( l9 |% U1 u6 P# Q ft.chrg.cpMin = lPos + strlen(ft.lpstrText);1 a% B6 T3 Q3 V- N* j+ N# Y
++nCount;
# U6 |' @" I& N. x}while(TRUE);0 L& l: k& u; V8 [. s
5 _- W& c9 {3 R
g.以Html格式保存9 ]5 l, b0 g( N3 {* H. m
目前做法可先转为RTF格式,再通过RTF-to-HTML Converter9 g- n" W5 Z2 w, N$ K/ e
http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/( H4 V* k3 E! S$ A, g$ B
2 ~; a! N% }9 Y' y& e: i
h.重载OnProtected函数得到对应的消息,如粘贴等2 L X$ ]& ?0 d, t' q
void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)3 g4 I# P/ ]- J2 z( c5 W4 E
{: `$ ~$ x5 V/ x5 D
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;: f9 P& W ~. b# Y9 Z
7 u' U; F1 K1 g% s
switch (pEP->msg) {+ g. F" e* q6 h/ m# t
case WM_KEYDOWN://按键,判断pEP->wParam9 }0 O# P8 K7 V# A( o
case WM_PASTE://粘贴' r) h, \7 N# _4 c9 \ V* r2 q
case WM_CUT://剪切# T- q! X; }" K7 r; R1 P
case EM_SETCHARFORMAT:
1 ?' Y5 q* i7 D" q0 }3 P! R default:8 |, d; L& d* j% `! e2 z* K+ n
break;
; f5 B5 S, y! ? r };8 |: @% N. Q% B% Z( y0 y
( z: |4 g- V c& H *pResult = FALSE;
& G$ M5 `& ^. { ^5 z/ X}
0 M( H( l! {) |- P! O. M% A3 u
三.聊天常用
9 R) U; J5 J7 r [, z6 u4 _* ka.LINK 链接功能
~6 \: _* }# N' v* e. d% w5 i6 f; D1. LoadLibrary(_T("Riched20.dll"));
" }" ^! j$ q' H+ |2 l- l2. 创建RichEdit2.0控件% v' p1 P1 P, r: a1 |/ k3 k; R+ v
CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP3 p) F# U } @
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,! i1 @8 ~; r0 v: @0 ^3 @. r; O) D
rect.left, rect.top, cx, cy,! E$ M* g7 v8 L0 A
pParentWnd->m_hWnd, (HMENU)nID, NULL);: }+ ^4 A4 r4 W7 o. E1 X Q
3. 设定选中的文字为链接显示$ a& l+ S N* r2 S: y3 h6 R! e
CHARFORMAT2 cf2;
; I# o y9 Z6 C, s5 x) bZeroMemory(&cf2, sizeof(CHARFORMAT2));//# R- j4 W$ ? }. t% B
cf2.cbSize = sizeof(CHARFORMAT2);/ |' H$ a* q9 |
cf2.dwMask = CFM_LINK;
+ ^, p, u+ ?9 _0 e- dcf2.dwEffects |= CFE_LINK;/ U. j3 t# S& E, R, O d1 y
m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
6 c$ H. a- @" b9 L2 h4.支持链接的点击响应
9 y0 T) t4 y* u% v& h" |: hm_cRichEdit.SetEventMask(ENM_LINK);: W- h) c! \8 @' {9 `
5.响应链接的点击EN_LINK
) i. C7 r0 q V+ O+ N& \5 S! X8 ?& \8 Y! U) o; [
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
( B$ p d$ Q g n K1 yON_NOTIFY_REFLECT(EN_LINK,OnURL)0 E# a7 R: o* Z' J8 t4 v" ]
END_MESSAGE_MAP()
6 Q+ P* g" V' w* b) e7 h/ k+ r' Z......1 \/ C4 a. e1 O+ U
% b3 S D! T& ?void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
! N) ^# m& w) b) ?1 ` w7 o9 r{
" O( F2 i/ ]( m* A1 XTCHAR LinkChar[512];. y1 U3 T/ f9 R a9 ?1 N
ENLINK *pLink = (ENLINK *)pNmhdr;
! ?, O) @7 q8 Hif (pLink->msg == WM_LBUTTONUP)
, a. f) O8 P7 E; }1 O1 V2 g6 ]3 }{
4 q$ E( C7 s& v# vSetSel(penLink->chrg);//这是链接的文字范围/ t: N, g2 X( J- Z/ X9 X% L. j
long Res = GetSelText((char *)LinkChar);//这是链接文字- @" n) Q' n1 u
//后面是你的处理过程
3 W: V2 q }6 K. o$ A4 Q ......
3 U7 Z8 |; F8 d" K9 j1 Q }
7 C3 Y& e; n$ w- h- S: R}1 V7 u& X x% d) U* z+ M
( A# d& Z+ _/ `0 I1 G
b.插入位图) g1 G9 @- L4 |& @7 ~
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
7 | \& E# R2 K) D2 jhttp://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/3 T( Z4 R* B* N3 |" o' A; j' @5 A
: P" _( e4 E: ~5 j% J1 z) Y
自定义在RichEdit中插入对象的图标3 ], H( z$ U7 P: _ ]$ L" C; n
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html
, D4 o7 ]9 Q( t8 f$ L, u# P方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
8 n- N; P* i8 ]! y4 N. @4 Q只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
" f4 ]8 U/ s0 L7 q) h
- w- f5 O" g: V" k" D S! b9 |使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
9 ~/ u/ V+ h6 L; Z7 a, T0 U' A. ?另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
3 d6 k# t3 v3 r, m6 D% k1 Y
% W: |& L% G# `8 ]c.显示GIF动画
! A! O$ O! @4 b$ Z$ K8 o8 p+ ]常用的是通过qq的imageole.dll(也有用Gif89.dll的)- w7 A1 x3 A! `9 V& |1 [. a
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82, r" |$ K E- N. H8 T; A
http://www.codeproject.com/richedit/AnimatedEmoticon.asp
% R# E a8 }# M5 Y$ C! m5 d X# d. F' F" U9 [3 i2 s# \
在richedit控件中插入动态GIF (Native C++版), M" \) ^$ x, e" g/ [1 H
http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx ~. B- B) I" H! `" _: `
9 Y- [6 u6 K, r& E% J) _
d.IRichEditOleCallback的使用
! p0 X w! H% O$ O9 M/ X0 ihttp://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022) i6 ?, c6 \+ \/ y" N1 D: a
: `+ y. H, p+ N5 X8 {* C
类似 MSN 信息发送框的制作(上)
% y' Y3 y/ F; U& S4 W6 X; ?6 Xhttp://www.vckbase.com/document/viewdoc/?id=1087' R" G) Y2 \5 q
内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串0 d! S/ x) K) B8 i/ F8 c8 z/ Z! k
0 c: ?( n9 _% |, K8 [5 P" m2 H自定义 CRichEditCtrl 控件
- q% S9 c. q2 |$ {" {3 ]1 Fhttp://www.vckbase.com/document/viewdoc/?id=328
8 g7 _. c9 e5 N5 Y* s内容包含:鼠标右键消息,消息映射,字体变换6 e a8 M/ U: t4 K1 Y% r' m
: z6 t4 `' r0 t7 WPS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
! |& Z6 `9 z! o3 l9 p是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778
6 i9 ]' Q6 E2 b----------------------
: ^ U( A+ _! f; w比我想象中还要花时间,所以最后潦草了点,见谅 |
|