|
|
一.常见问题4 T' K- X! j6 P) c0 H
a.可以编译,不能执行的+ V/ h1 [4 e8 n1 L d
AfxInitRichEdit();& p$ [ S* M/ b- P n$ {5 ^$ B# Q0 p
. ~/ ^" F3 `; w7 O J+ Q+ W
b.升级默认的Riched版本(默认的有一些bug),如
8 N2 B( `# ?' F1 u9 A% p% S6 {可在InitInstance中添加# L8 c/ ~1 |! \1 U$ C" u& q
LoadLibrary("RICHED20.DLL")
* N: w) Q8 e5 v+ z# b" ^+ B' f+ v最后注意 FreeLibrary1 o) [5 u0 k, o( b$ w
/ S9 C* @) w! | x: D+ i
如果是CRichEditView基类的可用0 }* H& v; A3 {. T2 h. ~5 e7 D
BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)2 v9 f5 `7 S" f# p% H; _4 p
{& X2 f$ G& s" E
//装入rich edit version 2.0- ^7 J9 ]" w, ?/ a% S( f
if (LoadLibraryA("RICHED20.DLL") == NULL)
! [. F: j2 R. q/ \3 T6 d{4 ]: I/ r$ U% S' t/ I# M! a
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
( s: K- W3 ~1 [8 g u7 JPostMessage(WM_QUIT,0,0);
4 ?# ~/ k! O/ V+ ^& c4 m: P% }return FALSE;) o, j. e, T f
}- ^0 j: x9 D8 h5 |' r
9 r% B" D8 ?5 X5 W: {" zm_strClass = RICHEDIT_CLASSA;//for 2.0 class; [' b. L8 ^7 `7 y8 A
2 [3 a4 y1 r* |: E0 h. e) ]: ]return CRichEditView::PreCreateWindow(cs);5 \- W/ C. l. _5 k2 D; {/ |
}
5 \9 O0 u4 u; u& ^7 U Q; ~7 e% ]' m* ~! [! x
c.最后追加行
5 N2 P( \+ y- Y" Q: Qricheditctrl.SetSel(-1, -1);6 T9 B: ?% u2 K. h0 z3 ~3 M
richeditctrl.ReplaceSel( (LPCTSTR)str );
9 g; p6 F9 L5 V- O( c
4 d8 k C8 n6 f$ t" c- Z p; A Hd.字数限制. U" m( b, t# J- V2 N
CRichEditCtrl::LimitText(long nChars)
7 K K4 ^0 r. G5 M7 M; d! T
9 b: ?) q2 m/ S6 [+ O# Ae.换行切换) B- \% Y% t( ~/ s
CRichEditView的OnInitialUpdate()函数中加入下面两句:( p% \. P1 e6 X5 G0 Q* P! p
m_nWordWrap = WrapNone;
) {/ S" y$ @. H- a8 f* QWrapChanged();
! i5 `$ l7 V) SWrapChanged实际上也是调用
1 e2 [% `; X2 mctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
, O( s: E2 \5 J) E/ S* [1 T2 A/ kctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
) K' N- B* K9 @; w% P还有不常用的 m_nWordWrap == WrapToTargetDevice
G8 E8 y0 U8 ]7 w s7 m1 u' V& Dctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
0 k9 A9 ?. F6 m5 b* ]) F如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return4 D/ _! Y1 s M- O" A& m! ]% r5 M! ?9 S
' }* t/ l* m- t- j3 G; yf.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴5 K# }5 {6 K) X; P% ?2 X! O
pmyRichEditCtrl->PasteSpecial(CF_TEXT);' G% }3 m' x9 r/ h# \ e
) R# g$ }2 B+ H0 c
g.随着输入随着自动滚动条滚动到最后一行
& i# O* P5 a; f6 q+ z yint nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
P, e& i, T1 t8 Vif (nFirstVisible > 0)
7 y8 Y" f; `( R: T' A{
5 H2 D; ^ G2 `( Y6 {8 f pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
6 _1 _2 l) K% ]}
, S. {6 ?7 R6 f或
$ p) P: t% {; J; p" wm_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);7 R0 Q! I6 Q# N9 W
' Q( Y9 Z. h0 G) }4 O" W3 F+ x7 m! i. m
h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
4 \5 T2 v/ C4 O& P$ w' cSendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);4 e. l, a: v. I& B( V+ [
TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
( J: i4 P* A) G; ~ e0 nSendMessage(EM_SETUNDOLIMIT,100,0);* D' w: p7 H. ?) }, T+ K8 P b
5 J0 s( ]2 i' J( s
i.响应OnChange' a- _ @+ f$ p: u
EM_SETEVENTMASK 设置 ENM_CHANGE Y) V& D& O5 h |
long lMask = GetEventMask();: P6 \0 H& w: }
lMask |= ENM_CHANGE;
+ @8 z L! r8 j6 D6 c1 B. h8 FlMask &= ~ENM_PROTECTED;' S. I- G. R9 B
SetEventMask(lMask);9 ?9 ^4 ?/ R; x
3 x. ^7 T n. O9 e. @. M3 _6 U
j.设置只读3 I. |( y$ C6 S4 u
CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );! U+ a8 d; |" d" _% c+ _6 d* @# C
通过设置PROTECTED实现选中的文本只读,参见
, ^/ [6 r1 `3 ^4 Q# m2 X/ i3 Shttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/" @+ r$ O5 B# h3 L& c; c3 y4 t
. p5 P+ ~1 F; {1 Y$ k二.函数应用
' v |1 f1 \5 y+ aa.设置字体(主要是通过SetSelectionCharFormat)
& a- q" f: ]6 r/ @CHARFORMAT cf;
. x2 x8 j0 S% @. J9 U. Yrich.GetSelectionCharFormat(cf);6 M7 j& r+ i* q% E" j
cf.dwMask|=CFM_BOLD;5 Y8 R. k0 T6 @3 j0 r: P6 X
cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;. P9 a& f0 y1 F$ ~
cf.dwMask|=CFM_ITALIC;
9 a% y4 V8 j; ^. r3 {$ m7 `& Jcf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;. y2 d# p% }, x
cf.dwMask|=CFM_UNDERLINE;, Z) T3 }( ~- q b3 O& u7 g
cf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;
0 L: i+ n* t# H& ?" K7 Wcf.dwMask|=CFM_COLOR;3 ~/ k6 }( z$ }# e! P2 ?
cf.crTextColor = RGB(255,0,0);//设置颜色
( I& f$ J+ M4 k1 `cf.dwMask|=CFM_SIZE;
8 a% t6 J) ~. }3 @cf.yHeight =200;//设置高度& n- g& n$ q8 c4 ?/ c4 D" C
cf.dwMask|=CFM_FACE;5 ~$ }7 n/ M; }+ S' _
strcpy(cf.szFaceName ,_T("隶书"));//设置字体
* T! [( C3 T4 [- d( ^rich.SetSelectionCharFormat(cf);. F4 E) x5 k: p7 U
; B2 }+ ^! n G) z; a% x! Wb.设置字体的行间距3 g7 G% [. z: r$ A5 `2 T
要用richedit2.0以上
' {) }+ z! [& j# B* v; L试试
6 A L2 G8 [0 @# p7 |2 zPARAFORMAT2 pf;
2 L, A$ P4 h# ^pf.cbSize = sizeof(PARAFORMAT2);) F' I# o$ h( ?, i3 b+ _8 J/ n6 y
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;/ ? p! b' u/ ?1 ?# w. B3 t8 s
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING : F, R$ F7 c! {. s' m5 t
pf.dxOffset = 10;8 e; H( o/ A: M
VERIFY(SetParaFormat(pf));
) N6 S& D O. r$ ` p! p8 t常用的dwMask有
9 d/ L4 F9 U7 b/ i# f1 E* a/ T$ s8 CPFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
8 U1 z8 d3 G$ K: r" V2 使用阿拉伯数字 (1, 2, 3, ...). 8 X# o0 Q! c1 N' W
3 使用小写字母 (a, b, c, ...).
& G; f; L8 F7 z3 E8 }- }4 使用大写字母 (A, B, C, ...). + j3 f5 e! D1 k5 B* ?) ~$ B) K8 t
5 使用小写罗马数字 (i, ii, iii, ...).
5 g" ^/ v' t x( i1 d* C2 X6 使用大写罗马数字 (I, II, III, ...). - X# h4 X' A( s' c. y, K# H" M
7 自定义,字符见成员 wNumberingStart. : y4 \. n4 }, t/ `) f
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
2 r+ U# h% S: A9 x* \PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进# }& g. G$ C* j; h) E
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
6 I. V4 |) _4 kPFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距. O2 A. i4 W+ o' v2 ^0 f
; h" b: l) N+ w y, Gc.设置CRichEditCtrl(2.0)背景透明
& S6 k+ V* F, y+ p6 t0 glong style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
- {. @ X) f8 A+ _& bstyle &= WS_EX_TRANSPARENT;
/ @" Z9 ^+ Q0 f" _( ~2 n::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
1 r5 n1 [1 V% E2 P5 r或 CreateEx,然后把WS_EX_TRANSPARENT样式加上
, s5 S- ^& n4 F* Q' x' [; x$ A r2 N" C! N
e.得到内容有三种
* @3 g! ^0 K/ L( `1)GetWindowText
! m5 S9 @% p3 x. g6 u: R2)使用EM_GETTEXTEX$ F# w. W4 x3 R/ a+ U8 P$ K
GETTEXTEX gt;: ~) j! }6 S. O5 B' g( j
gt.cb = 200;
& [9 ~1 D/ w4 o% ^8 xgt.flags = GT_DEFAULT;
0 Y; J! u f0 d( L/ Dgt.codepage = CP_ACP ;
: D* \6 {" Q7 U7 H0 K3 @2 zgt.lpDefaultChar = NULL; * h. `8 U& g8 t. _+ p
gt.lpUsedDefChar = NULL;) k$ X; R2 l9 |% D: D
SendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
8 N! x1 L! c$ ~3 D" M& L3)StreamOut(主要用于RTF等格式输出)
3 P2 f/ o* s( p0 C5 }- istatic DWORD CALLBACK
$ v+ ]$ f5 I1 `2 c' c7 V: E: cMyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)8 W( Y$ @3 s0 i
{% a0 L+ R5 @1 N. D' R
CFile* pFile = (CFile*) dwCookie;, L, ^$ Z: [& k
3 \% v) r, s4 H A pFile->Write(pbBuff, cb);
9 B n- P) P. y; m0 h( w% M4 Y- q *pcb = cb;
0 h% _8 A5 t& F) {; o9 O% Y0 ?+ Y2 Q. B9 C5 g# o
return 0;1 x( o3 D: k8 f# Y" G, O+ p9 l% T
}9 {( O; |' f( E. [# H- s# o8 v
0 B$ i4 E& {) L: [
& K* C9 U, f' q) f CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);0 \. q$ ?* `/ J a
EDITSTREAM es;
' a- |( y4 r# C- Y, o+ t& G es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用
3 b9 A% u1 W! R: p/ { es.pfnCallback = MyStreamOutCallback; + W% \, a9 e' m% }- X" d
pmyRichEditCtrl->StreamOut(SF_RTF, es);
2 N4 X* Q$ \# [8 t0 {( x读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
! J! k* h1 u- G( ]4 D, `0 q9 A1 {7 o+ @" u7 z
f.查找字符串5 ^6 E: r: q4 }8 I- r/ z2 k: u" `( j
FINDTEXTEX ft;
8 N$ M% z7 h$ ^% Yft.chrg.cpMin = 0;
$ {% O* v3 _1 l( s' q& hft.chrg.cpMax = -1;. L) C: d* g' g) C* g4 n2 S+ C
ft.lpstrText = "|";
5 C$ T9 K* y- o0 S% e4 jlong lPos = FindText(0, &ft);
+ f3 _7 H4 g3 P1 N* ] A6 x" U( U3 a0 {, D/ ?% {8 U3 W
如果要继续查找,修改cpMin,如( s+ u( Q. p, W" n5 ~* l; V, y: |
int nCount = 0;
9 H8 k- O7 a# `6 S2 K6 B2 \3 fdo+ [, W- R/ \* d# t5 b; D
{
$ O2 C8 Q3 [- ?9 h7 s long lPos = GetRichEditCtrl().FindText(0, &ft);
4 b* @1 v0 J9 i1 z8 ^! F8 C! L if( -1 == lPos) break;
& D/ A( e% g& Z( t1 Z8 f, _ ft.chrg.cpMin = lPos + strlen(ft.lpstrText);5 ^* ?8 w9 i& y; Q: \; }
++nCount;3 K. T2 T/ {' l& i
}while(TRUE);' O, d& v# m e$ q5 \
9 V4 v% [5 ]% W
g.以Html格式保存
0 t8 d5 c% y4 d; Q3 |# g( R' A8 `目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
, a6 K6 [: h; z W" s* thttp://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/& v3 K6 F" d: |2 h1 ^
- u* e0 O) d% gh.重载OnProtected函数得到对应的消息,如粘贴等
0 O9 S- q+ k5 l! H, G# P. p! N8 _% {void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult). p5 z8 R/ }1 I" v- N5 e
{
% E' y% z" W6 M q# t: h0 V ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
N! J: v$ S- u- `) w0 ~3 T! q1 U# l1 f/ T) l/ r: _0 d
switch (pEP->msg) {
: g9 L, v0 j8 q+ }. Z- P case WM_KEYDOWN://按键,判断pEP->wParam
5 Q4 M8 j) l: Q4 |) }% I% Y4 K case WM_PASTE://粘贴! L9 ~2 Z( K# `4 w- F
case WM_CUT://剪切
" G& ^3 O+ n) Y0 q case EM_SETCHARFORMAT:& L( m% [$ Y& ^4 h4 M$ |% l
default:
" T/ y k3 d- b$ D; H9 ? break;
) {0 ]+ l) u$ r1 l1 w }; l# Q" N% `/ G6 x
9 A3 C0 C% L; N( ?
*pResult = FALSE;
) d- {% H! j' D* L1 v}
; r+ L6 ?. @; E0 f1 H0 A# l3 E d
% r1 G( L2 ~, |+ z! j6 L三.聊天常用
, H3 b3 e8 T! Y+ Z2 J6 [$ qa.LINK 链接功能. S! A$ h, \5 j. {" q0 A$ q6 h
1. LoadLibrary(_T("Riched20.dll"));
1 {1 ^9 E2 V5 N; \, m' `( q9 u5 s2. 创建RichEdit2.0控件: g+ `5 _& T, g4 ~- w1 {( w
CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP4 P6 N, X9 Y: _9 z" Z k
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,; }$ B! q6 a( C. @/ G' v- B
rect.left, rect.top, cx, cy,
( U; t) [7 c5 r pParentWnd->m_hWnd, (HMENU)nID, NULL);
5 n) }* ?% N- M3. 设定选中的文字为链接显示
4 a; U, P) T1 l% I x, yCHARFORMAT2 cf2;. T7 D: A y+ ?9 w/ o( J
ZeroMemory(&cf2, sizeof(CHARFORMAT2));//
1 O3 E7 p" C1 `4 U& z* Hcf2.cbSize = sizeof(CHARFORMAT2);0 X6 }( v0 a+ P) a! X. B8 }; ^
cf2.dwMask = CFM_LINK;
; U, @" C2 `% q5 B+ ]( Wcf2.dwEffects |= CFE_LINK;
$ Y# l3 z3 W$ @; rm_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
, L i+ ~& y) A0 e8 f& r9 M! F, X4.支持链接的点击响应
3 t6 D6 R% g9 L" K+ a; cm_cRichEdit.SetEventMask(ENM_LINK);
$ [/ A7 S2 g2 ]( Y: V5.响应链接的点击EN_LINK2 R: R" M" u- q0 I% O
+ Q4 U: n/ y* Z: L# {BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
4 B7 Q" |! E$ X) d9 K7 U j, U0 kON_NOTIFY_REFLECT(EN_LINK,OnURL)
9 z0 Y, ^" ^1 ^END_MESSAGE_MAP(), k, y6 e) u5 [" J; j7 o4 \) d
......! f) G- E3 }# B- i6 H0 D
* F" m" K, v% o3 a) I! F
void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)% e) N$ v9 S/ H) \/ U+ |( F
{
6 c. ?. _6 p' E' r* X! \7 YTCHAR LinkChar[512];4 c( M/ m& O* d" |/ p! j
ENLINK *pLink = (ENLINK *)pNmhdr;# j6 [/ B+ q6 r' y& F* U! f; D- a
if (pLink->msg == WM_LBUTTONUP)+ C# j" y9 W6 _* s$ `
{
! w3 ^6 L& G7 CSetSel(penLink->chrg);//这是链接的文字范围8 Y) {5 g1 j/ [ c! R
long Res = GetSelText((char *)LinkChar);//这是链接文字
# N( m" x2 T5 g; Z //后面是你的处理过程
. r0 p/ M( M. [1 G ......6 o6 U+ P) P( V. K r N$ o8 Q
}
# p$ B. Q% }2 F, o* c}
; q% {" m4 O1 ?( r) E9 E+ E2 H9 S5 M! ~, O0 z' T$ ~0 w3 E) @! V4 b+ V
b.插入位图
0 i) }0 K5 Q: ohttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/ M. ?7 J D, y
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
! L% T5 i+ z6 t _- s/ c, m1 _( F/ R7 P/ Z- m b* ^' _
自定义在RichEdit中插入对象的图标- x9 e/ @' Z' ^2 i; L
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html
9 q7 `/ o6 q0 [8 D; `% K' T方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control* v) G1 }& L; n V+ H
只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
. E1 e% B D8 c1 y$ M
0 i5 Z J2 }% f) ^3 l3 ]4 K使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
5 i6 O% v0 Q# C3 U0 X. J另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
! u# Q+ c( ~( R. j# ^+ A( N( v1 _0 A. h
c.显示GIF动画0 s# W, W# d$ b7 l' f8 f6 Z! H
常用的是通过qq的imageole.dll(也有用Gif89.dll的)* s$ k; s4 O6 u5 O; h8 C; s) x f
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
' o N/ J. L, N: thttp://www.codeproject.com/richedit/AnimatedEmoticon.asp9 z) i- i; d+ w4 r7 \5 @
6 Q2 m3 _& ]( P J( @+ o' J) V* r% R
在richedit控件中插入动态GIF (Native C++版)0 S/ B$ ^% K& a$ Q3 Q$ ?1 z" Y
http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx/ k$ {$ p1 ~2 E: c J
M. B7 v+ C% g7 A( d
d.IRichEditOleCallback的使用3 v1 M7 z$ Q! `9 N# _
http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022
- M8 z! @9 n ~5 f2 b5 ?+ q9 b$ Q, }3 C( z# J$ l! L, w
类似 MSN 信息发送框的制作(上)
" o7 m" \ \2 `2 j9 zhttp://www.vckbase.com/document/viewdoc/?id=1087
. {0 M4 B( \6 d% g; F内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串* c/ q$ g6 T& o W
0 m5 E- Y) O9 P' ]" j$ Z自定义 CRichEditCtrl 控件
8 f( I' J% e' |3 Q1 t' zhttp://www.vckbase.com/document/viewdoc/?id=328
7 \3 [- |' S9 i; U( @( w5 q0 {内容包含:鼠标右键消息,消息映射,字体变换, }: y+ Z( y0 J7 F
, Y5 y2 I: [1 y* Y
PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
, V) U& T( d. v4 c. {& A是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778
' I8 \1 i) V" [. z5 P' s----------------------
; q8 M0 W ]4 b7 b+ z比我想象中还要花时间,所以最后潦草了点,见谅 |
|