|
一.常见问题. e& `7 c. F1 Q% S
a.可以编译,不能执行的
6 C/ }: f1 i) o: X. [; M6 ?: NAfxInitRichEdit();
. ~1 {' M9 X& G7 P( x# q4 R: S" |1 V7 r% b) K: S
b.升级默认的Riched版本(默认的有一些bug),如
* M4 s z. l/ G& Q9 v可在InitInstance中添加
4 Z/ y$ c5 M$ Q' P! L @LoadLibrary("RICHED20.DLL") : V# d! j, |" ]8 m9 [5 G
最后注意 FreeLibrary6 r3 |: ^( R" _1 P2 ^
; n+ v1 |5 ~, i- N# X5 n/ I( b# j如果是CRichEditView基类的可用! h' E0 s3 |& i9 z3 {
BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
* ]9 H m0 S2 i- ?0 S* x{0 F( L& o V' \8 g1 G M
//装入rich edit version 2.0) L C9 C# z" F4 j9 A7 x; w
if (LoadLibraryA("RICHED20.DLL") == NULL)3 ]+ I( z% G) V6 P$ j/ p0 g* `
{8 a" r8 ^8 l |4 J0 I
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
5 j: F A& x, ePostMessage(WM_QUIT,0,0);# e" x+ @2 ?2 T s5 w
return FALSE;$ j( S9 ] B* C8 w/ F2 s0 d
}' \% C8 w0 ` k# r- u
. z( @, T/ V: d# W* rm_strClass = RICHEDIT_CLASSA;//for 2.0 class
. ^+ ?: w1 w( [/ Z* u" S }/ d; b ]5 J; P$ L1 L
return CRichEditView::PreCreateWindow(cs);
& B% q. n6 |2 ^9 m6 m# c8 ^- b}
5 @, }+ a8 O/ y" A! X9 ?1 x6 h9 o5 A7 z( E
c.最后追加行1 L F# z. k( F6 T I
richeditctrl.SetSel(-1, -1);& m" e1 ]3 ]+ V# }% C+ z1 ~# x
richeditctrl.ReplaceSel( (LPCTSTR)str );6 M, l6 v5 S2 e% t- c
' q+ N, m- V1 h2 u: W; N
d.字数限制. Z g+ n4 C+ x( \, G' o7 V4 a0 [
CRichEditCtrl::LimitText(long nChars)
) g( Z2 O6 u1 _7 ^* I' Z# t- ?6 J' w8 }9 h: Q4 L0 U
e.换行切换
5 k! \" X4 C+ W" o7 SCRichEditView的OnInitialUpdate()函数中加入下面两句:/ G" u+ h- [7 D* w8 A
m_nWordWrap = WrapNone;7 | K! r" C' X" i& z0 S( D/ M9 R8 K
WrapChanged(); 1 r \* `- o, W6 e; z, m v
WrapChanged实际上也是调用
' m6 A7 y! x( q& u- S$ zctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone+ ~3 v" {1 u3 \0 {0 s- d/ [
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow5 ]& h: j/ R2 A) i- Q
还有不常用的 m_nWordWrap == WrapToTargetDevice
# r C" w+ `9 C& I! k" s# y9 Vctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
# r- z, a4 L' l' s如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return
. m1 f% T; G( c8 h' O
. g( J/ x! [0 ~# {7 M# f3 Yf.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
% B. u1 i8 _! x( H8 q! G0 apmyRichEditCtrl->PasteSpecial(CF_TEXT);6 T6 R' r8 }2 Q6 ?4 R2 S* j; t
7 |- J' h( n. `; T7 Z3 X! k
g.随着输入随着自动滚动条滚动到最后一行4 Y0 @" v5 l1 g( [. j: m! Z
int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
9 Y* H% h! [. h' b2 \7 aif (nFirstVisible > 0)8 ~% f& ~4 y: A2 R( Q* U# e
{
) q, O; Y7 v0 Q1 h5 w pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);# p, L+ I, A5 r- T
}4 p$ B* l9 O, W# f
或( d0 p; V" P2 {' B
m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);' k, x9 i# I- P& T$ O
6 j5 D# v Y1 v0 B" Z; F
* T. e4 F& M$ R/ ]; {h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
* z% Z1 v. ]0 W: NSendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
& M9 ~ o5 K( ^3 |3 {% B3 P6 `0 wTM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
, J4 _( ?/ o/ f5 `* ]. p; NSendMessage(EM_SETUNDOLIMIT,100,0);/ t! ]7 h2 |* j' t m4 J
7 v4 g9 ~3 Z! F1 \' c7 A$ Si.响应OnChange
* S l) f" e/ tEM_SETEVENTMASK 设置 ENM_CHANGE
' ]2 n9 Q2 X+ p4 j+ q A ?+ o& Clong lMask = GetEventMask();
2 M1 B2 S+ v; `3 R0 K5 Z! PlMask |= ENM_CHANGE;' [2 o5 j& t2 A- l
lMask &= ~ENM_PROTECTED;' R3 B* K! H* e5 N
SetEventMask(lMask);
3 j2 h6 x! V1 Y* W7 z3 D4 v/ ~2 \* R8 S% g* T% q! s; I
j.设置只读
! S' }2 |) Q# v8 FCRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );, z1 R# F% x8 u- x3 r9 H
通过设置PROTECTED实现选中的文本只读,参见
2 i, }+ k5 d$ F! J5 U& Uhttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/# W8 X4 m) {1 T# j- L3 k8 D
( [/ Y! G7 S9 V, d! D二.函数应用7 z3 `9 R2 P% ~
a.设置字体(主要是通过SetSelectionCharFormat)
. p& F' c- v' i- MCHARFORMAT cf;" W: x( o0 j/ T6 o3 m3 f
rich.GetSelectionCharFormat(cf);
0 ] l: T& K* @cf.dwMask|=CFM_BOLD;
1 a1 N! Q4 K7 y" }( {2 wcf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
$ |: d5 ~* M" n, kcf.dwMask|=CFM_ITALIC;
! v2 F! A, r. I& Y+ W+ r8 ecf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
2 k3 M9 F/ ], T/ W" wcf.dwMask|=CFM_UNDERLINE;0 @* h, J3 ~( R! }6 ]- {
cf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;6 | K6 }9 Z- R& U% {) O9 g
cf.dwMask|=CFM_COLOR;" g0 X& p6 x, _
cf.crTextColor = RGB(255,0,0);//设置颜色
$ G; q5 ~0 X0 z: ^, c6 Icf.dwMask|=CFM_SIZE;
3 V+ ~5 o0 v% P% X8 ocf.yHeight =200;//设置高度
+ e: B8 t! a# {1 Dcf.dwMask|=CFM_FACE;
0 [' ]6 o0 ^: s6 ~+ ?3 Wstrcpy(cf.szFaceName ,_T("隶书"));//设置字体
! l' t4 Z# s# }0 A2 Q4 h; k7 [rich.SetSelectionCharFormat(cf);# t0 t! |) P& d) m1 g) U8 k. `
; S, L8 B# X- [- y* gb.设置字体的行间距
" z' {! M& ^! H: G* Y8 w% w% s要用richedit2.0以上: L& N8 A0 Z+ l4 A
试试: @' e; {6 j+ i0 c9 Y; V
PARAFORMAT2 pf;5 G# Z' o o( J$ t8 A
pf.cbSize = sizeof(PARAFORMAT2);' Y/ |0 L* Q8 L2 z; k: [8 B9 V
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
! }, {% e4 n* R2 D% G V% k" gpf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING " O3 m: z* m+ W9 K5 k
pf.dxOffset = 10;
- M* K5 @, t; _0 I- o! Y$ h; }0 AVERIFY(SetParaFormat(pf));
9 C: L: G% @6 P4 \常用的dwMask有
7 M% O2 c8 S W! HPFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
/ @ w0 J2 |. c3 A- I2 使用阿拉伯数字 (1, 2, 3, ...).
. G* _6 x: K( W! j- c& t3 使用小写字母 (a, b, c, ...).
7 O$ p# e1 D, R, V b4 使用大写字母 (A, B, C, ...).
7 l- W( p k" [5 R* {+ s8 _7 P2 ]5 使用小写罗马数字 (i, ii, iii, ...).
1 C6 t+ a* J+ J" y6 使用大写罗马数字 (I, II, III, ...). 3 s* X$ W V% M
7 自定义,字符见成员 wNumberingStart.
" P) I. Q: \7 s8 T4 F lPFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips% h* ~" W$ E @8 f' I, g/ c& D
PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进! j9 n3 f. g8 {- X
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距, ]6 n+ G% a9 o( [- I
PFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
/ o R, g, l0 T
3 k. x) [- H4 Q4 Uc.设置CRichEditCtrl(2.0)背景透明 % e& G: k7 I7 q o5 D0 a- g- ?
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);* o9 A$ P1 U- K! V7 `$ P R' m$ M
style &= WS_EX_TRANSPARENT;, b* h$ l( |: ^
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
; h ^. W& r6 ~或 CreateEx,然后把WS_EX_TRANSPARENT样式加上: w; N5 X( P; X" T+ w
& D# F6 M; y; ^/ q7 m# G' q5 We.得到内容有三种
8 u% x1 C9 z( |# e" Z" J1)GetWindowText
" B& m; u0 a1 V( G7 P0 m/ s V, u2)使用EM_GETTEXTEX
+ Y# E1 N1 x' NGETTEXTEX gt;
2 M, l* X+ A7 D; d* X0 ggt.cb = 200;) \' w' M( m8 x
gt.flags = GT_DEFAULT;
: P+ ]# ~# C. f& [3 o7 Pgt.codepage = CP_ACP ;$ V, y& b1 m2 a" |; b) c
gt.lpDefaultChar = NULL; ]( W7 f( O) Z. `" y0 b. p$ }; u* F
gt.lpUsedDefChar = NULL;
! L/ O. k6 f/ |( o fSendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);/ }6 c# `3 B/ U1 p1 p- i* R
3)StreamOut(主要用于RTF等格式输出); o% y; j7 \* [) j5 z% M- d$ h
static DWORD CALLBACK
$ W, I9 l3 ?( a# G6 Z. QMyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
8 m/ `; {6 O/ e: Q{
$ R7 p* G/ [9 m, a o, P7 K3 ? CFile* pFile = (CFile*) dwCookie;- }; a9 E5 z2 D5 S7 [
$ e% |9 [. E l pFile->Write(pbBuff, cb);
9 ~, J. t n4 p& e* [& h *pcb = cb;
- u Y% o% p7 d. {% T: Z; k0 w: b1 {; k0 l- d1 i
return 0;$ n$ D; s! ]; q Q9 a
}/ v9 w" P+ \5 I
" m8 ?( D/ N2 J1 a5 e* L, T
7 |0 L2 F/ A! R: g% X
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
* z5 @ y2 k, G, Q7 I& w EDITSTREAM es;# b% O' [! b- `0 g( o
es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用! f- ~# x3 J. I, k. \# k" e2 e
es.pfnCallback = MyStreamOutCallback; : b* e& Z2 K W/ u0 }4 P
pmyRichEditCtrl->StreamOut(SF_RTF, es);
- x0 U. s" c0 \+ j读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
, I9 g: R* ]9 V* i! q% F
$ U, j* p1 B" S& K6 e' c( Nf.查找字符串2 k! |0 m3 b6 u2 ]7 Q& j
FINDTEXTEX ft;- w+ X: o1 y1 a* y& d
ft.chrg.cpMin = 0;! j$ A3 `; h* L* ]: d' _ m8 a/ l
ft.chrg.cpMax = -1;, |/ Z( w3 t. }3 \! u1 [2 @: Z
ft.lpstrText = "|";
- `7 b( D2 H+ v4 |; m2 s T! Zlong lPos = FindText(0, &ft);& G5 O; Q* n# t
* e2 g6 j, S p8 S- B如果要继续查找,修改cpMin,如9 @% b& W! [6 m; H' E: A
int nCount = 0;
R) T; O/ d8 Y& C' ]do
" F8 W. ~1 M# k4 S g3 r. _* V& B{
" z! G# C) ~8 A& h& [, Z8 t long lPos = GetRichEditCtrl().FindText(0, &ft);+ H1 d' s/ h6 W0 W2 }, E
if( -1 == lPos) break;
t3 @$ p. E' c$ U! o ft.chrg.cpMin = lPos + strlen(ft.lpstrText);
" S6 u; D! B- Q6 r: l# ?( L ++nCount;
3 V+ u# x8 V- ?1 d& c+ D}while(TRUE);6 _# ~, D; l" Y& a8 d
* j3 F. F: n0 z2 M8 Ig.以Html格式保存
5 Q) a& h2 @, U* s) K% w目前做法可先转为RTF格式,再通过RTF-to-HTML Converter( K; p, Q) S# a- a1 |
http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/: v4 q1 z! s4 K4 A$ {/ z" ]
- `0 \, Y9 A) D$ K3 X0 Ch.重载OnProtected函数得到对应的消息,如粘贴等
, y/ E/ f/ v+ l7 Fvoid CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
) f1 I7 H- m) U% R* g{9 }( t0 V- r5 O; G1 n0 C- W
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;8 w1 E; j. z& Y; @' w6 R, n3 d
( z0 V) {: D' m1 A# n$ \
switch (pEP->msg) {
# m8 n. n+ T6 c+ C case WM_KEYDOWN://按键,判断pEP->wParam" }+ C! k& p( X2 s- j: ~! C1 ]
case WM_PASTE://粘贴$ o% s/ x( S) I
case WM_CUT://剪切' @* C3 _0 i9 W9 G
case EM_SETCHARFORMAT:
' T$ s0 m m, [9 r, F( H Y4 p default:8 @) u& w2 o6 R6 D4 X
break;% i9 C( ]1 k: Q
};
! Q+ w% y0 r, X6 W: z7 G, @+ B+ p
6 j7 b2 l. B! } *pResult = FALSE;
* I9 m( p" t, _5 b1 `% l7 J}6 D: W. Q* G; u6 Z' H6 Y& ?
0 [$ o% I: v* C) h/ j三.聊天常用
O/ o" F3 ~+ O- la.LINK 链接功能& h: A/ W4 T* D4 b8 r
1. LoadLibrary(_T("Riched20.dll"));+ o; N9 | \8 d9 D4 v
2. 创建RichEdit2.0控件
2 h% n; V/ M5 n a% _( O7 v/ l CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
3 @' }' \1 |5 P l5 A [! c5 _5 \) t7 ]|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,9 A, V b* J7 Y( U. a& N8 {0 P
rect.left, rect.top, cx, cy,/ ~, s* z9 u( s, z% P; U! H( U6 l
pParentWnd->m_hWnd, (HMENU)nID, NULL);
5 C7 O( A2 J$ [# A3. 设定选中的文字为链接显示
& \% h2 m$ a4 p0 w) \CHARFORMAT2 cf2;
; b# \3 q+ x% pZeroMemory(&cf2, sizeof(CHARFORMAT2));//
- T% R# s) `; B" @* A) [cf2.cbSize = sizeof(CHARFORMAT2);% b8 Q, {2 u& y- _& b( u
cf2.dwMask = CFM_LINK;
& t b$ \9 u' l* \' Ccf2.dwEffects |= CFE_LINK;
; |$ U. N. E! X6 T2 y% v/ `8 rm_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
7 n$ _, T' n5 c' q6 `6 U2 q5 ]. [4.支持链接的点击响应
2 [, }4 S: W: M+ ^; Im_cRichEdit.SetEventMask(ENM_LINK);
8 n. d- t" M: U5.响应链接的点击EN_LINK
) p, s- \9 }8 ], e2 d
+ k2 c b8 l! L) e: Y Q) \5 V' `0 I) HBEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)# w1 Q0 ?7 e; H( I4 [, \
ON_NOTIFY_REFLECT(EN_LINK,OnURL)
0 `! W) y! I- CEND_MESSAGE_MAP()
5 X9 I+ [/ C8 A: x" z) p( K" d......
$ d8 s D; d$ E2 h: ^# F
- z( U5 [3 A9 G* X. `5 Hvoid CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)% L5 _8 Q) g4 a
{$ m" M/ N) k% D& L9 X! m
TCHAR LinkChar[512];
3 E. b7 A- ?' p; T3 m H9 ?8 QENLINK *pLink = (ENLINK *)pNmhdr;% w3 g$ Y4 ]* C8 z* X& M
if (pLink->msg == WM_LBUTTONUP)# [& F8 J# b# U- s6 y+ a6 G0 B
{
2 d$ r$ f: Z% f1 Y6 i+ d% \SetSel(penLink->chrg);//这是链接的文字范围* b; Q$ x' d/ M* y9 \; `
long Res = GetSelText((char *)LinkChar);//这是链接文字
% ?- B9 u* @3 l& `) O: b //后面是你的处理过程7 T# S. p' @& Z) z* N
......( e. N. x) V9 S/ ^2 F/ N% \2 ]
}
# x6 v& O: N4 z- a5 s}
+ l) l3 n4 ` s9 V# K' W6 D
* k6 @; ]6 J z @! Bb.插入位图
% B( v+ e, v4 h( D$ q. N- K; @http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/' a" Y; F2 x" b+ W" t2 ^) i( I+ e2 p
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
3 Z% {9 C9 p1 G# t" E) ?5 c0 \$ U" @# F& {
自定义在RichEdit中插入对象的图标, C( T' o1 w, [& q" [7 Z0 [* ~- F
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html
4 |1 X" J2 B* U( R方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control; N, i$ X- M6 s
只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片
: X- v: R1 T3 l- I: V6 S$ b2 o; ^+ U% V8 A3 A2 b* c! B
使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
2 d1 c: X, S+ D$ y) P/ [% p0 X$ n" u另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。 6 O( `; s1 N; ~2 Z
; X8 A" J/ N9 [# [
c.显示GIF动画3 f6 {4 P7 N! i7 G. u* @( C0 P
常用的是通过qq的imageole.dll(也有用Gif89.dll的)
2 J4 w$ k! R* g6 f, ?* I( p6 ]http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
9 {6 X' W( _- d$ a! V" ehttp://www.codeproject.com/richedit/AnimatedEmoticon.asp
% ~, G7 c7 Q$ ?: P8 l7 h' V, L9 n! }+ c8 c
在richedit控件中插入动态GIF (Native C++版)
" D! s' O. ^% ^' L2 S/ `# Shttp://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx/ }+ I1 G* u# C( |* u; j- H
8 w$ ?! }1 [( ?4 B
d.IRichEditOleCallback的使用
n- W; r, ^% U6 ^4 e! Bhttp://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022+ y' L% }& C x' j( m6 e
/ a8 n5 s, C; T5 c类似 MSN 信息发送框的制作(上)
7 g/ T) S! ~, r- V9 ihttp://www.vckbase.com/document/viewdoc/?id=1087" O/ W6 y- d( T* d$ c3 B2 w
内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串& {; ]/ Y# ~2 @: I" \, o" m: s
/ C* ~. T+ v y+ {3 P
自定义 CRichEditCtrl 控件
6 W( q R7 P+ y2 I3 ehttp://www.vckbase.com/document/viewdoc/?id=328
; H8 r4 ]% n f* F5 Y! |内容包含:鼠标右键消息,消息映射,字体变换
& v# U# b, W, e5 e* {. m4 O' p3 s; V1 s4 u# n
PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
# k( ?+ ~* R. T: f) G P5 l是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778
) C3 ~1 P+ y9 g----------------------
- \$ d4 P* f4 t7 r3 N: A比我想象中还要花时间,所以最后潦草了点,见谅 |
|