|
|
一.常见问题
( H: \* G% l% W* ^1 wa.可以编译,不能执行的
0 I$ c8 n4 i: r: V) n ~& x h2 e8 oAfxInitRichEdit();
4 G# ~/ P4 m4 d/ s6 v: _+ p7 Y/ p" h: l& H1 j+ k
b.升级默认的Riched版本(默认的有一些bug),如/ z$ ^( n' Z; |
可在InitInstance中添加* [* t. a* i0 U8 H
LoadLibrary("RICHED20.DLL") 1 L! g2 |, o* {$ f. T+ I, W
最后注意 FreeLibrary. ^- K8 a; I) O0 p
2 ^" T3 V# i! J' w& D
如果是CRichEditView基类的可用
& N) ?: p4 X A1 ]7 ]% yBOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)9 @$ d, n; Y" _* ^- S
{4 D0 k& @# p9 N. ?9 a7 h7 L
//装入rich edit version 2.0+ X, Y' o& _" `9 H) N) [
if (LoadLibraryA("RICHED20.DLL") == NULL). o1 l( ?4 r' Z1 @
{
( t: g" G" ?& U% {& _- Y# vAfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
) g* w k/ } M7 z( ~, T8 BPostMessage(WM_QUIT,0,0);1 m2 v4 z' }) g- W+ J( b4 t# X
return FALSE;/ J2 g' F4 \' y# V
}
2 x* K* r) V- H! i* d# v& u! j" G, F* ?& Z
m_strClass = RICHEDIT_CLASSA;//for 2.0 class
. i+ ]9 t0 F3 ^! U6 \% d- l! S
2 k! g& I' ]5 d9 Areturn CRichEditView::PreCreateWindow(cs);
8 }8 F4 w: ^4 H+ {" Y}
- p! J, h- [9 X6 S& {/ B: x
- E" [$ |7 m' S- y1 N/ i5 Ec.最后追加行6 [6 N: X6 ~' G) ]3 e- f
richeditctrl.SetSel(-1, -1);
: N1 M% x% G) t! J4 iricheditctrl.ReplaceSel( (LPCTSTR)str );
. S) F9 h. }9 C; p+ ^7 N& |
% S4 I2 O, M1 p* ^/ ~2 o+ ?1 I$ }d.字数限制
9 O0 H. L: ]" X; n/ y5 [CRichEditCtrl::LimitText(long nChars)
/ r3 N/ Z- r/ G7 M( D2 _3 d
$ V7 `, r4 o1 m5 j9 r+ n' u' D, Qe.换行切换
1 I5 f, ?( [4 [9 l: i- XCRichEditView的OnInitialUpdate()函数中加入下面两句:6 S) e6 R8 [) L( ~7 x* x
m_nWordWrap = WrapNone;& `7 E1 P! {- X/ K
WrapChanged();
" J/ `( u2 U: V$ MWrapChanged实际上也是调用
( g( {! V* N* z3 {" ^( Lctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone$ b# D- m( Y% p5 M: `; w( u
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
q) c( { |. O3 [" G" H0 O W还有不常用的 m_nWordWrap == WrapToTargetDevice
) X1 ]0 p4 ?1 W0 _ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());+ P/ v+ e8 }0 H. Q
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return
: P( l: l, W) ^( b1 H+ o# N" d0 P' z% f+ C. N& Q$ b
f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴, _5 `$ y; F1 _' h% ]
pmyRichEditCtrl->PasteSpecial(CF_TEXT);8 B! B A, [3 G1 l. `
+ e# ?) y# a9 z' }/ \) lg.随着输入随着自动滚动条滚动到最后一行
2 \/ e, b# a- p: j& Z' _" dint nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();2 j$ v( s% b2 j4 R5 I' E, q5 g8 A1 w
if (nFirstVisible > 0)
! b9 u. ?5 I9 C1 u* }8 v{0 W" X0 O. Z0 `1 A( f
pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);# R# {# q' M. p/ j ~ k. M
}
v0 A; r0 L! m$ P0 S或
" y! r# [# E2 x; E6 R5 I G" sm_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);7 B5 Z) e# ^! E
6 C: Z _- H2 N( U) a q
; N/ y: _3 B) F6 mh.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)7 D* ]' |% p4 I8 _# c4 z1 z' _
SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);; j4 u) n0 T4 q: R+ b* p" W
TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
9 s- r; |# j, H3 }) q. ]SendMessage(EM_SETUNDOLIMIT,100,0);
6 ?* ^ a7 f: e" y
0 W6 W L2 |) Si.响应OnChange8 Z5 h" h# \% y% r/ M& n
EM_SETEVENTMASK 设置 ENM_CHANGE # j3 ^" R# @7 j# ~# {" R3 m$ b
long lMask = GetEventMask();
: Z" J7 B F- l. w: n% _' Z8 m3 VlMask |= ENM_CHANGE;2 w4 P1 N! w3 R( Y8 L8 a2 s4 V
lMask &= ~ENM_PROTECTED;
% N' l( U$ g4 GSetEventMask(lMask);# O& J x4 `) n
1 P0 n. R6 a" g; N* p" Ij.设置只读
" y* h+ z8 D! v6 WCRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );
3 h6 ^8 o7 ^( ?4 q9 s通过设置PROTECTED实现选中的文本只读,参见/ L, `1 N# G1 O/ a0 }' r9 K
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
& k& t( B5 {, c3 P+ h6 J1 n& \5 X5 `& ~& G
二.函数应用: k6 n' T; n, r
a.设置字体(主要是通过SetSelectionCharFormat)
( d# B, b9 \3 e1 ACHARFORMAT cf;1 T2 M V6 \( {! ]* W+ s
rich.GetSelectionCharFormat(cf); J O6 [) ]& b, j/ |. r0 a" z. s) H7 ~
cf.dwMask|=CFM_BOLD;3 o7 z+ H5 E8 X# w( T9 _4 p
cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
, }' D! J- |4 H" c4 Dcf.dwMask|=CFM_ITALIC;
! e1 O4 U4 d5 I7 Ccf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
5 d* F3 W+ m9 g0 w, G4 W2 mcf.dwMask|=CFM_UNDERLINE;
! I# n5 g' E f6 Y0 ecf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;
3 c- _8 ]. i' b8 o' u& o+ ecf.dwMask|=CFM_COLOR;
( ]: L0 Q5 g4 z; d0 H7 Zcf.crTextColor = RGB(255,0,0);//设置颜色
- W, E# R, j- l; s! e; q$ ecf.dwMask|=CFM_SIZE;9 Z$ U$ `: R$ T& H8 b& a% a6 T) Z
cf.yHeight =200;//设置高度
q5 v% l1 V8 o/ Qcf.dwMask|=CFM_FACE; K0 s! {6 P6 |2 L
strcpy(cf.szFaceName ,_T("隶书"));//设置字体
) A% o* f5 A( H6 r8 q- W% ^rich.SetSelectionCharFormat(cf);
9 Z: c. L3 t8 C' b' T0 H
* _- A0 i8 j( tb.设置字体的行间距
% w# k0 C/ p/ z9 z2 I, W: ?要用richedit2.0以上3 @- a, j* G1 }, B$ _
试试
5 |! r) P4 P8 Y* P% |PARAFORMAT2 pf;. w. {, d- m$ e! P0 M
pf.cbSize = sizeof(PARAFORMAT2);
+ Q' R `) ~ [4 W2 x ppf.dwMask = PFM_NUMBERING | PFM_OFFSET;
2 V$ y% C$ {; {pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING ) r. f* V3 b5 D! o# W2 {, N
pf.dxOffset = 10;
/ d) g: E( `/ n+ dVERIFY(SetParaFormat(pf)); : C( y1 D# B8 z7 A$ A- o9 O7 u
常用的dwMask有- N, J" C7 n) ]& Q) r! n
PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET- C$ s5 f' B9 C, ^/ j) L" v4 Y
2 使用阿拉伯数字 (1, 2, 3, ...). + L0 A( y! z) b" B0 x$ f" K% ?
3 使用小写字母 (a, b, c, ...). 2 g% V# v. n4 A: V& @1 d, L7 y
4 使用大写字母 (A, B, C, ...).
% z. v" N' ~" S5 使用小写罗马数字 (i, ii, iii, ...). 7 A: Z5 J& g/ f9 Y$ w" T
6 使用大写罗马数字 (I, II, III, ...). $ G* ~" d$ ^) R7 ~3 w d
7 自定义,字符见成员 wNumberingStart. ; N4 c- o1 ]& `
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
0 q, c1 L8 S* K4 yPFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进" _7 _. S0 e3 d+ V$ k0 X% c
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
L1 ] i0 E; t. _) ?. [PFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距% }( @) e: u k/ g: @1 F
+ ^) t% H0 E9 f& j2 w7 |c.设置CRichEditCtrl(2.0)背景透明 1 w6 u8 j2 K6 S Z9 u
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
- A( | e( r( L, Tstyle &= WS_EX_TRANSPARENT;6 T/ Y/ i! Z# g0 [5 n9 [
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);% S. A( S( B$ j) X( C- n7 r, o; P
或 CreateEx,然后把WS_EX_TRANSPARENT样式加上
9 X' f$ i0 C- c( i+ N' x) x( J* F& I+ c5 b9 X
e.得到内容有三种
]5 F1 k. x7 a7 S3 M% y5 p) Y6 I1)GetWindowText! H' P5 @* C0 Z: F! ?
2)使用EM_GETTEXTEX
! }0 C$ p7 C$ `GETTEXTEX gt;2 d& T5 q* b- c9 f7 i
gt.cb = 200;
4 C! R, M4 d1 e" m0 i* `gt.flags = GT_DEFAULT;
. i2 z+ l6 h% ]: j) w0 J0 F4 Vgt.codepage = CP_ACP ;
* T. t, L. Q4 W6 y6 w; vgt.lpDefaultChar = NULL; 6 j; @! I6 t/ k- A$ b8 o- w( h7 a
gt.lpUsedDefChar = NULL;
" V$ J% _+ N1 OSendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
( d; t4 ~: j( `3 M$ y3 B5 P+ ]3)StreamOut(主要用于RTF等格式输出)
. o2 |4 ^( r% \: u8 W5 zstatic DWORD CALLBACK 9 K' {7 V* u* B) @7 _7 |' @" e
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
9 C0 s' k- B6 W; M! ~- E{% x6 d: R, f7 `8 R% ]5 p
CFile* pFile = (CFile*) dwCookie;
o! x$ X0 ~$ A
1 A$ w& ^: \) Q/ M- J7 v6 \ pFile->Write(pbBuff, cb);
, o, \2 N1 |, U+ o! ], _ *pcb = cb;7 ~9 ]& w a+ i2 j% u. Z# Z
! I* v: C: c5 w
return 0;
! ` A, ~+ } q3 N o. |2 N}1 w; z! d6 M/ F" h' M" z9 a
4 S8 ~8 t+ I, a
- u! v3 n+ b" j) r
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
' y" e/ b/ o, X9 g EDITSTREAM es;
% f* k$ _% V5 \4 I) {0 { es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用
! t/ i4 Y7 o+ Y. E0 }& M" K es.pfnCallback = MyStreamOutCallback;
6 @. ^7 K$ D" O8 V pmyRichEditCtrl->StreamOut(SF_RTF, es);! p/ l9 Q) W: z: W: s- N
读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn+ c* ^$ P K4 j, A, e; L
/ @% C4 h% ]: A) D& {; [% ^
f.查找字符串' ]2 O! I0 w0 }% p5 E
FINDTEXTEX ft;) Y! c% e# n ^' Y% V2 R- G1 ^
ft.chrg.cpMin = 0;, C) @, }& f3 @; b
ft.chrg.cpMax = -1;$ v$ O8 i9 N( L
ft.lpstrText = "|";
* {3 e! G$ N8 [! P4 X" Xlong lPos = FindText(0, &ft);) ~0 H1 ?" L# {: q% t# ]4 d
; _2 |# W7 d' X+ H& g1 R0 S( W
如果要继续查找,修改cpMin,如
' @( J6 ~2 X2 _9 k- M( i, v* Lint nCount = 0;
% O+ W8 C* ]! s: U# Q; O& Edo, w/ t# {- R4 N- M
{6 D% A, E* d% a- `# L c
long lPos = GetRichEditCtrl().FindText(0, &ft);
6 T8 i' `( y" M$ u if( -1 == lPos) break;
, H2 \+ C: K5 N- F ft.chrg.cpMin = lPos + strlen(ft.lpstrText);$ }( |' p& ~7 T0 e
++nCount;3 M$ @* |: s+ N
}while(TRUE);# ]# q0 m Q, H- s+ o/ m \
' M1 s3 J9 x) y* @& o# \g.以Html格式保存
8 l4 Z# P- T: `' X目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
" P. [1 Y& _* P1 F: V% i, K6 h& _http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
& I/ q4 @! I5 Z; J8 C0 b8 A+ d& l5 ]5 Y2 [% ?
h.重载OnProtected函数得到对应的消息,如粘贴等
0 H, }( t: f3 [) m8 Z+ Dvoid CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)2 g$ t! D& h" [
{! {/ l& l9 K7 G1 C0 @$ m3 S$ E
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
* U c, w1 [( a ]3 X5 Z- m
! j# u1 i8 K' k# w. ` switch (pEP->msg) {. q( M5 l& Y. ~; u% |3 m' N2 w5 G
case WM_KEYDOWN://按键,判断pEP->wParam
; J( v9 K# d$ E ]% I case WM_PASTE://粘贴% B) z1 T2 |7 p- Y' m9 P
case WM_CUT://剪切
3 X" B) Z4 M3 {7 D u" n case EM_SETCHARFORMAT:: _" M# ^ T2 _. s" x; z7 X
default:
5 R& Q9 R8 I9 b$ O break;
" a- G1 H! C) e- e };
( v- d* {; ~: L& _5 C( V: o, d' f 0 Z( V9 ^0 {2 Z9 h
*pResult = FALSE;
: S! w3 s' W- P; y* A}5 Z% L' ~8 p6 x
0 D7 b/ [+ v, D三.聊天常用
6 k" l: `7 l' u: f7 D; \- ya.LINK 链接功能
% ?3 o" R% y; j3 H" \1. LoadLibrary(_T("Riched20.dll"));" e* _' q7 L; u. r" A4 y6 L
2. 创建RichEdit2.0控件
0 l+ b7 m4 Z! ?/ z5 b7 F* ^" j, a CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP* D O; x! I3 q: l1 n3 y9 j8 C
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
( r# Y8 M8 U' R rect.left, rect.top, cx, cy,+ S; p8 l3 d' I3 y2 ?5 _! K
pParentWnd->m_hWnd, (HMENU)nID, NULL);6 H$ }" ^1 V$ U ]2 f( \
3. 设定选中的文字为链接显示
8 o" b$ K$ G/ d$ Z1 K8 b1 q7 `CHARFORMAT2 cf2;: }; {; H( G7 F9 i
ZeroMemory(&cf2, sizeof(CHARFORMAT2));//; ] F" ^) q$ V- Q
cf2.cbSize = sizeof(CHARFORMAT2);
5 @: e' h: m& R# Scf2.dwMask = CFM_LINK;
- x& u! h1 `! X3 @1 z3 Z+ qcf2.dwEffects |= CFE_LINK;
* a( @: ^- S5 M0 c; B$ fm_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
* m. d! I& s N' W& _% U4.支持链接的点击响应; O% ]2 p$ B" j" c& T. Q. H M( q
m_cRichEdit.SetEventMask(ENM_LINK);
8 }& G# k% W0 a/ o2 x4 u" [5.响应链接的点击EN_LINK( F5 h. l1 U3 I: D9 x
# ?% r4 `8 F- e; M A9 n: N1 j
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)0 g* H' N! l. J/ S8 D3 }
ON_NOTIFY_REFLECT(EN_LINK,OnURL)
7 p: y, q: c- p, Q/ lEND_MESSAGE_MAP(): W( R! H5 d, N" e* i5 ]. h
......0 h- y5 x2 z! ^5 a
1 M% G$ }; `8 H7 R% T
void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
# o h9 y+ F V- s{- X2 D) R \4 y$ C6 D# I5 P
TCHAR LinkChar[512];
* _: {5 k5 c5 @) VENLINK *pLink = (ENLINK *)pNmhdr;
( P( z8 ~$ a0 n' T) \8 U; tif (pLink->msg == WM_LBUTTONUP)
# `& k- T8 p! s; T# S9 y) t{) V' H/ q. t3 h% {
SetSel(penLink->chrg);//这是链接的文字范围
! j/ Y( V$ Y* A7 w. z5 Hlong Res = GetSelText((char *)LinkChar);//这是链接文字
. X9 L2 y8 y4 N( S, `2 y //后面是你的处理过程
+ u1 }& \8 X% J i& P% }# O ......6 X4 @& K! _' X4 d9 _8 Y* h
}
' w9 s% L7 b6 o/ D0 P z; ^$ n} I9 Z2 b& z4 A. e0 H: X6 ^8 _9 R
) O" n3 k. N( Q% {6 S1 t) @& U
b.插入位图
; Q: P& n9 i" Z! G) Chttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
h8 J. F4 H" P+ {0 Whttp://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/$ s1 E* X- E, j9 R( J
+ _8 Z/ i1 C# R
自定义在RichEdit中插入对象的图标4 C) m3 V7 A9 N7 Z, X# v& W3 f
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html+ d% I0 C. G9 L9 ~& V
方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
, j: O4 O! r0 y4 H* m. R2 g只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
2 z- g: H5 S1 y0 V6 e" v. y# y. z! E
使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。" x0 G, @$ K( u5 P6 Q
另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
( }3 Q: v. T; \! V T% R3 B8 Z: P/ n3 `
c.显示GIF动画
$ J0 Q8 q5 h/ A* [常用的是通过qq的imageole.dll(也有用Gif89.dll的)- X% n" A/ u' p# f7 B$ \6 k
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82) [: D0 g+ _* n7 a- Y: `; g7 l
http://www.codeproject.com/richedit/AnimatedEmoticon.asp
& O& k, ?+ o8 j0 l) L$ w& C9 F( c& o
, ^/ E5 z: e$ ^# j% M- k在richedit控件中插入动态GIF (Native C++版)
4 c0 O. K: Z q2 O6 chttp://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx/ _0 K/ k& i0 R
. A$ f* N; h) |& l1 `- U+ X" C0 G4 Wd.IRichEditOleCallback的使用
: q3 ~( G, G, X$ chttp://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022
2 ]! _' K; P% M: S
+ V! v4 d5 S, t* u) ?类似 MSN 信息发送框的制作(上)
. q/ Z* E2 I8 l, q! ^+ vhttp://www.vckbase.com/document/viewdoc/?id=1087
" x$ I5 \! f! h: A1 l6 h" c内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串; c T4 S* O4 L8 y+ M0 s+ Y
) O1 {2 [5 d5 r |# @' k% |$ Z
自定义 CRichEditCtrl 控件
, b* }2 @& N* T* i6 u% H' mhttp://www.vckbase.com/document/viewdoc/?id=328
8 t2 b2 y' k/ n3 r内容包含:鼠标右键消息,消息映射,字体变换* W& a1 v/ L5 s% `/ s
9 y: m+ }9 q$ APS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母/ g {( ?' z+ s2 o
是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778 ( g% b& A. M9 c6 r
----------------------
9 F/ h4 y5 {- E" [/ [7 h比我想象中还要花时间,所以最后潦草了点,见谅 |
|