|
|
一.常见问题
$ i: A7 [+ V: W7 na.可以编译,不能执行的& R/ J ]1 G4 w
AfxInitRichEdit();
, d2 E1 U3 M4 F6 c5 O7 a% W# g" F) p7 j( ^2 @
b.升级默认的Riched版本(默认的有一些bug),如- r$ E5 \8 }( [+ t. U- e
可在InitInstance中添加
. C; }' B4 z" }9 [LoadLibrary("RICHED20.DLL")
6 |: R. A! K! M4 h( Z" K2 X D% Q最后注意 FreeLibrary! B# a% W- S$ ^2 ?
3 n& q; g. N- i! ~- |
如果是CRichEditView基类的可用
3 c J4 D1 Z: Q* |5 [0 lBOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
; f3 |6 M# Y' o' U{/ L, [" e4 |- j) I2 M
//装入rich edit version 2.0
* e4 Z0 K* }1 r Pif (LoadLibraryA("RICHED20.DLL") == NULL)
0 ?" ] R: C# |( K{; w) |% a3 ^, A" `* A0 L
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);9 z ]: d5 \2 }4 J
PostMessage(WM_QUIT,0,0);" b2 @' n1 c2 {: i- T% r0 i
return FALSE;
- q' x* Z9 |& s& Y% E}
3 d1 t5 |) s7 k1 @6 _1 o& p% f7 O
$ l; u8 |* G: ym_strClass = RICHEDIT_CLASSA;//for 2.0 class. E5 j0 V. w# k& N8 g
/ i \. \% M2 d! b) I+ h0 {4 Ereturn CRichEditView::PreCreateWindow(cs);
0 a' {, W2 Z. t& _; ]}
8 ?5 h2 K% j& L; E6 ^4 K t3 w* T
7 b: z. }8 {$ b0 U7 m b) F* ac.最后追加行
4 l) L: o6 X7 Y. x: b8 Cricheditctrl.SetSel(-1, -1);+ l% J) P* g+ |$ I7 a/ {
richeditctrl.ReplaceSel( (LPCTSTR)str );
* T. k, s, p6 }* C" S( D5 R1 B4 M+ f7 c( Z& m8 }2 l: v6 z# u9 Y3 ]$ ]+ }. S( M
d.字数限制9 x, n2 E& P. [
CRichEditCtrl::LimitText(long nChars). Y0 v U N2 S: G$ p
4 }2 u* F- E# I3 o( O) se.换行切换 t/ ~: Y4 S! I. S
CRichEditView的OnInitialUpdate()函数中加入下面两句:7 {; b9 @' H8 K$ `% g2 [/ G
m_nWordWrap = WrapNone;- A; F- J0 ?1 w. O% c
WrapChanged(); 6 }; \5 |/ i% W1 O+ H- Q
WrapChanged实际上也是调用6 |7 w: D$ Z) _% q2 M- [' s3 E7 ^9 X6 [
ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone5 w* A7 C3 J; I1 z' n3 w
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow" y1 y% _! R T
还有不常用的 m_nWordWrap == WrapToTargetDevice
1 j4 B$ m' Y) h! |% lctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());* y6 F+ I( X- D( T% c8 B" X
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return3 F! L. m& p9 q
% g/ m3 B% t9 N& S% af.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
% @5 M8 W0 \5 ^9 @7 kpmyRichEditCtrl->PasteSpecial(CF_TEXT);! F: W9 o2 C2 k
6 n1 s* j7 s2 x2 d
g.随着输入随着自动滚动条滚动到最后一行) \. l5 v$ v( s, L/ `
int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();' |* e) F5 w6 s' ^: P( ~+ j
if (nFirstVisible > 0)
6 e h, d/ c+ E, U; j{
7 @* r( F3 c8 ]- u6 G pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
?2 T( o5 ?6 D& \1 J% S+ q}. l% z+ H/ f& E c0 E1 ]+ m
或
/ Q( ?8 y1 k$ l4 qm_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);4 N- n) {' A, }0 l8 R; Z
$ z, s z* }0 x( Y8 g. S
% o1 A! j, k9 t5 b0 \h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
G1 a4 o8 x5 d. V/ g/ k; E0 ^1 ]SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
$ y0 `3 n% O6 k4 ~% x$ F2 _2 f; oTM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
7 L+ c" V; h, L. y; H% ` CSendMessage(EM_SETUNDOLIMIT,100,0);" Z3 I( [1 x8 p9 i1 `$ o
e" m; h( I1 k4 W/ fi.响应OnChange6 H% p, ~7 z$ h9 Z: V( Y! B8 u
EM_SETEVENTMASK 设置 ENM_CHANGE
Q. @" j6 P' Q. j$ \$ b; flong lMask = GetEventMask();
' ?1 U5 _8 w7 K* C0 N: V# f7 _lMask |= ENM_CHANGE; n: H2 U0 j7 K8 o$ V/ r
lMask &= ~ENM_PROTECTED;: B, @- M9 R0 G x7 j
SetEventMask(lMask);
' n; ]5 c6 J: c; W1 k: V. U5 I* p( p6 n
j.设置只读
h2 U; d* L. xCRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );7 X8 G- S8 b+ T5 r2 ?- r
通过设置PROTECTED实现选中的文本只读,参见. S4 z! H" w2 A5 B# Y2 h
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
' y% e# f1 l! t: O" h
6 W& h4 \ Z/ U& h0 Q3 d |二.函数应用
. o1 s5 _8 f3 e* Y0 z; da.设置字体(主要是通过SetSelectionCharFormat)
) n! C; j ^1 t+ z8 `CHARFORMAT cf;- j! m3 ^* f# P7 X* e
rich.GetSelectionCharFormat(cf);
( s# F& r% q) L$ u8 h4 m' j, O, p' ycf.dwMask|=CFM_BOLD;' X& x, r; o- q# B
cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;( ~$ V- R* a! O
cf.dwMask|=CFM_ITALIC;( h8 Y. K0 `+ v; ?
cf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
6 ^- \ Y% Y/ ~! r& ncf.dwMask|=CFM_UNDERLINE;
* I7 G' `8 t9 {6 G# u: Wcf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;/ }- E! l1 J J# T
cf.dwMask|=CFM_COLOR;! J0 | I2 r* T& M
cf.crTextColor = RGB(255,0,0);//设置颜色
2 z( S, N9 w6 G# I: J$ _8 acf.dwMask|=CFM_SIZE;( {. a3 }5 w8 o! I# X0 T0 |
cf.yHeight =200;//设置高度, Y+ q/ ^. C! e& ~
cf.dwMask|=CFM_FACE;
' Q9 f7 M1 T3 f; t( mstrcpy(cf.szFaceName ,_T("隶书"));//设置字体1 `8 Y) q- m) B
rich.SetSelectionCharFormat(cf);
6 [$ b" {' J- y, f
3 L2 g% o# f! `& y+ s# Cb.设置字体的行间距2 b0 X/ X0 [' d/ A% [- j4 Z' s I ?
要用richedit2.0以上
3 Z, J" J4 o% p' [7 ]试试
0 U' \# A5 i. zPARAFORMAT2 pf;
! [& }. K" c9 y: ?" X; k! Mpf.cbSize = sizeof(PARAFORMAT2);
( E$ n5 Y- E4 n' C/ H* @pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
' R7 c9 g) L! Y6 I, Hpf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING ( q: P8 K/ p2 i: Y6 a
pf.dxOffset = 10;
N7 V& K) o9 ?9 U+ lVERIFY(SetParaFormat(pf));
0 i( N3 G* A9 p: Q常用的dwMask有
" B" r2 B) z& Z% q& jPFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
4 f2 }* Z+ P: V' C" B2 使用阿拉伯数字 (1, 2, 3, ...). # Z9 l+ p1 C$ t3 L- F/ V
3 使用小写字母 (a, b, c, ...).
* s6 Q# ^# a4 ]& `! E4 O7 v2 ^+ k4 使用大写字母 (A, B, C, ...).
( u# P+ @# f$ A2 m' p Y5 使用小写罗马数字 (i, ii, iii, ...). ( p4 K j& k+ M: o, L2 u7 A( e/ q5 s
6 使用大写罗马数字 (I, II, III, ...). + b5 m! E c1 G! X" T
7 自定义,字符见成员 wNumberingStart. ) E' u! S+ U& J( l: p5 Q
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
+ A' r, R6 `6 T! W* SPFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进! F/ i4 B, D7 E2 `' |( ^
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
" O4 @, D) V& J2 H$ }8 N- dPFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
. ?0 b, }( G+ _( x8 @& B8 s
M# H! m$ s2 {( Z8 R5 r2 Qc.设置CRichEditCtrl(2.0)背景透明
! W0 w G$ r/ b4 w7 m5 \long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);5 O6 s; r& ?6 r& E
style &= WS_EX_TRANSPARENT;
$ I {0 N( E6 F, p::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
8 o0 g: `4 D6 r ~3 Q* `; K7 d或 CreateEx,然后把WS_EX_TRANSPARENT样式加上
# d; ?% }9 }( Y! w
; ], f: I" g( S) O2 te.得到内容有三种9 o `+ i+ _* J3 f) x
1)GetWindowText. k7 U* q# g1 p) v) E$ x
2)使用EM_GETTEXTEX& y$ {5 `1 N$ ]- c' B1 B% L
GETTEXTEX gt;
" k* P h; b0 ^3 H( Ygt.cb = 200;" b/ }2 _$ g8 k i' D% `
gt.flags = GT_DEFAULT;
+ z4 Y; c D. G( l. o! R7 U0 a) m: ogt.codepage = CP_ACP ;9 I0 _0 O/ d) Q. }
gt.lpDefaultChar = NULL; 3 I( V* i% o$ v1 y5 {
gt.lpUsedDefChar = NULL;% Y/ t0 ?9 p2 `* {
SendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
& N- E. d9 i2 z3)StreamOut(主要用于RTF等格式输出)' [1 B) [' [3 o" L) N0 ^
static DWORD CALLBACK 4 a t( [% y' j0 J* n: E
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+ D1 l/ ?6 k& i" q* Z{' t; i5 b0 `5 e* D% ]+ d
CFile* pFile = (CFile*) dwCookie;
4 G' r$ ?1 K8 @$ l* \ g) U% Q/ v" F- D$ y d) q5 ^* J( K5 H4 i
pFile->Write(pbBuff, cb);
. n3 x4 l# x7 l4 v *pcb = cb;
0 P: V: z f t; _" J. @3 ^' T; o% S) @: B" }8 j$ e
return 0;
1 g& C$ i) p0 w- F+ S}* N+ u q$ o4 h, j' F) b% Q5 ~' r. Q
4 Z9 H D& R: q. l/ f+ _
6 g' {2 ^: F8 ~" a ] O CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
& C6 P. M; N* P6 O EDITSTREAM es;
1 J% a4 I; I. c4 t# i es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用
+ O2 a( K/ m/ P$ O( N9 x es.pfnCallback = MyStreamOutCallback; + d& J8 l6 ]3 z, i
pmyRichEditCtrl->StreamOut(SF_RTF, es);
! Q- ?; I: [* v |读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn: }1 J6 k7 q7 l" N! I
. a0 n9 Z& I& |& p/ ~f.查找字符串( o1 `( h6 R6 S0 C
FINDTEXTEX ft;9 l- }% f+ a$ I+ Q, s6 s
ft.chrg.cpMin = 0;; y% {& b/ e! ~% a
ft.chrg.cpMax = -1;+ c: V% n0 @- V+ S; P; V
ft.lpstrText = "|";
7 F" W( ^+ t" W" z$ q$ ulong lPos = FindText(0, &ft);( {2 ?! o, i, ^/ w- Q, k& k7 ]
$ T+ R w, ?( z( q+ K如果要继续查找,修改cpMin,如
3 _$ d1 E' [ d* g5 ]& [$ k2 wint nCount = 0;) _3 o9 X, N) X3 w& [( Z
do
; m: e4 I' U6 J{
7 @" Y% \# U _9 [3 a5 F: O long lPos = GetRichEditCtrl().FindText(0, &ft);
4 }$ L, u# a9 F C, J if( -1 == lPos) break;
6 V: d9 Y+ u( F6 g! C: v% w ft.chrg.cpMin = lPos + strlen(ft.lpstrText);0 u; W$ t7 l8 e/ L$ B
++nCount;4 r6 T0 {! K- ~6 _/ v* u% m/ R
}while(TRUE);
X4 |/ C7 j2 E, R% }/ m
& f' K% p! S$ v$ r9 l* _g.以Html格式保存' @$ G* s5 u6 S/ X/ I! i' c
目前做法可先转为RTF格式,再通过RTF-to-HTML Converter- k8 d3 v" v5 x2 h. u# l
http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/9 r0 H O, f. e0 L! g. ]3 i* q
m0 t8 \# H3 O8 X/ V0 Eh.重载OnProtected函数得到对应的消息,如粘贴等% {0 R, V# a: \$ r3 y* j
void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)( g. m H- ?% q$ [0 k
{
$ ], l, i# ?/ }4 j6 T ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;9 G- }7 {8 [6 V# `' H
" B6 A& N3 l- y# m0 s4 M
switch (pEP->msg) {
8 V" G: r' g6 F/ k* h4 H case WM_KEYDOWN://按键,判断pEP->wParam
) A; n( R% B% m, l case WM_PASTE://粘贴
- f4 X& W' b0 J8 X" e, L case WM_CUT://剪切* h D- i3 c8 S/ y/ G, O: j
case EM_SETCHARFORMAT:
) I7 J. H7 w" U1 r default:
1 w9 A- e/ Y8 f* H' K# ]7 n. c break;
( _( A; Q. J! G9 v% b% b };
. u3 D1 z3 J- F- J: S
: t, s' w1 T6 y- _, r' `, L *pResult = FALSE;' l" t3 R' }) o J5 l# Q9 E8 ~
}3 }. Q0 w" S* [; K" y
?, e$ K5 J R1 p9 Q三.聊天常用 - j# {& x, k# W) W' k
a.LINK 链接功能
* }4 v6 r0 Y, X- h1. LoadLibrary(_T("Riched20.dll"));
2 ~) K) H3 D$ d' b/ g2. 创建RichEdit2.0控件
0 ^- ~* `: x8 k. z CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP" l4 U" l# v7 `, _( F# W$ U0 t% _% T; v
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,9 Y; n6 q5 L- r4 m- z9 ~
rect.left, rect.top, cx, cy,2 A' x' p$ X' s" g' y! [
pParentWnd->m_hWnd, (HMENU)nID, NULL);4 A2 ]# ~: }. U
3. 设定选中的文字为链接显示# o0 b% f: J* B3 U* [8 h+ x
CHARFORMAT2 cf2;
) ?% q6 W1 p1 G. j) i5 E OZeroMemory(&cf2, sizeof(CHARFORMAT2));//. x; }, D$ C" m- @
cf2.cbSize = sizeof(CHARFORMAT2);
# P) w+ [( s7 I7 zcf2.dwMask = CFM_LINK;5 b4 J+ a: S/ X, Y R, _
cf2.dwEffects |= CFE_LINK;+ D+ g" c$ r2 ~# B
m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
! R5 I! ?" g8 @6 B4.支持链接的点击响应+ |: U# K& t& }6 Y
m_cRichEdit.SetEventMask(ENM_LINK);
* r# c$ p- l, S+ y! E/ ` I5.响应链接的点击EN_LINK1 F* D- ~$ } l& O% v
( h8 } L4 [. o7 D1 Z
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)8 X) l5 R# i. p6 J$ t) Q2 f( r
ON_NOTIFY_REFLECT(EN_LINK,OnURL)& I6 B/ h& p' P0 b7 R) x2 P' { Z
END_MESSAGE_MAP()) M% b' M8 Z1 @" V1 {
......
4 f$ l2 A% x9 h9 Z$ ~' C' k5 e. ]8 o; n6 [; ~# O
void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)4 ]) ]' U" {: n0 `! w& x
{0 I4 _4 a0 a0 Y: A$ D% e) r
TCHAR LinkChar[512];
0 W( e6 l0 S" w( hENLINK *pLink = (ENLINK *)pNmhdr;
: [: N4 q! P0 i4 `% b1 X! W) Xif (pLink->msg == WM_LBUTTONUP)
5 T. ]$ S3 I+ i& ] O{
; G7 u: S. N$ k, `/ V5 ]SetSel(penLink->chrg);//这是链接的文字范围
! G2 O7 G) w2 U9 D. V! @' \- @4 plong Res = GetSelText((char *)LinkChar);//这是链接文字& @! K" ^( f s; S2 p# R+ @
//后面是你的处理过程
" }9 N; P" B: g& N ......, d" N9 I# h1 h4 A& j
}
6 `7 ?$ _( s$ a8 J0 }}. m/ k7 v0 B! J$ n; ]1 `
$ Q$ B! ^+ `# Q/ a1 Z" m+ xb.插入位图0 `) A' f4 [2 j. O6 I
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
, F' z8 \5 O# ~5 Thttp://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/+ E+ T" {1 G' b' n# M6 e# c+ }
# G! H: Z# [ V$ B
自定义在RichEdit中插入对象的图标
" A% G, D+ C$ R1 |! Hhttp://www.blogcn.com/user3/jiangsheng/blog/1319738.html3 ]* K+ \- o6 s( A( B4 m3 K
方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control& ~2 T3 K& ^% i5 s6 G
只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
! a6 j- z. f( `0 J; [0 h3 t" X- T3 N2 e5 J' a
使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。) A0 P4 I. ]/ y1 A9 e! ~5 z
另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
0 J2 W1 Y$ d" f/ b* F$ S) t+ I9 L. j2 u3 R- F3 }
c.显示GIF动画3 V, u' P$ u# u7 r7 Q$ f7 L
常用的是通过qq的imageole.dll(也有用Gif89.dll的)
* n1 g7 ?6 O5 ]! x$ B0 h y: mhttp://www.xiaozhou.net/cooldog/blogview.asp?logID=82) ?) ]8 U& h7 ~3 Y+ L2 P
http://www.codeproject.com/richedit/AnimatedEmoticon.asp3 a- g4 H$ n5 i# }3 Y$ t% O
9 I7 A6 s. g4 u N* b b在richedit控件中插入动态GIF (Native C++版)
% I9 M6 h) b2 xhttp://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx
! j( p6 f" r, ]7 v
- e2 E5 q9 K8 ?, od.IRichEditOleCallback的使用: d4 p' @/ U) I1 c. p+ q8 ]
http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022
5 z) M& [9 N% c0 ?) `; Q, t8 P9 J
类似 MSN 信息发送框的制作(上): D6 J3 D2 {' k0 v
http://www.vckbase.com/document/viewdoc/?id=1087
. {! r/ ~1 N+ a6 q. r6 ^内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串 n) z6 E8 z* [. T9 o
6 f' i; D- ~ H, b7 r9 T. Y
自定义 CRichEditCtrl 控件. ~5 z6 w: p% z% W$ j% |5 g
http://www.vckbase.com/document/viewdoc/?id=328
E: C1 V; g6 s/ I内容包含:鼠标右键消息,消息映射,字体变换: f6 x x. X1 e% z' L" ~( N; o
1 X, s& @0 }2 A+ ^" q0 ~# ^PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母; W2 w9 e) m: t% o: t2 z8 [
是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778
( K9 h* k. `# q3 I. k# l----------------------
8 ?8 A. u. E/ X7 g比我想象中还要花时间,所以最后潦草了点,见谅 |
|