在VC中提供了两种很方便的编辑控件(CEdit 和CRichEditCtrl),一般来说这两种控件已经满足了我们大部分的需要,不过只有CEdit控件能响应我们鼠标右键消息,通过右键我们很容易的操作我们的编辑,而在CRichEditCtrl控件中我们不能得到这样的操作,同时CRichEditCtrl是能够包含各种格式的内容,就好像Word一样能够写入各种不同的字体,不过CRichEditCtrl没有给我们提供这样的要求,今天我的目的也就是给他添加这样的扩展操作。
本代码运行效果图
一. 首先我们要从CRichEditCtrl类派生一个我们自己的类CMyRichEdit,我们的操作也是在其中完成的。
二. 然后我们添加鼠标右键消息,在其中添加代码如下:
01.
//设置为焦点
02.
SetFocus();
03.
04.
//创建一个弹出式菜单
05.
CMenu popmenu;
06.
popmenu.CreatePopupMenu();
07.
08.
//添加菜单项目
09.
10.
popmenu.AppendMenu(0, ID_RICH_UNDO,
"&Undo"
);
11.
popmenu.AppendMenu(0, MF_SEPARATOR);
12.
popmenu.AppendMenu(0, ID_RICH_CUT,
"&Cut"
);
13.
popmenu.AppendMenu(0, ID_RICH_COPY,
"C&opy"
);
14.
popmenu.AppendMenu(0, ID_RICH_PASTE,
"&Paste"
);
15.
popmenu.AppendMenu(0, ID_RICH_CLEAR,
"C&lear"
);
16.
popmenu.AppendMenu(0, MF_SEPARATOR);
17.
popmenu.AppendMenu(0, ID_RICH_SELECTALL,
"Select &All"
);
18.
popmenu.AppendMenu(0, MF_SEPARATOR);
19.
popmenu.AppendMenu(0, ID_RICH_SETFONT,
"Select &Font"
);
20.
21.
//初始化菜单项
22.
UINT
nUndo=(CanUndo() ? 0 : MF_GRAYED );
23.
popmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND|nUndo);
24.
UINT
nSel=((GetSelectionType()!=SEL_EMPTY) ? 0 : MF_GRAYED) ;
25.
popmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND|nSel);
26.
popmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND|nSel);
27.
popmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND|nSel);
28.
UINT
nPaste=(CanPaste() ? 0 : MF_GRAYED) ;
29.
popmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND|nPaste);
30.
31.
//显示菜单
32.
CPoint pt;
33.
GetCursorPos(&pt);
34.
popmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y,
this
);
35.
popmenu.DestroyMenu();
三. 然后在.h文件中加入如下的ID定义:
1.
#define ID_RICH_UNDO 101
2.
#define ID_RICH_CUT 102
3.
#define ID_RICH_COPY 103
4.
#define ID_RICH_PASTE 104
5.
#define ID_RICH_CLEAR 105
6.
#define ID_RICH_SELECTALL 106
7.
#define ID_RICH_SETFONT 107
不过这些值还可以通过VC++编译器中的菜单View->Resource Symbols进行添加。 四. 添加消息相应操作,由于这些ID是我们自己定义的,所以我们只能手动添加:
1.在头文件中添加:
1.
afx_msg
void
OnRButtonDown(
UINT
nFlags, CPoint point);
2.
afx_msg
void
OnCopy() { Copy(); }
3.
afx_msg
void
OnCut() { Cut(); }
4.
afx_msg
void
OnPaste() { Paste(); }
5.
afx_msg
void
OnSelectall() { SetSel(0, -1); }
6.
afx_msg
void
OnUndo() { Undo(); }
7.
afx_msg
void
OnClear() { Clear(); }
8.
afx_msg
void
OnSelectfont();
//改变字体
2.在实现文件的消息映射宏中添加如下:
1.
ON_COMMAND(ID_RICH_COPY, OnCopy)
2.
ON_COMMAND(ID_RICH_CUT, OnCut)
3.
ON_COMMAND(ID_RICH_PASTE, OnPaste)
4.
ON_COMMAND(ID_RICH_SELECTALL, OnSelectall)
5.
ON_COMMAND(ID_RICH_UNDO, OnUndo)
6.
ON_COMMAND(ID_RICH_CLEAR, OnClear)
7.
ON_COMMAND(ID_RICH_SETFONT, OnSelectfont)
3.最后添加字体变换函数:
01.
CHARFORMAT cf;
02.
LOGFONT lf;
03.
memset
(&cf, 0,
sizeof
(CHARFORMAT));
04.
memset
(&lf, 0,
sizeof
(LOGFONT));
05.
06.
//判断是否选择了内容
07.
BOOL
bSelect = (GetSelectionType() != SEL_EMPTY) ? TRUE : FALSE;
08.
if
(bSelect)
09.
{
10.
GetSelectionCharFormat(cf);
11.
}
12.
else
13.
{
14.
GetDefaultCharFormat(cf);
15.
}
16.
17.
//得到相关字体属性
18.
BOOL
bIsBold = cf.dwEffects & CFE_BOLD;
19.
BOOL
bIsItalic = cf.dwEffects & CFE_ITALIC;
20.
BOOL
bIsUnderline = cf.dwEffects & CFE_UNDERLINE;
21.
BOOL
bIsStrickout = cf.dwEffects & CFE_STRIKEOUT;
22.
23.
//设置属性
24.
lf.lfCharSet = cf.bCharSet;
25.
lf.lfHeight = cf.yHeight/15;
26.
lf.lfPitchAndFamily = cf.bPitchAndFamily;
27.
lf.lfItalic = bIsItalic;
28.
lf.lfWeight = (bIsBold ? FW_BOLD : FW_NORMAL);
29.
lf.lfUnderline = bIsUnderline;
30.
lf.lfStrikeOut = bIsStrickout;
31.
sprintf
(lf.lfFaceName, cf.szFaceName);
32.
33.
34.
CFontDialog dlg(&lf);
35.
dlg.m_cf.rgbColors = cf.crTextColor;
36.
if
(dlg.DoModal() == IDOK)
37.
{
38.
dlg.GetCharFormat(cf);
//获得所选字体的属性
39.
if
(bSelect)
40.
SetSelectionCharFormat(cf);
//为选定的内容设定所选字体
41.
else
42.
SetWordCharFormat(cf);
//为将要输入的内容设定字体
43.
}
然后在我们需要的地方添加头文件和实现文件,将定义的CRichEditCtrl对象改为用CMyRichEdit来定义,就可以了。
还有提醒的就是不要忘记在InitInstance()中调用AfxInitRichEdit()