|
|
一.常见问题" x% f6 A* J+ U9 f% Q/ a3 a
a.可以编译,不能执行的
* b3 n* _+ l$ [9 U9 a6 y2 v# ^$ kAfxInitRichEdit();
4 g- N$ }, }8 X1 t
3 I/ B, B6 ^7 a4 p4 j2 S/ {0 Wb.升级默认的Riched版本(默认的有一些bug),如# g" H. L. x$ H$ G3 b
可在InitInstance中添加
9 S. ~; @4 z; l, U, G, jLoadLibrary("RICHED20.DLL")
3 C0 L; C* W$ s% G最后注意 FreeLibrary% g; s$ C9 t. d/ f, a% `. w
/ ?( L6 _/ U/ X# B
如果是CRichEditView基类的可用
- ?6 a! H1 y. x0 o" i2 l( {# EBOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)) }0 k' S+ h. w$ C% T
{2 D, B/ ]. \7 j8 p* f8 V7 b: g+ J
//装入rich edit version 2.03 i* U; ]$ T( M6 }* R- J
if (LoadLibraryA("RICHED20.DLL") == NULL): ^* L* Q; M" L9 ?* G( a. L3 d) o( Y
{$ g' Y4 B! t. o: y% C* @- c6 [
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR); g' S, m9 \: F5 X4 x
PostMessage(WM_QUIT,0,0);
7 G8 a4 P% [8 A' Zreturn FALSE;
; N8 v2 Y" O G( T! ?}4 r3 O) ]5 @- G* d
" r- f" o) I5 p9 f
m_strClass = RICHEDIT_CLASSA;//for 2.0 class
5 P8 k3 f- I. Z( L
' ]4 J6 N+ v. e' e# s# Lreturn CRichEditView::PreCreateWindow(cs);! H6 k5 H* F" c+ ~
}5 E+ J, z# Q+ \) P7 e7 g) _ Z
5 S/ ]& d: U8 N3 B1 z3 {4 mc.最后追加行! ?: E" i: D4 e5 ]1 I/ J( ^
richeditctrl.SetSel(-1, -1);
' P/ |, P8 e3 Q2 \richeditctrl.ReplaceSel( (LPCTSTR)str );
- p6 |9 y4 a8 w; D: |- d
! H0 x. ?- U2 z6 ]d.字数限制' l; R9 V' h% G$ R ^- P- y. u
CRichEditCtrl::LimitText(long nChars)
8 G/ z. i8 }' q3 x5 B0 a0 X8 J5 H0 k, {) {3 x e2 f
e.换行切换1 z7 }( ]0 B0 X" f) q- h2 |& q
CRichEditView的OnInitialUpdate()函数中加入下面两句:
1 ^( @5 m% g; m8 V* D& W) Dm_nWordWrap = WrapNone;
5 N3 m9 q, d# JWrapChanged(); ) l9 f5 H$ ^/ Q* V3 C3 \/ g4 {: w& A6 O4 n
WrapChanged实际上也是调用
- S. ~$ o/ w! R2 s- j. [ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
: w! A, K W l% ~3 Ectrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
7 a3 B" b* m. j7 D还有不常用的 m_nWordWrap == WrapToTargetDevice" K1 {; g9 K3 F5 n* H/ L5 O
ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());+ o0 x( g/ Y6 G
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return0 o+ ~2 g( P/ ~$ d0 q' E
. s" g/ x; z, Z
f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴' P1 e& P( p; s$ x- @
pmyRichEditCtrl->PasteSpecial(CF_TEXT);
! U, w6 p, a" d1 n7 D0 ]# U9 H4 U8 E6 ~7 K
g.随着输入随着自动滚动条滚动到最后一行: S' n6 P6 }. ^/ C( [! M% j) Y
int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
$ c9 q! n0 T1 T, {1 oif (nFirstVisible > 0)
3 i5 q) D3 H+ h! [( v4 ~, h{% n* S" x7 H5 Y# N! u! [
pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);6 W! Q9 s: p* i I6 K2 V
}7 }2 {4 h3 n/ X, @& l
或
' K) [8 X, K( ^6 Hm_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);2 S+ `$ G2 ]5 d8 |* f' p
( u) ~( ?. e- S5 }' j1 X" s" A4 h1 a3 p$ m
h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
# p, J9 i6 `. `7 ]8 a9 JSendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
1 K2 F. V8 j, D" D" \$ P# A1 ]3 _TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数 " ]+ R' R4 N* Z
SendMessage(EM_SETUNDOLIMIT,100,0);
$ K8 X5 B( C5 G1 u n. R. \3 h2 i; O5 G. H* N i
i.响应OnChange
$ F9 F \) F e. ^EM_SETEVENTMASK 设置 ENM_CHANGE K! v) Z0 g- V! ]: L0 A) s1 R
long lMask = GetEventMask();3 V# W& M, P! |* [; ^' Q
lMask |= ENM_CHANGE;
0 [$ D: M- e7 q7 W" s. H( U) u! clMask &= ~ENM_PROTECTED;
3 t& M1 ^; k' Y. P7 o# c% CSetEventMask(lMask);( A6 a/ A4 O: L6 u, Y2 n) |3 v5 _
$ I* y3 G* p* y* k; O+ Cj.设置只读
9 R" D1 a1 y# a! N+ WCRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );- U* U5 B* y" |; V6 z6 t
通过设置PROTECTED实现选中的文本只读,参见
1 ~" t7 a0 M* \ K2 m/ Thttp://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/ T: d9 B q( l( M1 F
; P5 e/ {) ^# v# K, c二.函数应用) l5 l- e# ^$ S: P& G6 l
a.设置字体(主要是通过SetSelectionCharFormat)1 j: q2 d7 w) R( j/ U' m( A) R
CHARFORMAT cf;
3 |. t# y% b, J" [rich.GetSelectionCharFormat(cf);2 c: f1 ]! i2 ?, [% |0 ]/ N
cf.dwMask|=CFM_BOLD;4 H4 p% d& _: G
cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
0 ~) e( u' o& c3 ocf.dwMask|=CFM_ITALIC;
0 Z- E1 p# m' q! |8 Mcf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;' d* j8 N/ E" K ] ]: J
cf.dwMask|=CFM_UNDERLINE;
" |3 o, G- C0 Q8 fcf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;* m" J9 ~& d: _; n/ }. H. e
cf.dwMask|=CFM_COLOR;
) W, `, |/ p, V) _2 w0 t4 _; f2 ncf.crTextColor = RGB(255,0,0);//设置颜色: ^# X8 `. X! \6 X2 {
cf.dwMask|=CFM_SIZE;& c8 n3 E* F8 r7 N
cf.yHeight =200;//设置高度
, Z$ G& }8 ^: n I8 _cf.dwMask|=CFM_FACE;+ Y' S+ v5 P. f) v, P8 B
strcpy(cf.szFaceName ,_T("隶书"));//设置字体2 f7 P3 f9 y9 j8 s- X
rich.SetSelectionCharFormat(cf);
f0 Z; J# K7 p& C* H7 s
! {5 z) T( k$ W" C/ Yb.设置字体的行间距& y2 t: B' E% e+ I& F
要用richedit2.0以上9 D$ I( U9 }# T+ [' b
试试$ U9 D) o* S1 R- Q' H, Z
PARAFORMAT2 pf;5 R& m# B2 d* e2 X, l
pf.cbSize = sizeof(PARAFORMAT2);* H/ |4 K- I% |! R
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;1 |4 B' x+ r! T- \) s
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
$ z/ ]# A( e, s! f8 e7 f, Q5 Ypf.dxOffset = 10;
: v/ G1 o5 v. t, b% l' iVERIFY(SetParaFormat(pf)); 4 w5 A' I3 h% L% t2 n& F6 ^+ Q
常用的dwMask有
/ D" s" J) Q; _( nPFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET: r- U) [# W8 Q% b& L
2 使用阿拉伯数字 (1, 2, 3, ...).
( }& e8 L6 b9 ?) ~3 使用小写字母 (a, b, c, ...). $ J9 e+ f. [1 Z/ Y/ n+ j
4 使用大写字母 (A, B, C, ...).
$ j$ h/ L8 ?3 c& l; h) g" @5 使用小写罗马数字 (i, ii, iii, ...). - [1 Y; w+ T5 w# |) ]3 l* m" p+ O
6 使用大写罗马数字 (I, II, III, ...). 8 {% X3 q+ Q. s7 `+ {5 t# F! t
7 自定义,字符见成员 wNumberingStart. ! I) D: D B# j4 u
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips, t, a/ e, D" t1 f6 x) g+ S4 s
PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进0 Y. ]& o+ _5 ^) g/ }/ l$ x
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
+ E6 H. K2 d4 e' J6 wPFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距5 c$ }* k7 c) x9 m- O9 Q
6 V8 S G- z5 d% N9 N6 \/ Nc.设置CRichEditCtrl(2.0)背景透明 $ G9 P7 w# E% m- M7 K6 B8 ]
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);( f P( A7 v$ r, |; y/ b
style &= WS_EX_TRANSPARENT;
+ ~$ v. M9 W3 @; X& w::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
$ f+ b3 d& \2 L或 CreateEx,然后把WS_EX_TRANSPARENT样式加上( |4 a9 Z- T: s G$ V% O
* X: y+ w- E4 q4 A! f' p
e.得到内容有三种
3 B B" q8 n# K5 c* P6 q1)GetWindowText
8 G$ g8 e5 c j+ I5 m# i1 W7 b; @2)使用EM_GETTEXTEX( D7 ~4 K: O0 L" i: a- I" h+ C
GETTEXTEX gt;
5 n1 B, X& {/ i z( Fgt.cb = 200;+ x, W7 [! ~& _$ E" d$ p" G
gt.flags = GT_DEFAULT;
2 C9 T# {- q6 R! ~- X; Igt.codepage = CP_ACP ;0 t- Y B4 ~$ d/ V
gt.lpDefaultChar = NULL;
! f- L" u$ ^9 J9 b. Rgt.lpUsedDefChar = NULL;6 f7 s0 h" G* E/ Q$ ] Y' N, y, s: N( L6 l
SendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
: l. k, t9 V. Q3 H3 g8 a) B( K3)StreamOut(主要用于RTF等格式输出), ~8 O+ |$ i i" h
static DWORD CALLBACK
2 a, s% R# k* N$ \0 cMyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
6 g" O! L2 ~8 O- T5 o6 _ {8 H{
5 J7 j4 C( R+ J1 F CFile* pFile = (CFile*) dwCookie;
; Z V+ |. X! w# D* y& M/ N. d3 Y$ J. g
pFile->Write(pbBuff, cb); l4 K# f5 [$ u$ Q+ l9 S( K2 R
*pcb = cb;
2 K* _" \. V* u) ]4 W
7 `( G- n5 b: R$ f/ S) P' Q# X return 0;
6 Z3 u$ ]; b" l0 N; y6 w/ d6 Q! }}; B3 [' o& P+ C! {
/ e9 J( n, _# k
4 G p. x- o6 V- | W
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
5 D( C. V8 ?$ R3 }5 W; y EDITSTREAM es;
^1 h+ x# U: x& e8 D: `1 H es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用+ a/ L i4 ]; T( ]- {- C
es.pfnCallback = MyStreamOutCallback; Q5 [* w" N# e5 A5 r) X1 U3 U
pmyRichEditCtrl->StreamOut(SF_RTF, es);& R* S4 Q/ C: g9 a- h+ \
读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
, g l% o; ~0 q8 D1 W/ \* P
- D5 J9 |. U6 K; K3 n+ mf.查找字符串9 h. { e H9 x+ ~' |
FINDTEXTEX ft;0 m9 [/ A. }" S% T7 @
ft.chrg.cpMin = 0;8 s* z( U! q$ q3 e1 j
ft.chrg.cpMax = -1;
1 v k8 j2 ^3 i6 lft.lpstrText = "|";
1 P7 b- r8 n) \1 t- c# o, A6 Blong lPos = FindText(0, &ft);9 G3 `5 D: G6 [7 V' R
7 D1 t+ ^( d: r如果要继续查找,修改cpMin,如/ Q( q( B b6 P* Q4 a6 N; A! `
int nCount = 0;
* o' i y& }( _# ^3 [do9 D" f$ q! v/ d: U, Y3 @
{
1 c0 W2 t) l0 \" h9 y/ K long lPos = GetRichEditCtrl().FindText(0, &ft);/ ^% ~: T, q' S" x* g
if( -1 == lPos) break;2 p8 h/ m3 w% S5 c& P
ft.chrg.cpMin = lPos + strlen(ft.lpstrText);3 G K# W0 M8 I H+ j
++nCount;' _4 h6 T! j: W: J, a# F* W$ T- z% y ]
}while(TRUE);
+ r( [3 t9 g. ~9 ~ q) }
6 R/ T2 M9 a: ^9 I' O2 G, H, @g.以Html格式保存
) Y& i( d; Z. b' r! V9 s目前做法可先转为RTF格式,再通过RTF-to-HTML Converter4 f/ f0 r* r3 u6 G* A
http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/. B, q5 v# n/ z# y; U/ | P
' _) R9 ?# I0 x; v+ w
h.重载OnProtected函数得到对应的消息,如粘贴等+ i t8 w; j* _
void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)8 t6 X" T4 S# s% ]# H L( ~
{. g% N2 I7 T. Z( W4 C+ x# }
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
) A2 h3 e2 Z& p6 ?& `% W. d/ Q. Z0 q0 K6 h
switch (pEP->msg) {
/ x, Z: V* v- P! G+ T+ ^2 s case WM_KEYDOWN://按键,判断pEP->wParam
/ c8 ~+ F/ k" ?8 c case WM_PASTE://粘贴
- W' F. [) O+ D3 X+ f9 m case WM_CUT://剪切
/ X0 p; e! ?* @3 l" q case EM_SETCHARFORMAT:9 T, L. L4 x- G
default:
* D) z2 D: `% X6 [7 s break;
9 [5 g6 r3 C! k };, R/ B @$ S. b4 g/ S
1 f# d6 a V8 ~, y2 K *pResult = FALSE;9 @* H, i. Z) ]6 h, {" w7 m3 J/ t
}, a1 N) R* X& ]* _- [% @
7 U0 y9 F5 V- K三.聊天常用 ) v* s4 \# K, a) ], S5 D
a.LINK 链接功能
& n/ g/ C& Y0 R% q u; t" J1. LoadLibrary(_T("Riched20.dll"));
( _/ t; G- l5 R9 U+ d. ]2. 创建RichEdit2.0控件
! r: M. p0 x9 P) W4 @" ] CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
. J ^3 ]0 X U/ O, B$ ]* k3 R3 ~|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
, a: g4 W5 ]- l3 [' m( ^& E9 u rect.left, rect.top, cx, cy,- ` U; y1 a2 _5 q1 ]# S% S% N
pParentWnd->m_hWnd, (HMENU)nID, NULL);
7 F( w( f* E# B/ _3. 设定选中的文字为链接显示
6 h4 _0 O( A0 ~8 }5 }6 \CHARFORMAT2 cf2;
" c0 x$ u; ~) K9 h2 m' x, l. i! k# TZeroMemory(&cf2, sizeof(CHARFORMAT2));//
- f: g# P1 n& A/ ~cf2.cbSize = sizeof(CHARFORMAT2);" ]0 t5 ~3 T; z0 \/ |6 h
cf2.dwMask = CFM_LINK;( g% A1 A6 a7 A$ n/ f( ]% A
cf2.dwEffects |= CFE_LINK;
4 b) a% s$ W2 Z, Y' k& O7 V# e K3 Tm_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
9 T3 ]; j$ X7 E* _- T: W4.支持链接的点击响应
7 F p1 l- m& S4 [# z- sm_cRichEdit.SetEventMask(ENM_LINK);
3 G, {4 ]1 H( x, A+ l8 ]5 }5.响应链接的点击EN_LINK+ b/ T1 T' O' z
7 v# q5 w2 {& C3 r/ o
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)/ D$ h; d& C; e2 ]8 M
ON_NOTIFY_REFLECT(EN_LINK,OnURL)! F2 d+ P$ |9 ~+ x2 r5 _
END_MESSAGE_MAP()/ T* v" q3 A \$ v. o
...... m, E$ }7 Y$ c
. n% {, B1 b* \+ G, W9 U7 g
void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
* S$ u$ Q% ^7 K& F, A: F* U{
6 @7 v6 L: D g+ f* X/ F. D& ATCHAR LinkChar[512];
/ k2 N- {3 L: m$ yENLINK *pLink = (ENLINK *)pNmhdr;: v8 Q" G! c: L6 v; T1 y
if (pLink->msg == WM_LBUTTONUP)
6 v$ V) B# T! |! R{$ Y# G/ T T+ t: y/ i, L2 j' K
SetSel(penLink->chrg);//这是链接的文字范围
, ]0 R' U9 L9 D+ y- Y! w1 Q7 X" Qlong Res = GetSelText((char *)LinkChar);//这是链接文字
4 l. a' M1 c2 i+ o# V //后面是你的处理过程9 s* S! s& ~& ]0 b+ ]* _! C
......
$ O2 N2 c+ }4 A6 W }
1 ]0 l/ B) N+ y. H' N+ Z) c}* H/ d$ ?& a6 `) S
& S7 Z2 l8 a* c& [
b.插入位图7 J& v- g( {+ [1 T- z/ w
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
- A* e9 H% H2 ~1 a6 p1 p5 K) e+ A) l) _http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
$ N# F; }# S2 e7 h. Q
6 E _( \ y+ v; w自定义在RichEdit中插入对象的图标5 w4 C( m& m h9 ~6 r) }
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html7 X v+ Q, v/ Q- X+ K
方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
7 R; R& g" ?6 O$ U9 L只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片# b4 d9 w- O5 k9 z
! g8 [& p( t0 n" @, u( X2 d+ ~使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
& j; ^5 @+ _- @5 \2 i- Q6 }# h另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
- y6 L7 K) P9 n8 M/ Q6 j' f/ ^8 @: a$ k. d
c.显示GIF动画' K7 n, x$ B0 d
常用的是通过qq的imageole.dll(也有用Gif89.dll的)5 S5 S" P- U" Q, ?
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82 a1 K3 u; E1 E: T; o" d! `: r1 I
http://www.codeproject.com/richedit/AnimatedEmoticon.asp7 Z* g7 [, w6 C- i
* k+ c! M, f' c- Q$ a+ S* L# g2 B
在richedit控件中插入动态GIF (Native C++版)
% u% g" d$ u( ^) }$ O( whttp://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx
9 A, u- d7 f" G4 r
. f6 w7 s" Q) J+ U8 Yd.IRichEditOleCallback的使用; E$ e2 i0 Y& F
http://61.186.252.131/Expert/topic/905/905844.xml?temp=.83790224 |; I) _8 D/ _- e; A
# q5 Y! K7 p) Y9 Y b
类似 MSN 信息发送框的制作(上)
r1 }& u P+ J j! _http://www.vckbase.com/document/viewdoc/?id=1087
$ U( ^ h( x( Q! g8 J- u! G8 P% l ~1 [内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串% i! s1 v% c2 G1 ~0 q# y( o8 @$ _2 [
3 w8 g0 m6 W& ?& v- @; W' d自定义 CRichEditCtrl 控件
9 C$ p. Z" L% y+ N ehttp://www.vckbase.com/document/viewdoc/?id=328
! I/ H1 m. X" m/ n' q内容包含:鼠标右键消息,消息映射,字体变换
! p, L( I# b3 k/ J" R& I( |. M m. V5 W. P
PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
5 N) r' a& O4 \8 ~ k是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778 , r# \) Z& g. t! V
----------------------+ H* h; ^ M8 F% ?
比我想象中还要花时间,所以最后潦草了点,见谅 |
|