|
|
一.常见问题
& v" u3 V$ X+ k$ O6 ea.可以编译,不能执行的5 V1 I1 A' r6 I
AfxInitRichEdit();
' H4 d- x3 f7 L2 }
: b6 L9 ?# h7 P0 zb.升级默认的Riched版本(默认的有一些bug),如$ P5 a1 s& {" M, x
可在InitInstance中添加" b0 P3 j/ X3 A: ^. f- Y
LoadLibrary("RICHED20.DLL")
& ~8 e2 F' g+ K" v* T/ h最后注意 FreeLibrary
) h/ N: P' z7 I6 u; s4 }" g3 A& P/ q# }0 [% p! Q q# P" L
如果是CRichEditView基类的可用0 a( G- }* Y, c+ m
BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
2 v# B0 X+ E) J4 R{
7 |$ n+ ~' U0 ] |6 e, h//装入rich edit version 2.03 e7 O1 J: `' K- K7 J$ m" X
if (LoadLibraryA("RICHED20.DLL") == NULL) f# B3 K! I2 T
{! y+ ^4 `) L9 A/ m8 N! s
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
9 V% e+ E( \) D1 G+ R& l3 i* VPostMessage(WM_QUIT,0,0);4 ~6 b! d- W9 Z) |7 i; N
return FALSE;
( Z" e/ n) F9 r, Y( U6 H}
0 B( v+ ] _0 Y N7 \; p6 |) A9 a! e/ P% C) c
m_strClass = RICHEDIT_CLASSA;//for 2.0 class- Y1 i3 G/ T+ R" p
2 T- P* A( v+ Y' j5 `. Z( l' H7 i5 Xreturn CRichEditView::PreCreateWindow(cs);1 b7 {2 {8 C, O- Z( U* E
}7 E, T0 n, y( t }! J6 c. m
3 n6 `9 ^2 d* V: G) l; jc.最后追加行
g2 b- j8 k9 H: X) aricheditctrl.SetSel(-1, -1);
$ o% P, \0 R( kricheditctrl.ReplaceSel( (LPCTSTR)str );$ l/ ^+ M+ l( w
: x3 a Q9 a. F: n3 {d.字数限制; J$ [+ d6 |2 F# t- S( o4 _ X% {
CRichEditCtrl::LimitText(long nChars)
; B2 n/ M. H/ b1 p a- [: I. D1 S1 r0 k3 c7 G/ A2 Z$ a$ z% l
e.换行切换# c) F2 y5 V, u8 m" x
CRichEditView的OnInitialUpdate()函数中加入下面两句:
/ I! g- H3 a! J5 @3 Am_nWordWrap = WrapNone;
' E+ R+ e9 \) v hWrapChanged(); : @7 w3 b& P8 \+ e# `( t+ J z9 S
WrapChanged实际上也是调用( H7 m* e1 W! p5 a/ l0 `& F, }
ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone; \, C) @ T; Y0 H" N
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow0 W4 R; ]8 l* U0 ~# e
还有不常用的 m_nWordWrap == WrapToTargetDevice
4 W/ {) L. L+ F* d5 ictrl.SetTargetDevice(m_dcTarget, GetPrintWidth());. v8 _6 P3 i1 S0 Y, q
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return! U) P9 ^. k( [9 k7 k, u- m
5 M6 _7 }7 o8 l/ m8 V% d7 E! p3 \
f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴9 b- ?7 u; c2 T7 ]
pmyRichEditCtrl->PasteSpecial(CF_TEXT);
# Z+ y6 q! ] O- D$ K, f1 A) n' [: w9 i
g.随着输入随着自动滚动条滚动到最后一行
# p4 b' Z- |; \$ Gint nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
& d( d' i! W: V0 W2 Jif (nFirstVisible > 0)
. O* @! J5 W# Y: E" L. F{3 I6 E2 s) |. c" X+ A# T
pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
! J7 L: ^' {+ @- ?+ ~}
`- ]/ f5 X: p3 u或+ g! p! G3 Z' u% F m" c' ^2 p
m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);
. y c: s& K$ D" Q: \, n
B% u- K( b2 O1 t" s$ S* f( L# k$ T
4 h/ m& F& Y$ |* u0 H- Zh.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
9 y0 u) r+ @6 Z& ySendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);3 C6 |8 [! z# {: H
TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
% n5 G( V( [7 q& s5 L! VSendMessage(EM_SETUNDOLIMIT,100,0);
7 v$ T8 _: e8 c
) u+ B% L8 a; ^6 {" P9 f$ wi.响应OnChange1 J Z1 Z2 `1 ]3 V& Y: P
EM_SETEVENTMASK 设置 ENM_CHANGE 8 d, Q1 f% ?3 A/ I$ l6 p
long lMask = GetEventMask();' p! t" M$ f5 j. D, r# A
lMask |= ENM_CHANGE;
* B7 v g8 r1 `. G' u/ K0 K+ mlMask &= ~ENM_PROTECTED;
0 e0 J" l' |$ G% u1 |- b! {SetEventMask(lMask);. Q! _+ @+ U! H! b" x
, O$ \6 ^2 d" E1 |" C
j.设置只读4 u; l: K' H1 G
CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );
+ {3 q( q7 @% X+ x7 Y6 @通过设置PROTECTED实现选中的文本只读,参见
. \/ g: g0 _1 P5 `' [http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
4 }* E: ^/ Q5 M) z! G2 Z
0 j/ y* S, R( K二.函数应用
; j4 p- _ A% V. g; oa.设置字体(主要是通过SetSelectionCharFormat)9 s, D; I7 L5 A, f$ m6 O
CHARFORMAT cf;# [; {2 m/ d O; _
rich.GetSelectionCharFormat(cf);
4 [: m& B! B8 x# V4 D8 C- Tcf.dwMask|=CFM_BOLD;
& [" P X/ f6 ]2 Qcf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;' j. I0 c# _5 h. {6 p( N; F
cf.dwMask|=CFM_ITALIC;/ }! t# G% F+ D; {
cf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;* z6 W2 w4 P2 f: \
cf.dwMask|=CFM_UNDERLINE;7 U; d0 P H7 V; f) f R% D7 n* Y9 a3 C
cf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;
9 {" q! }/ G @8 K7 ~7 o# L, Ccf.dwMask|=CFM_COLOR;( f# K$ H8 a! r
cf.crTextColor = RGB(255,0,0);//设置颜色$ J) S, v% q2 x2 G: n) j
cf.dwMask|=CFM_SIZE;9 k6 c# |0 ~, y) K9 R4 S
cf.yHeight =200;//设置高度% ]+ A6 y2 q7 p1 E$ S8 ~6 l* R' ?
cf.dwMask|=CFM_FACE;
' d/ f! l/ D8 x/ x2 R- cstrcpy(cf.szFaceName ,_T("隶书"));//设置字体
9 M& k: w6 F( E* R: \ E( f ]rich.SetSelectionCharFormat(cf);
7 k9 n6 d/ ^* _* h( g5 G
5 G2 S+ y ^ {7 N+ yb.设置字体的行间距
; [. o B9 s M4 \要用richedit2.0以上; R- v9 e, f( g' U
试试* y* b Y, z2 G: o6 a. b; K7 c2 E& l
PARAFORMAT2 pf;
; T3 U3 v5 O0 Q/ h+ z0 F8 ]pf.cbSize = sizeof(PARAFORMAT2);
- U- v6 s* b6 b1 g2 _pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
0 \* B4 E# \( a. t! H5 cpf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
( Q7 {9 w) c' S( Epf.dxOffset = 10;
' c! d0 J, [8 M* B: b( M3 B `- BVERIFY(SetParaFormat(pf)); ) L+ y5 I( {; T8 O( _
常用的dwMask有' Z$ l: G+ ^9 r, z$ P! G8 n B: A
PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
# b4 `: m( R3 C; n+ U2 使用阿拉伯数字 (1, 2, 3, ...).
c/ M" j1 r( f; j& \: F3 g3 使用小写字母 (a, b, c, ...).
3 p( p, U! t8 m7 \, G! x4 使用大写字母 (A, B, C, ...). 2 w! Y7 A1 a9 L7 `
5 使用小写罗马数字 (i, ii, iii, ...).
6 t0 H L7 B6 {0 H9 b/ R' F9 Y7 t6 使用大写罗马数字 (I, II, III, ...). ) H5 k1 ?. I0 e4 j$ N
7 自定义,字符见成员 wNumberingStart. # C5 ~0 _4 l' A$ Z0 j3 h+ p
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips1 g: P4 S: H- V+ I9 v# y5 |
PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进6 j$ k+ J4 B; f
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距: o- D2 C6 s; ?! K4 }; ~, E9 S
PFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距
6 D0 B& @3 p4 h& K- O! d+ M e# S/ N ?& ]$ B
c.设置CRichEditCtrl(2.0)背景透明 ; D5 W) g) Y; L1 h
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
5 u" g- [" Y( O( Nstyle &= WS_EX_TRANSPARENT;
/ i7 Z9 d# w% R::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);2 e) }9 O3 I! @+ A% K
或 CreateEx,然后把WS_EX_TRANSPARENT样式加上+ v3 a& L6 n% l5 s8 _( z( Y" Z4 H. P
. }( H2 V+ Q! a$ e3 ^
e.得到内容有三种/ N: v4 J9 c5 r/ X1 f0 B
1)GetWindowText
1 J' x& j( B8 I7 k2)使用EM_GETTEXTEX/ V! N. j( z- j2 k F; e7 A0 v
GETTEXTEX gt;
! [' Z$ v: M. O) T" T9 T. E, F# qgt.cb = 200;- q3 O; {; R8 Z4 c) u/ G' c
gt.flags = GT_DEFAULT;
; s! `, w4 |. [8 u2 |4 ^gt.codepage = CP_ACP ;
3 M4 _0 R# N7 G/ l8 z- U4 ]* Agt.lpDefaultChar = NULL;
4 A+ X5 H4 W6 W- A; x+ Sgt.lpUsedDefChar = NULL;
5 D5 h4 a$ m: o/ GSendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);" _% \4 E! Y/ Z& v1 s. S
3)StreamOut(主要用于RTF等格式输出)
0 |( t s# ]/ Q5 ~8 ]; t" Y& rstatic DWORD CALLBACK
3 ]! ^& S3 ~9 ]/ E' L; ]7 h( ~MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
) t# Z5 M+ l; S5 p{ z: x! \6 l' G G
CFile* pFile = (CFile*) dwCookie;
9 [5 c9 R2 X! B% ]) F3 ]2 w
, Z3 Q% U% ~1 A: J pFile->Write(pbBuff, cb);
3 Q4 `* e# B Q5 b *pcb = cb;2 }" `5 J, @+ m- g* H( w! m
$ R i8 W0 s5 o2 i
return 0;
& O: M' ]1 ?. V}; e( `4 |8 ?/ j& @
& K/ x1 t6 z1 f \$ y/ J# f
, x4 `( p; I9 K6 s4 b CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);5 ~4 \( j: J+ @' @& p6 z1 N
EDITSTREAM es;
2 x4 p1 Q* V+ t4 U# E es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用) J b- O1 P# A9 p; p Q
es.pfnCallback = MyStreamOutCallback;
, H: g) H# r2 i* ?0 B; b3 l1 X" X pmyRichEditCtrl->StreamOut(SF_RTF, es);& t3 }5 x) t5 E. `* b
读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn0 X5 Z, s+ m* F) r
, {+ ^1 x) j' E+ w# ]1 x- \2 m1 Gf.查找字符串4 i" D1 Q4 w6 R" H
FINDTEXTEX ft;
* |- s3 E' X R7 Gft.chrg.cpMin = 0;2 o5 R1 ^+ |: ~1 l
ft.chrg.cpMax = -1;; Y* g+ G% ~% ?% H
ft.lpstrText = "|";- H3 k/ A1 r/ b+ g( h2 N# Y( o
long lPos = FindText(0, &ft);
f W* A \, B3 |+ i' O1 a( O/ F/ J$ X6 o1 y/ A' s
如果要继续查找,修改cpMin,如0 p% G3 G+ V- z! y. Q
int nCount = 0;6 V7 d: w% K+ @7 G1 {
do
% ~0 R- g/ _ {# Q' K) m{
! R: D5 {! A8 H; }- G3 V long lPos = GetRichEditCtrl().FindText(0, &ft);- O5 ]/ G/ ] K3 n0 W- O1 C
if( -1 == lPos) break;
' C& X. l, r/ n( P4 [2 J ft.chrg.cpMin = lPos + strlen(ft.lpstrText);* a9 ?- @' Z9 o( ?: J- S8 Y
++nCount;
8 x2 E3 M L1 ]% P( l4 F6 x}while(TRUE);
. I2 d$ O+ K5 P0 v+ f( L, Q# ?' i- M/ C& N. z
g.以Html格式保存! e7 c4 z7 V, E, U T
目前做法可先转为RTF格式,再通过RTF-to-HTML Converter
# n' _/ \$ H" ]http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
. m- {/ Z4 N7 ^# H, S) H. V Y* e: e$ M+ `
h.重载OnProtected函数得到对应的消息,如粘贴等
3 Q9 M# U# g, B* B- Jvoid CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)" N. |% b% i2 t. `0 {# J3 {
{5 D ^0 I& }' Q1 O
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
' m+ t. o! t( v7 \$ y4 f- M* M O+ _: S
switch (pEP->msg) {
2 n- O: g4 G1 l* m! h" [% q case WM_KEYDOWN://按键,判断pEP->wParam( `+ g5 Q* C. ]0 t2 |- }
case WM_PASTE://粘贴. q; n4 B2 I- H3 R
case WM_CUT://剪切
0 H4 j4 K/ z) E; {8 X# [ case EM_SETCHARFORMAT:# @( ^. f: V9 H, V0 S9 p
default:
& u8 a9 m9 ]8 ^* K' Y, {1 ] break;' A8 ~6 e, `- O1 \$ L
};
4 j U0 ^# }5 @6 v
! G- C" a3 I& ^: k9 a$ l" j8 L( Z/ X *pResult = FALSE;
4 Y" I/ h7 ]9 L6 N5 i1 X# d}; i6 [$ W S0 \" R: g
6 f [* p `- ~% c# V三.聊天常用 5 G8 O0 y2 D' ~1 Q5 e
a.LINK 链接功能& }- O2 p7 I p; K/ e& A
1. LoadLibrary(_T("Riched20.dll"));
% Z. a' n3 N! @7 H2. 创建RichEdit2.0控件/ G( W3 s% J- V4 z! }
CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
4 w# t3 j" a. |8 M& w) ^' z1 W5 {7 ?6 U|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,9 d* {. G3 a. d- M0 p
rect.left, rect.top, cx, cy,% Y& w2 t& A4 O8 \) t: X
pParentWnd->m_hWnd, (HMENU)nID, NULL);
* y' P: s* J j" E8 u5 p3. 设定选中的文字为链接显示. h6 W/ A/ p7 X! F1 B
CHARFORMAT2 cf2;- v# J8 v7 G5 Y6 n) f/ n% g% ~1 \
ZeroMemory(&cf2, sizeof(CHARFORMAT2));//
6 s. i; U/ s* B! y" ucf2.cbSize = sizeof(CHARFORMAT2);
) g5 q+ Z4 r! v* xcf2.dwMask = CFM_LINK;
* r. f" d8 }# T; T* ucf2.dwEffects |= CFE_LINK;
: o! X0 Q/ n4 ?m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);% x. F2 m& N9 d" ^8 U/ C6 z
4.支持链接的点击响应
4 e# J6 k; X4 s2 sm_cRichEdit.SetEventMask(ENM_LINK);+ Z: Q# [) L T
5.响应链接的点击EN_LINK
/ d+ e2 E- N- B; [% ? g6 e! r" T$ b. J
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
) C9 R( H5 W9 H) y! \2 O3 C( {- S2 y$ Y) CON_NOTIFY_REFLECT(EN_LINK,OnURL); H. m3 Y; x6 L. i4 S G
END_MESSAGE_MAP()
5 c5 Z) o; L) w......
# p; e! w3 g% n, l
- V/ \" m- \* S/ r1 N1 h& ivoid CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
5 n" K! z8 Z: K! ~! }{: ?* d3 e$ e3 n/ I" F/ B
TCHAR LinkChar[512];
; K2 o( S9 ?5 u9 y) @& t7 LENLINK *pLink = (ENLINK *)pNmhdr;
" N# ^" G$ ]; B6 Y0 D' Mif (pLink->msg == WM_LBUTTONUP)
# N3 d5 u6 p# ?+ X$ S{" X- {) R" u/ d7 d/ L. w$ _
SetSel(penLink->chrg);//这是链接的文字范围9 W- `- z$ c& Z! p7 T$ R8 e
long Res = GetSelText((char *)LinkChar);//这是链接文字
; b" a2 P2 V0 a% @# G //后面是你的处理过程
0 Q5 H( y, h/ c+ z ...... K9 B. s( _9 v% a* \+ {
}5 P9 H1 w b* @% N( V {
}/ z2 x: f9 R+ E) \) `+ R1 O
- Q8 F+ |8 v1 Zb.插入位图3 Q d( D% U, ~4 M0 }
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
- P% a2 u/ j( p1 k8 Chttp://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/7 V$ j9 X m( D% u3 @9 @: t/ d
6 O0 }7 c% O2 G% J+ g+ x
自定义在RichEdit中插入对象的图标
: @. H, h9 ~! F) g) B9 a* whttp://www.blogcn.com/user3/jiangsheng/blog/1319738.html
/ ?: F+ A7 L! U3 g/ k2 w方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control o) l$ d4 n: v4 d0 O
只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片9 s+ D: F5 J% r2 R/ ^; s
8 }- U# V+ e( ]) M
使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。! G; A4 B$ \) v) f2 R
另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
/ c, ]8 F, l7 H6 x) }. v
. a2 l! k, ~' }# `3 zc.显示GIF动画1 V! I1 R4 W8 {: a+ \5 K
常用的是通过qq的imageole.dll(也有用Gif89.dll的)
4 g/ ]! Y% C3 |4 f4 X1 Vhttp://www.xiaozhou.net/cooldog/blogview.asp?logID=82! e# [' C6 S7 D: F/ m
http://www.codeproject.com/richedit/AnimatedEmoticon.asp1 i4 \( l1 {8 f* {
0 k1 @ R3 F2 c4 J' w
在richedit控件中插入动态GIF (Native C++版)
3 B* G. z8 A/ i5 G4 Uhttp://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx
n/ U0 N- u% y
/ P; K5 A H; @/ b$ \1 I( Ad.IRichEditOleCallback的使用
, s+ j" l0 c, ?2 Y# m4 }http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022! Z1 ?( P6 \5 L
. j7 Z: }/ \3 h& ~9 E类似 MSN 信息发送框的制作(上)
7 Q6 M: s* t) l) t3 W& c& zhttp://www.vckbase.com/document/viewdoc/?id=1087
7 ]1 ^& j/ z5 }. t& I内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串6 w. c+ g" G% I B2 n
. V. }* c1 F& G- q( o) q* i4 T
自定义 CRichEditCtrl 控件' E4 n! ?' L. S2 v2 P3 ?7 C8 \. V3 L3 x
http://www.vckbase.com/document/viewdoc/?id=328& k# C/ [* b# _/ @* i: u. V3 M
内容包含:鼠标右键消息,消息映射,字体变换; w/ n" n0 I9 j9 C1 \+ H
; k$ ]5 Q$ J" U- ]6 C5 QPS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
+ S+ g1 q3 \: r m; d5 O7 S" c是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778 - L2 [0 w1 r1 ?3 }9 n5 y2 d! J6 {
----------------------
0 z% {$ Z! K! Y5 y' d: Z1 a. |比我想象中还要花时间,所以最后潦草了点,见谅 |
|