|
|
一.常见问题
( Q7 q) D5 V2 @6 Ha.可以编译,不能执行的$ k' j2 [ P- b- {
AfxInitRichEdit();+ ?' U5 p0 w$ U
& }( e- E$ x- g$ N5 N* Cb.升级默认的Riched版本(默认的有一些bug),如# a7 k [4 R$ s9 Z9 ?
可在InitInstance中添加' h. t7 b' |8 F4 b0 D
LoadLibrary("RICHED20.DLL") ( Y( z+ R# c2 f) K" ?1 z% j/ M
最后注意 FreeLibrary% z9 a- Y4 c* M0 z! y/ l
5 q: M9 `3 M6 I9 r+ O' n- T如果是CRichEditView基类的可用
8 R4 o/ G% O' Z4 pBOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
0 ^9 k$ ]2 [& [' _' }" Q; J{. b; P8 l7 x& J; r7 R. b8 F
//装入rich edit version 2.0* [9 O$ P) `5 G
if (LoadLibraryA("RICHED20.DLL") == NULL)
$ p7 V- q; s, u* Q{) j! g. h! O$ Z! Q, v- M+ @$ O
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);% N& w; G, t, z j
PostMessage(WM_QUIT,0,0);
3 a4 u- x' D) u. h7 z- Preturn FALSE;
: f9 v' j7 R: f( d}
: |, t8 A: P8 O0 w
7 p# v1 K$ W+ t/ }9 R* `m_strClass = RICHEDIT_CLASSA;//for 2.0 class* m6 ?) F7 L7 w
1 K K- {1 w* I5 L# T1 p. m) u% Treturn CRichEditView::PreCreateWindow(cs);
* H, c. d% Z$ V0 O+ Q/ W% b}
. |1 q' l v) a4 z; h' ?4 g' r; E) s+ K( X" ~
c.最后追加行. m, \$ J) G C
richeditctrl.SetSel(-1, -1);7 y. ^$ x! [ ^- C/ o8 T
richeditctrl.ReplaceSel( (LPCTSTR)str );
1 e2 g3 r( m& T9 e" K7 d
5 c, B2 K' |$ {! r' E' B' U) W! _d.字数限制2 X' R* {" B, ~; D: @ r+ s' j. j1 w
CRichEditCtrl::LimitText(long nChars)% C9 U9 f- @& e7 H2 {& e
9 p6 f& Z; T3 h( ?/ ]e.换行切换
0 R0 y, U- [, f! ?5 G n0 wCRichEditView的OnInitialUpdate()函数中加入下面两句:' x* ]/ K |/ N. T0 x0 h% I: @; ~
m_nWordWrap = WrapNone;
g1 c; \& Z9 I# G' Z+ K bWrapChanged();
1 A1 }& Z! t% x1 E+ l5 |) dWrapChanged实际上也是调用
8 j9 G- L7 k: i9 S1 A. Actrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone2 B# z$ Z5 x( P) F3 x
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
( n6 l/ x1 h( o; }还有不常用的 m_nWordWrap == WrapToTargetDevice
* Y' }. `8 T' Z, t' `ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());8 c n7 y* `1 N+ ~6 W! V1 ?8 u, R
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return8 K" o% e7 J4 e* X" I1 l
S; ?( j( P- }. l8 ]# e, z- bf.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
4 N+ i! ?' p% Y2 z- I8 G' w" lpmyRichEditCtrl->PasteSpecial(CF_TEXT);! U: C' `( |+ b z5 N
& `# g9 ~1 v2 }' t1 bg.随着输入随着自动滚动条滚动到最后一行
8 T' l( O7 C3 z$ Z$ [" gint nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
! ^4 d8 Z, v& |if (nFirstVisible > 0); K& N8 M7 d/ D& i) y7 K8 m8 P" o
{$ c$ C; w9 z Y# K. O7 R% ^% V- e( S
pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
6 `4 j+ x2 J9 |- A3 w}
$ O6 @) l8 j8 |2 P或/ a* g$ e# j- h
m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);: v- c2 j4 z$ x
2 ]# [7 L6 u, p V- g7 \+ I6 N9 Y
; G+ G6 _9 B- D+ X% oh.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)! x' G% T' M7 F+ s2 r
SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
& I9 O2 `, B: PTM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数 + x* y- d: n- H, F8 g
SendMessage(EM_SETUNDOLIMIT,100,0);
5 |$ @. C2 f4 x: F4 R6 i$ Y. D7 t) U a( z& B
i.响应OnChange( _# t/ d4 L: j0 `8 B+ j/ P% e
EM_SETEVENTMASK 设置 ENM_CHANGE
! T/ J# }& p% d* I( @% A2 qlong lMask = GetEventMask();
# [* _# f6 H# T& l$ E$ SlMask |= ENM_CHANGE;, D$ H: G `2 H* D" o4 D6 n4 W: s3 D
lMask &= ~ENM_PROTECTED;
5 S! E( X" f, t% t6 XSetEventMask(lMask);3 l% n$ g8 S2 O U6 s! \' o! S1 A
+ E3 }* u* f- g
j.设置只读
/ a, t7 \) _$ B: \0 lCRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );& h" Z+ a5 `0 P% W0 k* B6 G
通过设置PROTECTED实现选中的文本只读,参见$ H& Q2 F, j, _9 h6 m5 [8 x
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/1 }- f) \- O4 E. E' U( h! t: D6 R p4 |
0 t8 t g) T* P; v! G0 p二.函数应用3 i& h/ ~0 V1 e' v% y
a.设置字体(主要是通过SetSelectionCharFormat)
" a: @7 q& l, H) O6 V% w @: yCHARFORMAT cf;
6 P* s( |% u# Y( ^2 z5 Yrich.GetSelectionCharFormat(cf);
) V: V7 I Q2 Xcf.dwMask|=CFM_BOLD;
; X6 |0 D* e! c( hcf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;# A# |8 _! }2 M" ~& O3 u
cf.dwMask|=CFM_ITALIC;
% `( L& S8 b0 zcf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
& T: ^5 } O% fcf.dwMask|=CFM_UNDERLINE;2 f4 C5 g% I8 A$ M" s
cf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;
X# g0 F4 B9 D7 j8 S; ^+ |cf.dwMask|=CFM_COLOR;
' ~( Y- X# G# J4 w% k! @! kcf.crTextColor = RGB(255,0,0);//设置颜色& r# U* A {* s* Y' V6 h5 B3 U% [
cf.dwMask|=CFM_SIZE;4 H# a# N' h1 v0 v9 A
cf.yHeight =200;//设置高度
- j1 {% ]8 b- K3 e- f6 Vcf.dwMask|=CFM_FACE;' l7 d% B/ Z. G4 y. [& m
strcpy(cf.szFaceName ,_T("隶书"));//设置字体* v) i# W% J( l+ M3 U% P. V
rich.SetSelectionCharFormat(cf);4 I( Y* ?! B/ K- V
" y1 S7 Z# v' ]5 _# i* ]
b.设置字体的行间距" s# n* ]4 d b( t" A9 N5 P
要用richedit2.0以上
+ \$ ^8 Y6 Z+ u/ X+ F( A试试
7 s! Y: T& h6 t" e" P5 cPARAFORMAT2 pf;4 U' G5 ?/ G) l, l
pf.cbSize = sizeof(PARAFORMAT2);9 p0 P+ M+ | ?' W" h: l
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;" T( U& _( n* i0 ?# [/ {
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING - h0 E# N5 l' _: ]* b
pf.dxOffset = 10;2 v/ E f+ f: \6 @, y( }# \, O3 x5 b
VERIFY(SetParaFormat(pf));
7 Y, x, Y. d% a- f9 C$ K; L5 p/ Z常用的dwMask有
; z+ u% K" X% p+ L qPFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET; I9 |) f% G. u" l. V
2 使用阿拉伯数字 (1, 2, 3, ...).
% m9 ^" _9 g$ e. D. b0 `. n, J3 使用小写字母 (a, b, c, ...). ) {1 N4 E4 a4 A& C) ^
4 使用大写字母 (A, B, C, ...). , A4 @: U4 e2 F, u2 V c
5 使用小写罗马数字 (i, ii, iii, ...). ; U8 K T2 r9 h8 \, V5 u
6 使用大写罗马数字 (I, II, III, ...). ! ], \( ^: a; `7 Z. b
7 自定义,字符见成员 wNumberingStart.
5 }# ?! H* g3 k, l/ V$ }/ B$ z+ J& aPFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
7 F, H$ |$ s5 Y# h8 C3 BPFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进
0 o$ F1 c, ~" u- A4 BPFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
& l% L1 V1 ^: g( _& d3 HPFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
& q7 m7 v& H# `! {: C) ~6 J4 r w& P( V% A5 d9 c7 p# F
c.设置CRichEditCtrl(2.0)背景透明
7 F" W% {5 ~: J4 l) ~long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);6 X2 g. A9 i3 y8 T
style &= WS_EX_TRANSPARENT;2 ]3 f: P' ~2 Y2 ]/ G' j6 n
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);, N% d6 |" \) {+ p: q
或 CreateEx,然后把WS_EX_TRANSPARENT样式加上
" R, D& f: c% m- ?0 u
. G7 M0 ^- H9 N5 Q0 de.得到内容有三种
# @; |, O* b: J! R+ F; B. `1)GetWindowText
, S: n8 G. f! l' n6 V' _2)使用EM_GETTEXTEX
) P* b) K7 ~* l3 k$ }GETTEXTEX gt;
2 m, \; n! y2 e8 vgt.cb = 200;! l/ W* i6 ^( Z h3 x6 w" k% X
gt.flags = GT_DEFAULT;
* p, x4 [% n. v+ h2 o! h I, Fgt.codepage = CP_ACP ;
1 w7 O' w( O! bgt.lpDefaultChar = NULL;
& R: i/ D# U- |% K# Xgt.lpUsedDefChar = NULL;
0 Q w- ?% p0 N& ASendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);7 p. Q; j$ U9 ~0 X
3)StreamOut(主要用于RTF等格式输出)+ G3 T V$ z3 v. j% A! T" a/ C, K
static DWORD CALLBACK ; S5 H9 s5 m' O( n
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)1 K9 J7 Z; q0 D% y1 K6 o9 d
{
, m, ~2 f2 M2 I# O2 Z$ Y& } CFile* pFile = (CFile*) dwCookie;! Y( U( s: c% B$ S( N' d
# `! M% {! j/ g9 M# T
pFile->Write(pbBuff, cb);
5 D9 O, T$ s/ o% Z *pcb = cb;5 {2 N+ Z4 S% l/ d
6 K3 Q; s: ?5 L6 A9 [
return 0;: l3 V0 b% n9 R- v
}4 C0 A1 t, ?8 Q, z+ m4 k8 E( f
( E5 [" e' L/ {. Q% ?1 c8 w- O( \
/ z! J3 q, P8 s1 u7 K, f
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
& T9 h! ^4 d) ^; [( x X) j EDITSTREAM es;
$ }" l0 P- Z( R, Q es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用& ]! F5 D- g2 R: `1 z
es.pfnCallback = MyStreamOutCallback; # W: [ k( d+ n8 T" n) s; C
pmyRichEditCtrl->StreamOut(SF_RTF, es);
% A$ @4 s, C) }5 U/ Y1 T读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn8 A- S( S6 D* N% s2 _
0 X% Z! ~. P1 V& \( Cf.查找字符串
# R' Q+ | P n% Z1 q2 kFINDTEXTEX ft;
0 x$ M0 x- V5 \& uft.chrg.cpMin = 0;& |" L, \. U: ]
ft.chrg.cpMax = -1;, H' c1 @ ^$ j8 L* }6 S
ft.lpstrText = "|";
; t+ r" S+ U5 g- x; r4 Elong lPos = FindText(0, &ft);4 W$ C2 u- |8 X; r' M
3 I$ P }5 ~1 j; i8 a) r4 \) Y
如果要继续查找,修改cpMin,如7 p3 i: p) Z! v5 q6 t3 e
int nCount = 0;1 B4 C# J6 I9 A0 b& f
do' M }1 h2 c& b/ O
{
; I- l. Q& E$ g" N long lPos = GetRichEditCtrl().FindText(0, &ft);
0 b+ ]6 V8 i- ?) i; G! t if( -1 == lPos) break;
' a$ ]$ c6 o# D7 k- u ft.chrg.cpMin = lPos + strlen(ft.lpstrText);
/ \. b! U$ ?: ]% f# r ++nCount;
) n+ ]0 g5 {4 r) e2 N* z0 ^2 b}while(TRUE);
+ l9 }9 l- l C! q( T; `
. F0 d9 }, C8 o& o1 ug.以Html格式保存
2 P% b" R4 p: ~( \+ }$ N5 `' e6 d# N目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
% |# E( I F/ Thttp://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
1 d! |' U4 i$ d5 n x* D5 z# `3 u6 j) H' o" ^ c' r/ t' `5 s
h.重载OnProtected函数得到对应的消息,如粘贴等9 H1 z j3 J; k( J8 N
void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
0 S w4 i+ u8 }6 ]3 R{
7 s1 j, o6 Z. U" { _ ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;6 D; V( V7 E8 T. j( V( g
3 n$ P6 j) r' G0 X4 d switch (pEP->msg) {
; u" U7 q- r1 [3 q; D case WM_KEYDOWN://按键,判断pEP->wParam( |* J7 j! I. a* n# M. {9 v
case WM_PASTE://粘贴
+ \* y' n, l: k' t case WM_CUT://剪切
) z+ \$ {( E$ }6 z/ l6 o case EM_SETCHARFORMAT:
% [2 I) t2 F0 X, j9 I default:; ~. i/ ]8 f, C- l- v5 O: K
break;
- v, F$ o, N S8 i6 f };
8 h8 C8 _" r5 m& g/ p- `
5 J, }5 P& n. Q. A2 B* m; g *pResult = FALSE;) ^3 L7 q$ a- ?; Q/ P
}
" `9 E: G9 d6 a7 K8 |- f0 R0 ?* n2 B |! G
三.聊天常用 9 P, V- r9 x X* T5 E, u* a
a.LINK 链接功能
: W/ b! G# {! a& |5 F" L2 O! b' C1. LoadLibrary(_T("Riched20.dll"));# g1 k+ x, W& e# ^) D
2. 创建RichEdit2.0控件
% G; c/ i J6 Z0 l: e/ d5 d' y/ k CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
" r4 Z3 r# j6 ^|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
4 x" X, L; }7 U( Y" m& o8 z6 Y rect.left, rect.top, cx, cy,5 L% ?. u4 W3 \
pParentWnd->m_hWnd, (HMENU)nID, NULL);
- N% Y1 I+ J. D3. 设定选中的文字为链接显示
/ k+ L3 f% @4 ]! g' `CHARFORMAT2 cf2;: g; A+ U& K, p
ZeroMemory(&cf2, sizeof(CHARFORMAT2));//: I0 c; X$ c/ s) k9 C- }0 u
cf2.cbSize = sizeof(CHARFORMAT2);9 w3 J( o6 M; h) {0 @
cf2.dwMask = CFM_LINK;9 f' i$ U$ u2 O3 B( Y6 Q4 g
cf2.dwEffects |= CFE_LINK;! i$ J1 C0 X8 D: V9 y+ g
m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
( t S2 [) {# q. v/ T0 S$ P4.支持链接的点击响应1 b @+ ^) a/ p+ s, }; i+ R6 I
m_cRichEdit.SetEventMask(ENM_LINK);' L8 q3 f# d: y
5.响应链接的点击EN_LINK5 c6 E, f1 }2 G4 t+ }
; A6 J0 `) z/ ~. c. l# ?. dBEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
/ W* P$ J3 |, BON_NOTIFY_REFLECT(EN_LINK,OnURL)
- e# x7 o$ x* B& m' V' h! iEND_MESSAGE_MAP() w; v o L/ b: M3 E% [+ i
......
1 `. B' w' _( A: K" v3 K/ I- D9 m& A' S8 b8 ~2 Q; n0 u
void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)' Q1 S. Z6 ~5 _) W, G* a6 {
{7 ]' q8 l% E0 d! L& Z
TCHAR LinkChar[512];* ~$ |9 L# L+ z" V# c% E
ENLINK *pLink = (ENLINK *)pNmhdr;
5 s& z( z# R! p$ c; gif (pLink->msg == WM_LBUTTONUP)
1 Y8 u1 { [3 o5 g6 u, K{
7 Y: y" m+ S- ]' }# Y7 Z t9 e! JSetSel(penLink->chrg);//这是链接的文字范围$ u: @; }! g' P# I6 L k( c: k" g. Z
long Res = GetSelText((char *)LinkChar);//这是链接文字% J2 W4 a$ J, T X
//后面是你的处理过程1 v1 o& t0 I0 b* W
......: e* B1 _2 ~& j& G& }9 n& ]- s
}
% k! f9 M9 G8 U4 X+ i3 T1 p}
# k) D2 W0 z9 N! B# t
1 |2 W4 S+ G+ \b.插入位图( C& M' x* }3 V; m
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/ m9 I! D4 g/ }4 ^7 i' O- u- X
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
1 t1 D, C# ?, u4 t1 d' x
# a* r# O5 W5 e3 x% C4 a0 f _自定义在RichEdit中插入对象的图标
7 v( @2 k0 k- h. p, z' D. ihttp://www.blogcn.com/user3/jiangsheng/blog/1319738.html
& @! \) ^8 n% f9 n8 F" b- ~5 M方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
1 K) C9 g# O& p; ?6 ^只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片; T! i7 {$ ^- m
* V/ p7 F& M# \: L, {. r# m使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
4 ^ Y B9 a/ _3 h) a: u5 }另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。 : U* X w7 A" g8 H# t
2 }$ C2 \0 [: \. u: S1 |
c.显示GIF动画" u- [. u# z3 \( a& U
常用的是通过qq的imageole.dll(也有用Gif89.dll的)8 B# a. J: e( A0 w
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
- k$ x: W! y- P" fhttp://www.codeproject.com/richedit/AnimatedEmoticon.asp: ?- W' Y# q$ Z t* @9 y
0 D+ b& ], Z3 Q) N9 ]* k
在richedit控件中插入动态GIF (Native C++版), e; D, b" @; R1 ^- H! {
http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx! f0 w6 l% N U0 L: ?& q
- u* X. i: q7 {, Gd.IRichEditOleCallback的使用 I) w5 y8 S0 k1 |2 a
http://61.186.252.131/Expert/topic/905/905844.xml?temp=.83790228 J: }' Z( E0 s% O+ ?4 a
/ V$ z5 o9 L# b2 u1 b
类似 MSN 信息发送框的制作(上)
6 ]4 i5 @# j4 Zhttp://www.vckbase.com/document/viewdoc/?id=1087& ^+ h) H' {$ C0 S, C+ k
内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串6 Z# U6 c2 y# ^2 T- H
8 V0 y+ T* H. [: |6 `2 p
自定义 CRichEditCtrl 控件
& r: b2 D9 O1 g" Hhttp://www.vckbase.com/document/viewdoc/?id=328
, E) U2 K3 W3 O; @- s$ x1 R内容包含:鼠标右键消息,消息映射,字体变换
x/ A6 p# K: g3 p: a+ R' N5 }7 G% r# \; }
PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
! [5 J' {6 q6 `& g是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778 ( ]# s5 p( L( D5 o
----------------------8 Z" U+ N+ V8 B( @( Z G2 l
比我想象中还要花时间,所以最后潦草了点,见谅 |
|